[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.33,1.34 obj_date.c,1.14,1.15 obj_delta.c,1.18,1.19 test_both.py,1.20,1.21

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Mon, 02 Dec 2002 13:51:07 -0800


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

Modified Files:
	datetime.c obj_date.c obj_delta.c test_both.py 
Log Message:
Repaired comparison for date objects.  datetime comparison is still broken
in the C implementation.


Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** datetime.c	2 Dec 2002 19:40:41 -0000	1.33
--- datetime.c	2 Dec 2002 21:50:55 -0000	1.34
***************
*** 538,541 ****
--- 538,566 ----
  static PyObject* three_ones = NULL;	/* an argument tuple for __reduce__ */
  
+ /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
+  * The comparisons here all most naturally compute a cmp()-like result.
+  * This little helper turns that into a bool result for rich comparisons.
+  */
+ static PyObject *
+ diff_to_bool(long diff, int op)
+ {
+ 	PyObject *result;
+ 	int istrue;
+ 
+ 	switch (op) {
+ 		case Py_EQ: istrue = diff == 0; break;
+ 		case Py_NE: istrue = diff != 0; break;
+ 		case Py_LE: istrue = diff <= 0; break;
+ 		case Py_GE: istrue = diff >= 0; break;
+ 		case Py_LT: istrue = diff < 0; break;
+ 		case Py_GT: istrue = diff > 0; break;
+ 		default:
+ 			assert(! "op unknown");
+ 	}
+ 	result = istrue ? Py_True : Py_False;
+ 	Py_INCREF(result);
+ 	return result;
+ }
+ 
  #include "obj_delta.c"
  #include "obj_date.c"

Index: obj_date.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_date.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** obj_date.c	2 Dec 2002 19:40:42 -0000	1.14
--- obj_date.c	2 Dec 2002 21:50:57 -0000	1.15
***************
*** 95,108 ****
  }
  
! static int
! date_compare(PyDateTime_Date *self, PyObject *other)
  {
! 	if (!PyType_IsSubtype(other->ob_type, &PyDateTime_DateType)) {
  		PyErr_SetString(PyExc_TypeError,
  				"can't compare date to %s instance");
! 		return -1;
  	}
! 	return memcmp(self->data, ((PyDateTime_Date *)other)->data,
  		      _PyDateTime_DATE_DATA_SIZE);
  }
  
--- 95,115 ----
  }
  
! /* This is more natural as a tp_compare, but doesn't work then:  for whatever
!  * reason, Python's try_3way_compare ignores tp_compare unless
!  * PyInstance_Check returns true, but these aren't old-style classes.
!  */
! static PyObject *
! date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
  {
! 	long diff;
! 
! 	if (! PyType_IsSubtype(other->ob_type, &PyDateTime_DateType)) {
  		PyErr_SetString(PyExc_TypeError,
  				"can't compare date to %s instance");
! 		return NULL;
  	}
! 	diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
  		      _PyDateTime_DATE_DATA_SIZE);
+ 	return diff_to_bool(diff, op);
  }
  
***************
*** 479,483 ****
  	0,						/* tp_getattr */
  	0,						/* tp_setattr */
! 	(cmpfunc)date_compare,				/* tp_compare */
  	(reprfunc)date_repr,				/* tp_repr */
  	&date_as_number,				/* tp_as_number */
--- 486,490 ----
  	0,						/* tp_getattr */
  	0,						/* tp_setattr */
! 	0,						/* tp_compare */
  	(reprfunc)date_repr,				/* tp_repr */
  	&date_as_number,				/* tp_as_number */
***************
*** 495,499 ****
  	0,						/* tp_traverse */
  	0,						/* tp_clear */
! 	0,						/* tp_richcompare */
  	0,						/* tp_weaklistoffset */
  	0,						/* tp_iter */
--- 502,506 ----
  	0,						/* tp_traverse */
  	0,						/* tp_clear */
! 	(richcmpfunc)date_richcompare,			/* tp_richcompare */
  	0,						/* tp_weaklistoffset */
  	0,						/* tp_iter */

Index: obj_delta.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_delta.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** obj_delta.c	2 Dec 2002 21:17:14 -0000	1.18
--- obj_delta.c	2 Dec 2002 21:50:59 -0000	1.19
***************
*** 253,259 ****
  delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
  {
- 	PyObject *result;
  	long diff;
- 	int istrue;
  
  	if (! PyObject_TypeCheck(other, &PyDateTime_DeltaType)) {
--- 253,257 ----
***************
*** 270,286 ****
  			       GET_TD_MICROSECONDS(other);
  	}
! 	switch (op) {
! 		case Py_EQ: istrue = diff == 0; break;
! 		case Py_NE: istrue = diff != 0; break;
! 		case Py_LE: istrue = diff <= 0; break;
! 		case Py_GE: istrue = diff >= 0; break;
! 		case Py_LT: istrue = diff < 0; break;
! 		case Py_GT: istrue = diff > 0; break;
! 		default:
! 			assert(! "op unknown");
! 	}
! 	result = istrue ? Py_True : Py_False;
! 	Py_INCREF(result);
! 	return result;
  }
  
--- 268,272 ----
  			       GET_TD_MICROSECONDS(other);
  	}
! 	return diff_to_bool(diff, op);
  }
  
***************
*** 690,694 ****
  	0,						/* tp_traverse */
  	0,						/* tp_clear */
! 	delta_richcompare,				/* tp_richcompare */
  	0,						/* tp_weaklistoffset */
  	0,						/* tp_iter */
--- 676,680 ----
  	0,						/* tp_traverse */
  	0,						/* tp_clear */
! 	(richcmpfunc)delta_richcompare,			/* tp_richcompare */
  	0,						/* tp_weaklistoffset */
  	0,						/* tp_iter */

Index: test_both.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_both.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** test_both.py	2 Dec 2002 21:37:47 -0000	1.20
--- test_both.py	2 Dec 2002 21:51:00 -0000	1.21
***************
*** 458,463 ****
                  self.assertEqual(orig, derived)
  
!     # XXX This currently fails in the C implementation, due to never raising
!     # XXX TypeError.  Needs to be fixed as timedelta got fixed.
      def test_compare(self):
          t1 = self.theclass(2, 3, 4)
--- 458,464 ----
                  self.assertEqual(orig, derived)
  
!     # XXX This currently fails in the C implementation, for datetime (but not
!     # XXX date) objects, due to never raising TypeError.  Needs to be fixed
!     # XXX as timedelta and date got fixed.
      def test_compare(self):
          t1 = self.theclass(2, 3, 4)