[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.99,1.100 test_both.py,1.71,1.72

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Fri, 13 Dec 2002 14:56:25 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv24033

Modified Files:
	datetime.py test_both.py 
Log Message:
Added some non-trivial datetimetz comparison tests.  Needed to fiddle the
Python implementatino a little to match.


Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.99
retrieving revision 1.100
diff -C2 -d -r1.99 -r1.100
*** datetime.py	12 Dec 2002 23:04:13 -0000	1.99
--- datetime.py	13 Dec 2002 22:56:22 -0000	1.100
***************
*** 1051,1057 ****
          else:
              offset = tz.utcoffset(self)
!             if -1440 < offset < 1440:
                  return offset
!             raise ValueError("utcoffset=%d, must be in -1439..1439" % offset)
  
  
--- 1051,1057 ----
          else:
              offset = tz.utcoffset(self)
!             if offset is None or -1440 < offset < 1440:
                  return offset
!             raise ValueError("utcoffset=%s, must be in -1439..1439" % offset)
  
  
***************
*** 1445,1453 ****
  
      def utcoffset(self):
          tz = self.__tzinfo
          if tz is None:
              return None
          else:
!             return tz.utcoffset(self)
  
      def tzname(self):
--- 1445,1458 ----
  
      def utcoffset(self):
+         """Return the timezone offset in minutes east of UTC (negative west of
+         UTC)."""
          tz = self.__tzinfo
          if tz is None:
              return None
          else:
!             offset = tz.utcoffset(self)
!             if offset is None or -1440 < offset < 1440:
!                 return offset
!             raise ValueError("utcoffset=%s, must be in -1439..1439" % offset)
  
      def tzname(self):
***************
*** 1500,1518 ****
          superself = super(datetimetz, self)
          supercmp = superself.__cmp__
!         mytz = self.__tzinfo
!         ottz = None
          if isinstance(other, datetimetz):
!             ottz = other.__tzinfo
!         if mytz is ottz:
!             return supercmp(other)
!         myoff = otoff = None
!         if mytz is not None:
!             myoff = mytz.utcoffset(self)
!         if ottz is not None:
!             otoff = ottz.utcoffset(other)
          if myoff == otoff:
              return supercmp(other)
          if myoff is None or otoff is None:
!             raise ValueError, "cannot mix naive and timezone-aware time"
          # XXX What follows could be done more efficiently...
          diff = superself.__sub__(other) + timedelta(minutes=otoff-myoff)
--- 1505,1516 ----
          superself = super(datetimetz, self)
          supercmp = superself.__cmp__
!         myoff = self.utcoffset()
!         otoff = None
          if isinstance(other, datetimetz):
!             otoff = other.utcoffset()
          if myoff == otoff:
              return supercmp(other)
          if myoff is None or otoff is None:
!             raise TypeError, "cannot mix naive and timezone-aware time"
          # XXX What follows could be done more efficiently...
          diff = superself.__sub__(other) + timedelta(minutes=otoff-myoff)

Index: test_both.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_both.py,v
retrieving revision 1.71
retrieving revision 1.72
diff -C2 -d -r1.71 -r1.72
*** test_both.py	13 Dec 2002 17:20:29 -0000	1.71
--- test_both.py	13 Dec 2002 22:56:23 -0000	1.72
***************
*** 1680,1683 ****
--- 1680,1831 ----
          self.assertEqual(dt.tzinfo, None)
  
+     # XXX This is a copy of TestDate's routine.  We'll eventually inherit
+     # XXX it.
+     def test_compare(self):
+         t1 = self.theclass(2, 3, 4)
+         t2 = self.theclass(2, 3, 4)
+         self.failUnless(t1 == t2)
+         self.failUnless(t1 <= t2)
+         self.failUnless(t1 >= t2)
+         self.failUnless(not t1 != t2)
+         self.failUnless(not t1 < t2)
+         self.failUnless(not t1 > t2)
+         self.assertEqual(cmp(t1, t2), 0)
+         self.assertEqual(cmp(t2, t1), 0)
+ 
+         for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
+             t2 = self.theclass(*args)   # this is larger than t1
+             self.failUnless(t1 < t2)
+             self.failUnless(t2 > t1)
+             self.failUnless(t1 <= t2)
+             self.failUnless(t2 >= t1)
+             self.failUnless(t1 != t2)
+             self.failUnless(t2 != t1)
+             self.failUnless(not t1 == t2)
+             self.failUnless(not t2 == t1)
+             self.failUnless(not t1 > t2)
+             self.failUnless(not t2 < t1)
+             self.failUnless(not t1 >= t2)
+             self.failUnless(not t2 <= t1)
+             self.assertEqual(cmp(t1, t2), -1)
+             self.assertEqual(cmp(t2, t1), 1)
+ 
+         for badarg in 10, 10L, 34.5, "abc", {}, [], ():
+             self.assertRaises(TypeError, lambda: t1 == badarg)
+             self.assertRaises(TypeError, lambda: t1 != badarg)
+             self.assertRaises(TypeError, lambda: t1 <= badarg)
+             self.assertRaises(TypeError, lambda: t1 < badarg)
+             self.assertRaises(TypeError, lambda: t1 > badarg)
+             self.assertRaises(TypeError, lambda: t1 >= badarg)
+             self.assertRaises(TypeError, lambda: badarg == t1)
+             self.assertRaises(TypeError, lambda: badarg != t1)
+             self.assertRaises(TypeError, lambda: badarg <= t1)
+             self.assertRaises(TypeError, lambda: badarg < t1)
+             self.assertRaises(TypeError, lambda: badarg > t1)
+             self.assertRaises(TypeError, lambda: badarg >= t1)
+ 
+     # XXX This is a copy of TestDateTime's routine.  We'll eventually inherit
+     # XXX it.
+     def test_more_compare(self):
+         # The test_compare() inherited from TestDate covers the error cases.
+         # We just want to test lexicographic ordering on the members datetime
+         # has that date lacks.
+         args = [2000, 11, 29, 20, 58, 16, 999998]
+         t1 = self.theclass(*args)
+         t2 = self.theclass(*args)
+         self.failUnless(t1 == t2)
+         self.failUnless(t1 <= t2)
+         self.failUnless(t1 >= t2)
+         self.failUnless(not t1 != t2)
+         self.failUnless(not t1 < t2)
+         self.failUnless(not t1 > t2)
+         self.assertEqual(cmp(t1, t2), 0)
+         self.assertEqual(cmp(t2, t1), 0)
+ 
+         for i in range(len(args)):
+             newargs = args[:]
+             newargs[i] = args[i] + 1
+             t2 = self.theclass(*newargs)   # this is larger than t1
+             self.failUnless(t1 < t2)
+             self.failUnless(t2 > t1)
+             self.failUnless(t1 <= t2)
+             self.failUnless(t2 >= t1)
+             self.failUnless(t1 != t2)
+             self.failUnless(t2 != t1)
+             self.failUnless(not t1 == t2)
+             self.failUnless(not t2 == t1)
+             self.failUnless(not t1 > t2)
+             self.failUnless(not t2 < t1)
+             self.failUnless(not t1 >= t2)
+             self.failUnless(not t2 <= t1)
+             self.assertEqual(cmp(t1, t2), -1)
+             self.assertEqual(cmp(t2, t1), 1)
+ 
+     def test_even_more_compare(self):
+         # The test_compare() and test_more_compare() inherited from TestDate
+         # and TestDateTime covered non-tzinfo cases.
+ 
+         # Smallest possible after UTC adjustment.
+         t1 = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
+         # Largest possible after UCT adjustment.
+         t2 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
+                            tzinfo=FixedOffset(-1439, ""))
+ 
+         # Make sure those compare correctly, and w/o overflow.
+         self.failUnless(t1 < t2)
+         self.failUnless(t1 != t2)
+         self.failUnless(t2 > t1)
+ 
+         self.failUnless(t1 == t1)
+         self.failUnless(t2 == t2)
+ 
+         # Equal afer adjustment.
+         t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""))
+         t2 = self.theclass(2, 1, 1, 3, 13, tzinfo=FixedOffset(3*60+13+2, ""))
+         self.assertEqual(t1, t2)
+ 
+         # Change t1 not to subtract a minute, and t1 should be larger.
+         t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, ""))
+         self.failUnless(t1 > t2)
+ 
+         # Change t1 to subtract 2 minutes, and t1 should be smaller.
+         t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, ""))
+         self.failUnless(t1 < t2)
+ 
+         # Back to the original t1, but make seconds resolve it.
+         t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
+                            second=1)
+         self.failUnless(t1 > t2)
+ 
+         # Likewise, but make microseconds resolve it.
+         t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
+                            microsecond=1)
+         self.failUnless(t1 > t2)
+ 
+         # Make t2 naive and it should fail.
+         t2 = self.theclass.min
+         self.assertRaises(TypeError, lambda: t1 == t2)
+         self.assertEqual(t2, t2)
+ 
+         # It's also naive if it has tzinfo but tzinfo.utcoffset() is None.
+         class Naive(tzinfo):
+             def utcoffset(self, dt): return None
+         t2 = self.theclass(5, 6, 7, tzinfo=Naive())
+         self.assertRaises(TypeError, lambda: t1 == t2)
+         self.assertEqual(t2, t2)
+ 
+         # OTOH, it's OK to compare two of these mixing the two ways of being
+         # naive.
+         t1 = self.theclass(5, 6, 7)
+         self.assertEqual(t1, t2)
+ 
+         # Try a bogus uctoffset.
+         class Bogus(tzinfo):
+             def utcoffset(self, dt): return 1440 # out of bounds
+         t1 = self.theclass(2, 2, 2, tzinfo=Bogus())
+         t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, ""))
+         self.assertRaises(ValueError, lambda: t1 == t1)
+ 
+ 
  def test_suite():
      allsuites = [unittest.makeSuite(klass, 'test')