[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.122,1.123 doc.txt,1.69,1.70 test_datetime.py,1.79,1.80

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Mon, 23 Dec 2002 20:35:02 -0800


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

Modified Files:
	datetime.py doc.txt test_datetime.py 
Log Message:
Implemented replace() for datetimetz, time and timetz.  That's it for
this one.


Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.122
retrieving revision 1.123
diff -C2 -d -r1.122 -r1.123
*** datetime.py	23 Dec 2002 23:49:51 -0000	1.122
--- datetime.py	24 Dec 2002 04:35:00 -0000	1.123
***************
*** 258,263 ****
  def _check_date_fields(year, month, day):
      if not MINYEAR <= year <= MAXYEAR:
!         raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR),
!                          year)
      if not 1 <= month <= 12:
          raise ValueError('month must be in 1..12', month)
--- 258,262 ----
  def _check_date_fields(year, month, day):
      if not MINYEAR <= year <= MAXYEAR:
!         raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
      if not 1 <= month <= 12:
          raise ValueError('month must be in 1..12', month)
***************
*** 276,279 ****
--- 275,282 ----
          raise ValueError('microsecond must be in 0..999999', microsecond)
  
+ def _check_tzinfo_arg(tz):
+     if tz is not None and not isinstance(tz, tzinfo):
+         raise TypeError("tzinfo argument must be None or of a tzinfo subclass")
+ 
  # This is a start at a struct tm workalike.  Goals:
  #
***************
*** 939,942 ****
--- 942,958 ----
          return _wrap_strftime(self, fmt, timetuple)
  
