[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
2002年12月13日 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')

AltStyle によって変換されたページ (->オリジナル) /