[pypy-commit] pypy default: Improve the test, and fix:
amauryfa
pypy.commits at gmail.com
Fri Jul 1 13:35:51 EDT 2016
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r85498:f616e095f87e
Date: 2016-07-01 19:34 +0200
http://bitbucket.org/pypy/pypy/changeset/f616e095f87e/
Log: Improve the test, and fix: The subclass __init__ and __new__ should
not be called.
Thanks Armin!
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -839,7 +839,7 @@
month = self._month
if day is None:
day = self._day
- return type(self)(year, month, day)
+ return date.__new__(type(self), year, month, day)
# Comparisons of date objects with other.
@@ -1356,7 +1356,8 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- return type(self)(hour, minute, second, microsecond, tzinfo)
+ return time.__new__(type(self),
+ hour, minute, second, microsecond, tzinfo)
def __nonzero__(self):
if self.second or self.microsecond:
@@ -1566,8 +1567,9 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- return type(self)(year, month, day, hour, minute, second, microsecond,
- tzinfo)
+ return datetime.__new__(type(self),
+ year, month, day, hour, minute, second,
+ microsecond, tzinfo)
def astimezone(self, tz):
if not isinstance(tz, tzinfo):
diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -315,13 +315,50 @@
class sub(datetime.timedelta): pass
assert type(+sub()) is datetime.timedelta
- def test_subclass(self):
- class MyDate(datetime.date): pass
- class MyTime(datetime.time): pass
- class MyDateTime(datetime.datetime): pass
- assert type(MyDate.today().replace(day=1)) is MyDate
- assert type(MyTime().replace(hour=1)) is MyTime
- assert type(MyDateTime.now().replace(day=1, hour=1)) is MyDateTime
+ def test_subclass_date(self):
+ # replace() should return a subclass but not call __new__ or __init__.
+ class MyDate(datetime.date):
+ forbidden = False
+ def __new__(cls):
+ if cls.forbidden: FAIL
+ return datetime.date.__new__(cls, 2016, 2, 3)
+ def __init__(self, *args):
+ if self.forbidden: FAIL
+ d = MyDate()
+ d.forbidden = True
+ d2 = d.replace(day=5)
+ assert type(d2) is MyDate
+ assert d2 == datetime.date(2016, 2, 5)
+
+ def test_subclass_time(self):
+ # replace() should return a subclass but not call __new__ or __init__.
+ class MyTime(datetime.time):
+ forbidden = False
+ def __new__(cls):
+ if cls.forbidden: FAIL
+ return datetime.time.__new__(cls, 1, 2, 3)
+ def __init__(self, *args):
+ if self.forbidden: FAIL
+ d = MyTime()
+ d.forbidden = True
+ d2 = d.replace(hour=5)
+ assert type(d2) is MyTime
+ assert d2 == datetime.time(5, 2, 3)
+
+ def test_subclass_datetime(self):
+ # replace() should return a subclass but not call __new__ or __init__.
+ class MyDatetime(datetime.datetime):
+ forbidden = False
+ def __new__(cls):
+ if cls.forbidden: FAIL
+ return datetime.datetime.__new__(cls, 2016, 4, 5, 1, 2, 3)
+ def __init__(self, *args):
+ if self.forbidden: FAIL
+ d = MyDatetime()
+ d.forbidden = True
+ d2 = d.replace(hour=7)
+ assert type(d2) is MyDatetime
+ assert d2 == datetime.datetime(2016, 4, 5, 7, 2, 3)
class TestDatetimeHost(BaseTestDatetime):
More information about the pypy-commit
mailing list