[Python-checkins] python/nondist/sandbox/datetime obj_datetime.c,1.49,1.50 obj_datetimetz.c,1.4,1.5

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Fri, 13 Dec 2002 14:19:27 -0800


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

Modified Files:
	obj_datetime.c obj_datetimetz.c 
Log Message:
Made datetime_richcompare smart enough to handle datetime and datetimetz
objects, and arranged for datetimetz to inherit it.  Unfortunately, I see
there are currently no tests of datetimetz comparison.


Index: obj_datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetime.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -C2 -d -r1.49 -r1.50
*** obj_datetime.c	13 Dec 2002 19:16:08 -0000	1.49
--- obj_datetime.c	13 Dec 2002 22:19:25 -0000	1.50
***************
*** 409,412 ****
--- 409,413 ----
   * reason, Python's try_3way_compare ignores tp_compare unless
   * PyInstance_Check returns true, but these aren't old-style classes.
+  * Note that this routine handles all comparisons for datetime and datetimetz.
   */
  static PyObject *
***************
*** 414,427 ****
  {
  	long diff;
  
  	if (! PyDateTime_Check(other)) {
  		PyErr_Format(PyExc_TypeError,
! 			     "can't compare datetime to %s instance",
  			     other->ob_type->tp_name);
  		return NULL;
  	}
! 	diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
! 		      _PyDateTime_DATETIME_DATASIZE);
! 	return diff_to_bool(diff, op);
  }
  
--- 415,478 ----
  {
  	long diff;
+ 	naivety n1, n2;
+ 	long offset1, offset2;
  
  	if (! PyDateTime_Check(other)) {
+ 		/* Stop this from falling back to address comparison. */
  		PyErr_Format(PyExc_TypeError,
! 			     "can't compare '%s' to '%s'",
! 			     self->ob_type->tp_name,
  			     other->ob_type->tp_name);
  		return NULL;
  	}
! 	n1 = classify_object((PyObject *)self, &offset1);
! 	assert(n1 != OFFSET_UNKNOWN);
! 	if (n1 == OFFSET_ERROR)
! 		return NULL;
! 
! 	n2 = classify_object(other, &offset2);
! 	assert(n2 != OFFSET_UNKNOWN);
! 	if (n2 == OFFSET_ERROR)
! 		return NULL;
! 
! 	/* If they're both naive, or both aware and have the same offsets,
! 	 * we get off cheap.  Note that if they're both naive, offset1 ==
! 	 * offset2 == 0 at this point.
! 	 */
! 	if (n1 == n2 && offset1 == offset2) {
! 		diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
! 			      _PyDateTime_DATETIME_DATASIZE);
! 		return diff_to_bool(diff, op);
! 	}
! 
! 	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
! 		/* We want the sign of
! 		 *     (self - offset1 minutes) - (other - offset2 minutes) =
! 		 *     (self - other) + (offset2 - offset1) minutes.
! 		 */
! 		PyDateTime_Delta *delta;
! 		long days, seconds, us;
! 
! 		assert(offset1 != offset2);	/* else last "if" handled it */
! 		delta = (PyDateTime_Delta *)sub_datetime_datetime(self,
! 						(PyDateTime_DateTime *)other);
! 		if (delta == NULL)
! 			return NULL;
! 		days = delta->days;
! 		seconds = delta->seconds + (offset2 - offset1) * 60;
! 		us = delta->microseconds;
! 		Py_DECREF(delta);
! 		normalize_d_s_us(&days, &seconds, &us);
! 		diff = days;
! 		if (diff == 0)
! 			diff = seconds | us;
! 		return diff_to_bool(diff, op);
! 	}
! 
! 	assert(n1 != n2);
! 	PyErr_SetString(PyExc_TypeError,
! 			"can't compare offset-naive and "
! 			"offset-aware datetimes");
! 	return NULL;
  }
  

Index: obj_datetimetz.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetimetz.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** obj_datetimetz.c	13 Dec 2002 19:19:28 -0000	1.4
--- obj_datetimetz.c	13 Dec 2002 22:19:25 -0000	1.5
***************
*** 402,424 ****
  /* Miscellaneous methods. */
  
! /* 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 *
! datetimetz_richcompare(PyDateTime_DateTimeTZ *self, PyObject *other, int op)
! {
! 	long diff;
! 
! 	if (! PyDateTimeTZ_CheckExact(other)) {
! 		PyErr_Format(PyExc_TypeError,
! 			     "can't compare datetime to %s instance",
! 			     other->ob_type->tp_name);
! 		return NULL;
! 	}
! 	diff = memcmp(self->data, ((PyDateTime_DateTimeTZ *)other)->data,
! 		      _PyDateTime_DATETIME_DATASIZE);
! 	return diff_to_bool(diff, op);
! }
  
  static PyObject *datetimetz_getstate(PyDateTime_DateTimeTZ *self);
--- 402,406 ----
  /* Miscellaneous methods. */
  
! /* Note:  tp_richcompare is inherited from datetime. */
  
  static PyObject *datetimetz_getstate(PyDateTime_DateTimeTZ *self);
***************
*** 609,612 ****
--- 591,598 ----
  };
  
+ /* Note:  we don't inherit datetime_richcompare automatically, because we're
+  * overriding datetime's tp_hash.  That's why tp_richcompare is filled in
+  * here explicitly.
+  */
  statichere PyTypeObject PyDateTime_DateTimeTZType = {
  	PyObject_HEAD_INIT(NULL)
***************
*** 636,640 ****
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
! 	(richcmpfunc)datetimetz_richcompare,	/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	0,					/* tp_iter */
--- 622,626 ----
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
! 	(richcmpfunc)datetime_richcompare,	/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	0,					/* tp_iter */