[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.81,1.82 doc.txt,1.28,1.29 obj_datetime.c,1.35,1.36 test_both.py,1.53,1.54 test_datetime.py,1.57,1.58

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Sat, 07 Dec 2002 13:06:41 -0800


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

Modified Files:
	datetime.py doc.txt obj_datetime.c test_both.py 
	test_datetime.py 
Log Message:
Implemented the datetime.datetime.combine() constructor.  Added type
checking to the Python implementation of this.  Moved the test case to
test_both.py.  Added error cases to the test.

YUCK:  The METH_CLASS bug makes the combination of a class method with
METH_KEYWORDS excruciating.


Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.81
retrieving revision 1.82
diff -C2 -d -r1.81 -r1.82
*** datetime.py	7 Dec 2002 19:51:18 -0000	1.81
--- datetime.py	7 Dec 2002 21:06:38 -0000	1.82
***************
*** 1133,1136 ****
--- 1133,1141 ----
      def combine(cls, date, time):
          "Construct a datetime from a given date and a given time."
+         import datetime
+         if not isinstance(date, datetime.date):
+             raise TypeError("combine's first argument must be a date")
+         if not isinstance(time, datetime.time):
+             raise TypeError("combine's second argument must be a time")
          return cls(date.year, date.month, date.day,
                     time.hour, time.minute, time.second, time.microsecond)

Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** doc.txt	7 Dec 2002 20:24:46 -0000	1.28
--- doc.txt	7 Dec 2002 21:06:38 -0000	1.29
***************
*** 396,399 ****
--- 396,405 ----
      second and microsecond of the result are all 0.
  
+   - combine(date, time)
+ 
+     Return a new datetime object whose date components are equal to the
+     given date object's, and whose time components are equal to the given
+     time object's.
+ 
  Class attributes:
  

Index: obj_datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetime.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** obj_datetime.c	7 Dec 2002 20:24:46 -0000	1.35
--- obj_datetime.c	7 Dec 2002 21:06:38 -0000	1.36
***************
*** 198,201 ****
--- 198,231 ----
  }
  
+ /* Return new datetime from date and time arguments. */
+ static PyObject *
+ datetime_combine(PyObject *self, PyObject *args, PyObject *kw)
+ {
+ 	/* XXX Ack!  The METH_CLASS bug (see below) makes us pass a
+ 	 * XXX keyword name for the class argument.  Rather than try to
+ 	 * XXX work around it, we pass an "impossible" class name.  This
+ 	 * XXX function will need some reworking when the bug is fixed.
+ 	 */
+ 	static char *keywords[] = {" cls ", "date", "time", NULL};
+ 	PyObject *cls;
+ 	PyObject *date;
+ 	PyObject *time;
+ 	PyObject *result = NULL;
+ 
+ 	if (PyArg_ParseTupleAndKeywords(args, kw, "OO!O!:combine", keywords,
+ 					&cls,
+ 					&PyDateTime_DateType, &date,
+ 					&PyDateTime_TimeType, &time))
+ 		result = PyObject_CallFunction(cls, "iiiiiii",
+ 						GET_YEAR(date),
+ 				    		GET_MONTH(date),
+ 						GET_DAY(date),
+ 				    		TIME_GET_HOUR(time),
+ 				    		TIME_GET_MINUTE(time),
+ 				    		TIME_GET_SECOND(time),
+ 				    		TIME_GET_MICROSECOND(time));
+ 	return result;
+ }
+ 
  static PyObject *
  datetime_utcnow(PyObject *self, PyObject *cls)
***************
*** 294,298 ****
  	               (DATE_GET_MINUTE(left) - DATE_GET_MINUTE(right)) * 60 +
  		       DATE_GET_SECOND(left) - DATE_GET_SECOND(right);
! 	long delta_us = DATE_GET_MICROSECOND(left) - 
  			DATE_GET_MICROSECOND(right);
  
--- 324,328 ----
  	               (DATE_GET_MINUTE(left) - DATE_GET_MINUTE(right)) * 60 +
  		       DATE_GET_SECOND(left) - DATE_GET_SECOND(right);
! 	long delta_us = DATE_GET_MICROSECOND(left) -
  			DATE_GET_MICROSECOND(right);
  
***************
*** 365,369 ****
  			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
  			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
! 			      DATE_GET_SECOND(self), 
  			      DATE_GET_MICROSECOND(self));
  	}
--- 395,399 ----
  			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
  			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
! 			      DATE_GET_SECOND(self),
  			      DATE_GET_MICROSECOND(self));
  	}
***************
*** 461,465 ****
  				     DATE_GET_HOUR(self),
  				     DATE_GET_MINUTE(self),
! 				     DATE_GET_SECOND(self), 
  				     DATE_GET_MICROSECOND(self));
  		if (temp != NULL) {
--- 491,495 ----
  				     DATE_GET_HOUR(self),
  				     DATE_GET_MINUTE(self),
! 				     DATE_GET_SECOND(self),
  				     DATE_GET_MICROSECOND(self));
  		if (temp != NULL) {
***************
*** 599,602 ****
--- 629,636 ----
  	 "timestamp -> UTC datetime from a POSIX timestamp "
  	 "(like time.time())."},
+ 
+ 	{"combine", (PyCFunction)datetime_combine,
+ 	 METH_KEYWORDS | METH_CLASS,
+ 	 "date, time -> datetime with same date and time fields"},
  
  	/* Instance methods: */

Index: test_both.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_both.py,v
retrieving revision 1.53
retrieving revision 1.54
diff -C2 -d -r1.53 -r1.54
*** test_both.py	7 Dec 2002 20:24:46 -0000	1.53
--- test_both.py	7 Dec 2002 21:06:38 -0000	1.54
***************
*** 1131,1134 ****
--- 1131,1150 ----
          self.assertEqual(dt.time(), time(18, 45, 3, 1234))
  
+     def test_combine(self):
+         d = date(2002, 3, 4)
+         t = time(18, 45, 3, 1234)
+         expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
+         combine = self.theclass.combine
+         dt = combine(d, t)
+         self.assertEqual(dt, expected)
+         dt = combine(time=t, date=d)
+         self.assertEqual(dt, expected)
+ 
+         self.assertRaises(TypeError, combine) # need an arg
+         self.assertRaises(TypeError, combine, d) # need two args
+         self.assertRaises(TypeError, combine, t, d) # args reversed
+         self.assertRaises(TypeError, combine, d, t, 1) # too many args
+         self.assertRaises(TypeError, combine, "date", "time") # wrong types
+ 
  class TestTime(unittest.TestCase):
  

Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.57
retrieving revision 1.58
diff -C2 -d -r1.57 -r1.58
*** test_datetime.py	7 Dec 2002 20:24:46 -0000	1.57
--- test_datetime.py	7 Dec 2002 21:06:39 -0000	1.58
***************
*** 74,84 ****
              self.assertEqual(timestamp, tm.time())
  
-     def test_combine(self):
-         d = date(2002, 3, 4)
-         t = time(18, 45, 3, 1234)
-         dt = datetime.combine(d, t)
-         self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234))
- 
- 
  class FixedOffset(object):
      def __init__(self, offset, name):
--- 74,77 ----