[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
2002年12月13日 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 */

AltStyle によって変換されたページ (->オリジナル) /