+     def replace(self, hour=None, minute=None, second=None, microsecond=None):
+         """Return a new time with new values for the specified fields."""
+         if hour is None:
+             hour = self.hour
+         if minute is None:
+             minute = self.minute
+         if second is None:
+             second = self.second
+         if microsecond is None:
+             microsecond = self.microsecond
+         _check_time_fields(hour, minute, second, microsecond)
+         return time(hour, minute, second, microsecond)
+ 
      def __nonzero__(self):
          return (self.__hour != 0 or
***************
*** 1025,1032 ****
          tzinfo (default to None)
          """
!         import datetime
!         if tzinfo is not None and not isinstance(tzinfo, datetime.tzinfo):
!             raise TypeError("tzinfo argument must be None or of a tzinfo "
!                             "subclass")
          super(timetz, self).__init__(hour, minute, second, microsecond)
          self.__tzinfo = tzinfo
--- 1041,1045 ----
          tzinfo (default to None)
          """
!         _check_tzinfo_arg(tzinfo)
          super(timetz, self).__init__(hour, minute, second, microsecond)
          self.__tzinfo = tzinfo
***************
*** 1153,1156 ****
--- 1166,1186 ----
          return offset
  
+     def replace(self, hour=None, minute=None, second=None, microsecond=None,
+                 tzinfo=True):
+         """Return a new timetz with new values for the specified fields."""
+         if hour is None:
+             hour = self.hour
+         if minute is None:
+             minute = self.minute
+         if second is None:
+             second = self.second
+         if microsecond is None:
+             microsecond = self.microsecond
+         if tzinfo is True:
+             tzinfo = self.tzinfo
+         _check_time_fields(hour, minute, second, microsecond)
+         _check_tzinfo_arg(tzinfo)
+         return timetz(hour, minute, second, microsecond, tzinfo)
+ 
      # Return an integer (or None) instead of a timedelta (or None).
      def _dst(self):
***************
*** 1466,1473 ****
      def __init__(self, year, month, day, hour=0, minute=0, second=0,
                   microsecond=0, tzinfo=None):
!         import datetime
!         if tzinfo is not None and not isinstance(tzinfo, datetime.tzinfo):
!             raise TypeError("tzinfo argument must be None or of a tzinfo "
!                             "subclass")
          super(datetimetz, self).__init__(year, month, day,
                                           hour, minute, second, microsecond)
--- 1496,1500 ----
      def __init__(self, year, month, day, hour=0, minute=0, second=0,
                   microsecond=0, tzinfo=None):
!         _check_tzinfo_arg(tzinfo)
          super(datetimetz, self).__init__(year, month, day,
                                           hour, minute, second, microsecond)
***************
*** 1525,1528 ****
--- 1552,1580 ----
          return timetz(self.hour, self.minute, self.second, self.microsecond,
                        self.__tzinfo)
+ 
+     def replace(self, year=None, month=None, day=None, hour=None,
+                 minute=None, second=None, microsecond=None, tzinfo=True):
+         """Return a new datetimetz with new values for the specified fields."""
+         if year is None:
+             year = self.year
+         if month is None:
+             month = self.month
+         if day is None:
+             day = self.day
+         if hour is None:
+             hour = self.hour
+         if minute is None:
+             minute = self.minute
+         if second is None:
+             second = self.second
+         if microsecond is None:
+             microsecond = self.microsecond
+         if tzinfo is True:
+             tzinfo = self.tzinfo
+         _check_date_fields(year, month, day)
+         _check_time_fields(hour, minute, second, microsecond)
+         _check_tzinfo_arg(tzinfo)
+         return datetimetz(year, month, day, hour, minute, second,
+                           microsecond, tzinfo)
  
      def isoformat(self, sep='T'):

Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.69
retrieving revision 1.70
diff -C2 -d -r1.69 -r1.70
*** doc.txt	23 Dec 2002 23:49:52 -0000	1.69
--- doc.txt	24 Dec 2002 04:35:00 -0000	1.70
***************
*** 733,736 ****
--- 733,740 ----
  Instance methods:
  
+   - replace(hour=None, minute=None, second=None, microsecond=None)
+     Return a time with the same fields as self, except for those
+     members given in the argument list.
+ 
    - isoformat()
      Return a string representing the time in ISO 8601 format,
***************
*** 958,961 ****
--- 962,972 ----
      converted to a timedelta object.
  
+   - replace(hour=None, minute=None, second=None, microsecond=None,
+             tzinfo=True)
+     Return a timetz with the same fields as self, except for those
+     members given in the argument list.  Note that the tzinfo argument
+     defaults to True instead of to None.  This is so you can specify
+     tzinfo=None to remove a timetz's tzinfo member.
+ 
  
  class datetimetz
***************
*** 1105,1108 ****
--- 1116,1126 ----
      If self.tzinfo is None, returns None, else self.tzinfo.dst(self),
      converted to a timedelta object.
+ 
+   - replace(year=None, month=None, day=None, hour=None, minute=None,
+             second=None, microsecond=None, tzinfo=True)
+     Return a datet with the same fields as self, except for those
+     members given in the argument list.  Note that the tzinfo argument
+     defaults to True instead of to None.  This is so you can specify
+     tzinfo=None to remove a datetimetz's tzinfo member.
  
    - timetuple()

Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.79
retrieving revision 1.80
diff -C2 -d -r1.79 -r1.80
*** test_datetime.py	23 Dec 2002 23:49:52 -0000	1.79
--- test_datetime.py	24 Dec 2002 04:35:00 -0000	1.80
***************
*** 1303,1307 ****
  
          # Out of bounds.
!         base = date(2000, 2, 29)
          self.assertRaises(ValueError, base.replace, year=2001)
  
--- 1303,1307 ----
  
          # Out of bounds.
!         base = cls(2000, 2, 29)
          self.assertRaises(ValueError, base.replace, year=2001)
  
***************
*** 1525,1528 ****
--- 1525,1553 ----
          self.failUnless(not cls())
  
+     def test_replace(self):
+         cls = self.theclass
+         args = [1, 2, 3, 4]
+         base = cls(*args)
+         self.assertEqual(base, base.replace())
+ 
+         i = 0
+         for name, newval in (("hour", 5),
+                              ("minute", 6),
+                              ("second", 7),
+                              ("microsecond", 8)):
+             newargs = args[:]
+             newargs[i] = newval
+             expected = cls(*newargs)
+             got = base.replace(**{name: newval})
+             self.assertEqual(expected, got)
+             i += 1
+ 
+         # Out of bounds.
+         base = cls(1)
+         self.assertRaises(ValueError, base.replace, hour=24)
+         self.assertRaises(ValueError, base.replace, minute=-1)
+         self.assertRaises(ValueError, base.replace, second=100)
+         self.assertRaises(ValueError, base.replace, microsecond=1000000)
+ 
  # A mixin for classes with a tzinfo= argument.  Subclasses must define
  # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
***************
*** 1796,1799 ****
--- 1821,1863 ----
          self.assertRaises(ValueError, lambda: bool(t))
  
+     def test_replace(self):
+         cls = self.theclass
+         z100 = FixedOffset(100, "+100")
+         zm200 = FixedOffset(timedelta(minutes=-200), "-200")
+         args = [1, 2, 3, 4, z100]
+         base = cls(*args)
+         self.assertEqual(base, base.replace())
+ 
+         i = 0
+         for name, newval in (("hour", 5),
+                              ("minute", 6),
+                              ("second", 7),
+                              ("microsecond", 8),
+                              ("tzinfo", zm200)):
+             newargs = args[:]
+             newargs[i] = newval
+             expected = cls(*newargs)
+             got = base.replace(**{name: newval})
+             self.assertEqual(expected, got)
+             i += 1
+ 
+         # Ensure we can get rid of a tzinfo.
+         self.assertEqual(base.tzname(), "+100")
+         base2 = base.replace(tzinfo=None)
+         self.failUnless(base2.tzinfo is None)
+         self.failUnless(base2.tzname() is None)
+ 
+         # Ensure we can add one.
+         base3 = base2.replace(tzinfo=z100)
+         self.assertEqual(base, base3)
+         self.failUnless(base.tzinfo is base3.tzinfo)
+ 
+         # Out of bounds.
+         base = cls(1)
+         self.assertRaises(ValueError, base.replace, hour=24)
+         self.assertRaises(ValueError, base.replace, minute=-1)
+         self.assertRaises(ValueError, base.replace, second=100)
+         self.assertRaises(ValueError, base.replace, microsecond=1000000)
+ 
  class TestDateTimeTZ(TestDateTime, TZInfoBase):
      theclass = datetimetz
***************
*** 2218,2221 ****
--- 2282,2323 ----
                  self.assertEqual(str(d), datestr + ' ' + tailstr)
  
+     def test_replace(self):
+         cls = self.theclass
+         z100 = FixedOffset(100, "+100")
+         zm200 = FixedOffset(timedelta(minutes=-200), "-200")
+         args = [1, 2, 3, 4, 5, 6, 7, z100]
+         base = cls(*args)
+         self.assertEqual(base, base.replace())
+ 
+         i = 0
+         for name, newval in (("year", 2),
+                              ("month", 3),
+                              ("day", 4),
+                              ("hour", 5),
+                              ("minute", 6),
+                              ("second", 7),
+                              ("microsecond", 8),
+                              ("tzinfo", zm200)):
+             newargs = args[:]
+             newargs[i] = newval
+             expected = cls(*newargs)
+             got = base.replace(**{name: newval})
+             self.assertEqual(expected, got)
+             i += 1
+ 
+         # Ensure we can get rid of a tzinfo.
+         self.assertEqual(base.tzname(), "+100")
+         base2 = base.replace(tzinfo=None)
+         self.failUnless(base2.tzinfo is None)
+         self.failUnless(base2.tzname() is None)
+ 
+         # Ensure we can add one.
+         base3 = base2.replace(tzinfo=z100)
+         self.assertEqual(base, base3)
+         self.failUnless(base.tzinfo is base3.tzinfo)
+ 
+         # Out of bounds.
+         base = cls(2000, 2, 29)
+         self.assertRaises(ValueError, base.replace, year=2001)
  
  def test_suite():