[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.102,1.103 obj_datetime.c,1.52,1.53 test_both.py,1.75,1.76
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Fri, 13 Dec 2002 17:33:59 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv2815
Modified Files:
datetime.py obj_datetime.c test_both.py
Log Message:
Repaired Python datetimetz.__hash__ overflow cases; implemented
C datetimetz.__hash__.
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.102
retrieving revision 1.103
diff -C2 -d -r1.102 -r1.103
*** datetime.py 14 Dec 2002 00:35:04 -0000 1.102
--- datetime.py 14 Dec 2002 01:33:57 -0000 1.103
***************
*** 1527,1536 ****
def __hash__(self):
tzoff = self.utcoffset()
! if not tzoff: # zero or None!
return super(datetimetz, self).__hash__()
! # XXX The rest is broken: can cause OverflowError on the low and
! # XXX high ends.
! t = self - timedelta(minutes=tzoff)
! return super(datetimetz, t).__hash__()
def __getstate__(self):
--- 1527,1535 ----
def __hash__(self):
tzoff = self.utcoffset()
! if tzoff is None:
return super(datetimetz, self).__hash__()
! days = _ymd2ord(self.year, self.month, self.day)
! seconds = self.hour * 3600 + (self.minute - tzoff) * 60 + self.second
! return hash(timedelta(days, seconds, self.microsecond))
def __getstate__(self):
Index: obj_datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetime.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** obj_datetime.c 14 Dec 2002 01:14:32 -0000 1.52
--- obj_datetime.c 14 Dec 2002 01:33:57 -0000 1.53
***************
*** 498,502 ****
}
else {
! long minutes;
assert(n == OFFSET_AWARE);
--- 498,504 ----
}
else {
! long days;
! long seconds;
! PyDateTime_Delta *delta;
assert(n == OFFSET_AWARE);
***************
*** 512,525 ****
* with hour=6 and offset=0.
*/
! /* XXX This code makes no sense -- repair it. */
! minutes = TIME_GET_HOUR(self) * 60L +
! TIME_GET_MINUTE(self) - offset;
! /* The multipliers below are arbitrary. */
! self->hashcode = minutes * 3601L +
! TIME_GET_SECOND(self) * 61L +
! TIME_GET_MICROSECOND(self);
! if (self->hashcode == -1)
! self->hashcode = -2;
!
}
}
--- 514,531 ----
* with hour=6 and offset=0.
*/
! days = ymd_to_ord(GET_YEAR(self),
! GET_MONTH(self),
! GET_DAY(self));
! seconds = DATE_GET_HOUR(self) * 3600L +
! (DATE_GET_MINUTE(self) - offset) * 60L +
! DATE_GET_SECOND(self);
! delta = (PyDateTime_Delta *)new_delta(days,
! seconds,
! DATE_GET_MICROSECOND(self),
! 1);
! if (delta == NULL)
! return -1;
! self->hashcode = delta_hash(delta);
! Py_DECREF(delta);
}
}
Index: test_both.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_both.py,v
retrieving revision 1.75
retrieving revision 1.76
diff -C2 -d -r1.75 -r1.76
*** test_both.py 14 Dec 2002 00:49:39 -0000 1.75
--- test_both.py 14 Dec 2002 01:33:57 -0000 1.76
***************
*** 1882,1885 ****
--- 1882,1896 ----
self.assertEqual(derived.tzname(), 'cookie')
+ def test_extreme_hashes(self):
+ # If an attempt is made to hash these via subtracting the offset
+ # then hashing a datetime object, OverflowError results. The
+ # Python implementation used to blow up here.
+ t = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
+ hash(t)
+ t = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
+ tzinfo=FixedOffset(-1439, ""))
+ hash(t)
+
+
def test_suite():
allsuites = [unittest.makeSuite(klass, 'test')