[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 */