Commit a11d8c03 authored by Alexander Belopolsky's avatar Alexander Belopolsky

Issue #9000: datetime.timezone objects now have eval-friendly repr.

parent 44afa5e6
...@@ -153,6 +153,15 @@ class TestTimeZone(unittest.TestCase): ...@@ -153,6 +153,15 @@ class TestTimeZone(unittest.TestCase):
timezone.min, timezone.max]: timezone.min, timezone.max]:
self.assertEqual(str(tz), tz.tzname(None)) self.assertEqual(str(tz), tz.tzname(None))
def test_repr(self):
import datetime
for tz in [self.ACDT, self.EST, timezone.utc,
timezone.min, timezone.max]:
# test round-trip
tzrep = repr(tz)
self.assertEqual(tz, eval(tzrep))
def test_class_members(self): def test_class_members(self):
limit = timedelta(hours=23, minutes=59) limit = timedelta(hours=23, minutes=59)
self.assertEqual(timezone.utc.utcoffset(None), ZERO) self.assertEqual(timezone.utc.utcoffset(None), ZERO)
......
...@@ -1394,6 +1394,8 @@ Library ...@@ -1394,6 +1394,8 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #9000: datetime.timezone objects now have eval-friendly repr.
- In the math module, correctly lookup __trunc__, __ceil__, and __floor__ as - In the math module, correctly lookup __trunc__, __ceil__, and __floor__ as
special methods. special methods.
......
...@@ -780,6 +780,8 @@ typedef struct ...@@ -780,6 +780,8 @@ typedef struct
PyObject *name; PyObject *name;
} PyDateTime_TimeZone; } PyDateTime_TimeZone;
PyObject *PyDateTime_TimeZone_UTC;
/* Create new timezone instance checking offset range. This /* Create new timezone instance checking offset range. This
function does not check the name argument. Caller must assure function does not check the name argument. Caller must assure
that offset is a timedelta instance and name is either NULL that offset is a timedelta instance and name is either NULL
...@@ -3379,6 +3381,24 @@ _timezone_check_argument(PyObject *dt, const char *meth) ...@@ -3379,6 +3381,24 @@ _timezone_check_argument(PyObject *dt, const char *meth)
return -1; return -1;
} }
static PyObject *
timezone_repr(PyDateTime_TimeZone *self)
{
/* Note that although timezone is not subclassable, it is convenient
to use Py_TYPE(self)->tp_name here. */
const char *type_name = Py_TYPE(self)->tp_name;
if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
return PyUnicode_FromFormat("%s.utc", type_name);
if (self->name == NULL)
return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
self->name);
}
static PyObject * static PyObject *
timezone_str(PyDateTime_TimeZone *self) timezone_str(PyDateTime_TimeZone *self)
{ {
...@@ -3505,7 +3525,7 @@ static PyTypeObject PyDateTime_TimeZoneType = { ...@@ -3505,7 +3525,7 @@ static PyTypeObject PyDateTime_TimeZoneType = {
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_reserved */ 0, /* tp_reserved */
0, /* tp_repr */ (reprfunc)timezone_repr, /* tp_repr */
0, /* tp_as_number */ 0, /* tp_as_number */
0, /* tp_as_sequence */ 0, /* tp_as_sequence */
0, /* tp_as_mapping */ 0, /* tp_as_mapping */
...@@ -5260,7 +5280,7 @@ PyInit_datetime(void) ...@@ -5260,7 +5280,7 @@ PyInit_datetime(void)
Py_DECREF(delta); Py_DECREF(delta);
if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
return NULL; return NULL;
Py_DECREF(x); PyDateTime_TimeZone_UTC = x;
delta = new_delta(-1, 60, 0, 1); /* -23:59 */ delta = new_delta(-1, 60, 0, 1); /* -23:59 */
if (delta == NULL) if (delta == NULL)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment