[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.67,1.68 obj_time.c,1.11,1.12 obj_timetz.c,1.21,1.22

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


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

Modified Files:
	datetime.c obj_time.c obj_timetz.c 
Log Message:
Made time_richcompare() smart enough to handle time and timetz objects,
let timetz inherit it, and got rid of timetz_richcompare.  That was an
ugly routine, and I didn't want to propagate the bad design into
datetimetz too.  I like this way much better.


Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -d -r1.67 -r1.68
*** datetime.c	13 Dec 2002 20:40:39 -0000	1.67
--- datetime.c	13 Dec 2002 21:26:55 -0000	1.68
***************
*** 638,641 ****
--- 638,642 ----
   * the "naivety" typedef for details.  If the type is aware, *offset is set
   * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
+  * If the type is offset-naive, *offset is set to 0.
   */
  static naivety
***************
*** 645,648 ****
--- 646,650 ----
  	PyObject *tzinfo;
  
+ 	*offset = 0;
  	if (PyDateTime_CheckExact(op) ||
  	    PyTime_CheckExact(op) ||

Index: obj_time.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_time.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** obj_time.c	13 Dec 2002 19:25:34 -0000	1.11
--- obj_time.c	13 Dec 2002 21:26:55 -0000	1.12
***************
*** 131,134 ****
--- 131,135 ----
   * 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 handle all comparisons for time and timetz.
   */
  static PyObject *
***************
*** 136,149 ****
  {
  	long diff;
  
  	if (! PyTime_Check(other)) {
  		PyErr_Format(PyExc_TypeError,
! 			     "can't compare time to %s instance",
  			     other->ob_type->tp_name);
  		return NULL;
  	}
! 	diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
! 		      _PyDateTime_TIME_DATASIZE);
! 	return diff_to_bool(diff, op);
  }
  
--- 137,195 ----
  {
  	long diff;
+ 	naivety n1, n2;
+ 	long offset1, offset2;
  
  	if (! PyTime_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_Time *)other)->data,
! 			      _PyDateTime_TIME_DATASIZE);
! 		return diff_to_bool(diff, op);
! 	}
! 
! 	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
! 		assert(offset1 != offset2);	/* else last "if" handled it */
! 		/* Convert everything except microseconds to seconds.  These
! 		 * can't overflow (no more than the # of seconds in 2 days).
! 		 */
! 		offset1 = TIME_GET_HOUR(self) * 3600 +
! 			  (TIME_GET_MINUTE(self) - offset1) * 60 +
! 			  TIME_GET_SECOND(self);
! 		offset2 = TIME_GET_HOUR(other) * 3600 +
! 			  (TIME_GET_MINUTE(other) - offset2) * 60 +
! 			  TIME_GET_SECOND(other);
! 		diff = offset1 - offset2;
! 		if (diff == 0)
! 			diff = TIME_GET_MICROSECOND(self) -
! 			       TIME_GET_MICROSECOND(other);
! 		return diff_to_bool(diff, op);
! 	}
! 
! 	assert(n1 != n2);
! 	PyErr_SetString(PyExc_TypeError,
! 			"can't compare offset-naive and "
! 			"offset-aware times");
! 	return NULL;
! 
  }
  

Index: obj_timetz.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_timetz.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** obj_timetz.c	13 Dec 2002 19:25:36 -0000	1.21
--- obj_timetz.c	13 Dec 2002 21:26:56 -0000	1.22
***************
*** 19,23 ****
  };
  
! /* Constructors. */
  
  static PyObject *
--- 19,25 ----
  };
  
! /*
!  * Constructors.
!  */
  
  static PyObject *
***************
*** 47,51 ****
  }
  
! /* Destructor. */
  
  static void
--- 49,55 ----
  }
  
! /*
!  * Destructor.
!  */
  
  static void
***************
*** 56,62 ****
  }
  
! /* Indirect access to tzinfo methods.  One more "convenience function" and
   * it won't be possible to find the useful methods anymore <0.5 wink>.
   */
  static PyObject *
  timetz_convienience(PyDateTime_TimeTZ *self, char *name)
--- 60,68 ----
  }
  
! /*
!  * Indirect access to tzinfo methods.  One more "convenience function" and
   * it won't be possible to find the useful methods anymore <0.5 wink>.
   */
+ 
  static PyObject *
  timetz_convienience(PyDateTime_TimeTZ *self, char *name)
***************
*** 89,93 ****
  }
  
! /* Various ways to turn a timetz into a string. */
  
  static PyObject *
--- 95,101 ----
  }
  
! /*
!  * Various ways to turn a timetz into a string.
!  */
  
  static PyObject *
***************
*** 164,250 ****
  }
  
! /* 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 *
- timetz_richcompare(PyDateTime_TimeTZ *self, PyObject *other, int op)
- {
- 	PyObject *self_tzinfo;
- 	PyObject *other_tzinfo;
- 	long self_offset;
- 	long other_offset;
- 	int self_none;
- 	int other_none;
- 	long diff;
- 
- 	if (! PyTime_Check(other)) {
- 		PyErr_Format(PyExc_TypeError,
- 			     "can't compare 'timetz' to '%s'",
- 			     other->ob_type->tp_name);
- 		return NULL;
- 	}
- 
- 	self_tzinfo = self->tzinfo;
- 	other_tzinfo = PyTimeTZ_Check(other) ?
- 				((PyDateTime_TimeTZ *)other)->tzinfo :
- 				Py_None;
- 
- 	if (self_tzinfo == other_tzinfo)
- 		return time_richcompare((PyDateTime_Time *)self, other, op);
- 
- 	if (self_tzinfo == Py_None) {
- 		self_offset = 0;
- 		self_none = 1;
- 	}
- 	else {
- 		self_offset = call_utcoffset(self_tzinfo,
- 					     (PyObject *)self,
- 					     &self_none);
- 		if (self_offset == -1 && PyErr_Occurred())
- 			return NULL;
- 	}
- 
- 	if (other_tzinfo == Py_None) {
- 		other_offset = 0;
- 		other_none = 1;
- 	}
- 	else {
- 		other_offset = call_utcoffset(other_tzinfo,
- 					      (PyObject *)other,
- 					      &other_none);
- 		if (other_offset == -1 && PyErr_Occurred())
- 			return NULL;
- 	}
  
! 	if (self_none ^ other_none) {
! 		PyErr_SetString(PyExc_TypeError,
! 				"can't compare naive and timezone-aware "
! 				"times");
! 		return NULL;
! 	}
! 
! 	if (self_offset == other_offset)
! 		return time_richcompare((PyDateTime_Time *)self, other, op);
! 
! 	/* Convert everything except microseconds to seconds.  These can't
! 	 * overflow.
! 	 */
! 	self_offset = TIME_GET_HOUR(self) * 3600 +
! 		      (TIME_GET_MINUTE(self) - self_offset) * 60 +
! 		      TIME_GET_SECOND(self);
! 	other_offset = TIME_GET_HOUR(other) * 3600 +
! 		       (TIME_GET_MINUTE(other) - other_offset) * 60 +
! 		       TIME_GET_SECOND(other);
! 	diff = self_offset - other_offset;
! 	if (diff == 0)
! 		diff = TIME_GET_MICROSECOND(self) -
! 		       TIME_GET_MICROSECOND(other);
! 	return diff_to_bool(diff, op);
! }
! 
! static PyObject *timetz_getstate(PyDateTime_TimeTZ *self);
  
  static long
--- 172,180 ----
  }
  
! /*
!  * Miscellaneous methods.
   */
  
! /* Note:  tp_ricomparison is inherited from time. */
  
  static long
***************
*** 470,474 ****
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
! 	(richcmpfunc)timetz_richcompare,	/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	0,					/* tp_iter */
--- 400,404 ----
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
! 	(richcmpfunc)time_richcompare,		/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	0,					/* tp_iter */