diff options
author | Eric Smith <eric@trueblade.com> | 2007-09-11 18:06:02 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2007-09-11 18:06:02 (GMT) |
commit | 1ba3114fdb5adb5e6852c85e1d3caccba3395471 (patch) | |
tree | 0341bc0a923b50960ecf14302132eea3b30142a7 | |
parent | 54d6874e48cc9aa57c141b59868f6a99a87dd1b6 (diff) | |
download | cpython-1ba3114fdb5adb5e6852c85e1d3caccba3395471.zip cpython-1ba3114fdb5adb5e6852c85e1d3caccba3395471.tar.gz cpython-1ba3114fdb5adb5e6852c85e1d3caccba3395471.tar.bz2 |
Added __format__ method to datetime.datetime, datetime.date, and datetime.time.
If format_spec is empty, __format__ calls str(self), else it calls
self.strftime(format_spec).
-rw-r--r-- | Lib/test/test_datetime.py | 78 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 36 |
2 files changed, 114 insertions, 0 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index dce9fc3..b1a1b38 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -849,6 +849,32 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): # A naive object replaces %z and %Z w/ empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + def test_format(self): + dt = self.theclass(2007, 9, 10) + self.assertEqual(format(dt, ''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10) + self.assertEqual(format(a, ''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10) + self.assertEqual(format(b, ''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(format(dt, fmt), dt.strftime(fmt)) + self.assertEqual(format(a, fmt), dt.strftime(fmt)) + self.assertEqual(format(b, fmt), 'B') + def test_resolution_info(self): self.assert_(isinstance(self.theclass.min, self.theclass)) self.assert_(isinstance(self.theclass.max, self.theclass)) @@ -1150,6 +1176,34 @@ class TestDateTime(TestDate): # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 00:00:00") + def test_format(self): + dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(format(dt, ''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(format(a, ''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(format(b, ''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(format(dt, fmt), dt.strftime(fmt)) + self.assertEqual(format(a, fmt), dt.strftime(fmt)) + self.assertEqual(format(b, fmt), 'B') + + + def test_more_ctime(self): # Test fields that TestDate doesn't touch. import time @@ -1781,6 +1835,30 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase): # A naive object replaces %z and %Z with empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + def test_format(self): + t = self.theclass(1, 2, 3, 4) + self.assertEqual(format(t, ''), str(t)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(1, 2, 3, 4) + self.assertEqual(format(a, ''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(1, 2, 3, 4) + self.assertEqual(format(b, ''), str(t)) + + for fmt in ['%H %M %S', + ]: + self.assertEqual(format(t, fmt), t.strftime(fmt)) + self.assertEqual(format(a, fmt), t.strftime(fmt)) + self.assertEqual(format(b, fmt), 'B') + def test_str(self): self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004") self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000") diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 14990a3..b48385f 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -2440,6 +2440,21 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) return result; } +static PyObject * +date_format(PyDateTime_Date *self, PyObject *args) +{ + PyObject *format; + + if (!PyArg_ParseTuple(args, "U:__format__", &format)) + return NULL; + + /* if the format is zero length, return str(self) */ + if (PyUnicode_GetSize(format) == 0) + return PyObject_Unicode((PyObject *)self); + + return PyObject_CallMethod((PyObject *)self, "strftime", "O", format); +} + /* ISO methods. */ static PyObject * @@ -2610,6 +2625,9 @@ static PyMethodDef date_methods[] = { {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, + {"__format__", (PyCFunction)date_format, METH_VARARGS, + PyDoc_STR("Formats self with strftime.")}, + {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS, PyDoc_STR("Return time tuple, compatible with time.localtime().")}, @@ -3198,6 +3216,21 @@ time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw) return result; } +static PyObject * +time_format(PyDateTime_Time *self, PyObject *args) +{ + PyObject *format; + + if (!PyArg_ParseTuple(args, "U:__format__", &format)) + return NULL; + + /* if the format is zero length, return str(self) */ + if (PyUnicode_GetSize(format) == 0) + return PyObject_Unicode((PyObject *)self); + + return PyObject_CallMethod((PyObject *)self, "strftime", "O", format); +} + /* * Miscellaneous methods. */ @@ -3385,6 +3418,9 @@ static PyMethodDef time_methods[] = { {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, + {"__format__", (PyCFunction)time_format, METH_VARARGS, + PyDoc_STR("Formats self with strftime.")}, + {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS, PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, |