[Python-checkins] python/nondist/sandbox/datetime obj_timetz.c,NONE,1.1 datetime.c,1.52,1.53 datetime.h,1.12,1.13
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Mon, 09 Dec 2002 18:04:29 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv5008
Modified Files:
datetime.c datetime.h
Added Files:
obj_timetz.c
Log Message:
Added wholly non-functional code for the timetz -- this is just a copy,
paste, and mindless edit of the time code.
--- NEW FILE: obj_timetz.c ---
/*
* PyDateTime_TimeTZ implementation.
*/
/* Accessor properties. */
static PyObject *
timetz_hour(PyDateTime_TimeTZ *self, void *unused)
{
return PyInt_FromLong(TIME_GET_HOUR(self));
}
static PyObject *
timetz_minute(PyDateTime_TimeTZ *self, void *unused)
{
return PyInt_FromLong(TIME_GET_MINUTE(self));
}
static PyObject *
timetz_second(PyDateTime_TimeTZ *self, void *unused)
{
return PyInt_FromLong(TIME_GET_SECOND(self));
}
static PyObject *
timetz_microsecond(PyDateTime_TimeTZ *self, void *unused)
{
return PyInt_FromLong(TIME_GET_MICROSECOND(self));
}
static PyGetSetDef timetz_getset[] = {
{"hour", (getter)timetz_hour},
{"minute", (getter)timetz_minute},
{"second", (getter)timetz_second},
{"microsecond", (getter)timetz_microsecond},
{NULL}
};
/* Constructors. */
static PyObject *
timetz_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
PyObject *self = NULL;
long hour = 0;
long minute = 0;
long second = 0;
long usecond = 0;
static char *keywords[] = {
"hour", "minute", "second", "microsecond", NULL
};
if (PyArg_ParseTupleAndKeywords(args, kw, "|llll", keywords,
&hour, &minute, &second, &usecond)) {
if (hour < 0 || hour > 23) {
PyErr_SetString(PyExc_ValueError,
"hour must be in 0..23");
return NULL;
}
if (minute < 0 || minute > 59) {
PyErr_SetString(PyExc_ValueError,
"minute must be in 0..59");
return NULL;
}
if (second < 0 || second > 59) {
PyErr_SetString(PyExc_ValueError,
"second must be in 0..59");
return NULL;
}
if (usecond < 0 || usecond > 999999) {
PyErr_SetString(PyExc_ValueError,
"microsecond must be in 0..999999");
return NULL;
}
self = new_time(hour, minute, second, usecond);
}
return self;
}
/* Various ways to turn a time into a string. */
static PyObject *
timetz_repr(PyDateTime_TimeTZ *self)
{
char buffer[100];
char *typename = self->ob_type->tp_name;
int h = TIME_GET_HOUR(self);
int m = TIME_GET_MINUTE(self);
int s = TIME_GET_SECOND(self);
int us = TIME_GET_MICROSECOND(self);
if (us)
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d, %d)", typename, h, m, s, us);
else if (s)
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d)", typename, h, m, s);
else
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d)", typename, h, m);
return PyString_FromString(buffer);
}
static PyObject *
timetz_str(PyDateTime_TimeTZ *self)
{
return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
}
static PyObject *
timetz_isoformat(PyDateTime_TimeTZ *self)
{
char buffer[100];
/* Reuse the time format code from the datetime type. */
PyDateTime_DateTime datetime;
PyDateTime_DateTime *pdatetime = &datetime;
/* Copy over just the time bytes. */
memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
self->data,
_PyDateTime_TIME_DATASIZE);
isoformat_time(pdatetime, buffer, sizeof(buffer));
return PyString_FromString(buffer);
}
static PyObject *
timetz_strftime(PyDateTime_TimeTZ *self, PyObject *format)
{
PyObject *result;
PyObject *tuple = Py_BuildValue("iiiiiiiii",
0, 0, 0, /* year, month, day */
TIME_GET_HOUR(self),
TIME_GET_MINUTE(self),
TIME_GET_SECOND(self),
0, 0, -1); /* weekday, daynum, dst */
if (tuple == NULL)
return NULL;
assert(PyTuple_Size(tuple) == 9);
result = format_strftime(format, tuple);
Py_DECREF(tuple);
return result;
}
/* 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)
{
long diff;
if (!PyType_IsSubtype(other->ob_type, &PyDateTime_TimeType)) {
PyErr_Format(PyExc_TypeError,
"can't compare time to %s instance",
other->ob_type->tp_name);
return NULL;
}
diff = memcmp(self->data, ((PyDateTime_TimeTZ *)other)->data,
_PyDateTime_TIME_DATASIZE);
return diff_to_bool(diff, op);
}
static PyObject *timetz_getstate(PyDateTime_TimeTZ *self);
static long
timetz_hash(PyDateTime_TimeTZ *self)
{
if (self->hashcode == -1) {
PyObject *temp = timetz_getstate(self);
if (temp != NULL) {
self->hashcode = PyObject_Hash(temp);
Py_DECREF(temp);
}
}
return self->hashcode;
}
static int
timetz_nonzero(PyDateTime_TimeTZ *self)
{
return TIME_GET_HOUR(self) ||
TIME_GET_MINUTE(self) ||
TIME_GET_SECOND(self) ||
TIME_GET_MICROSECOND(self);
}
/* Pickle support. Quite a maze! */
static PyObject *
timetz_getstate(PyDateTime_TimeTZ *self)
{
return PyString_FromStringAndSize(self->data,
_PyDateTime_TIME_DATASIZE);
}
static PyObject *
timetz_setstate(PyDateTime_TimeTZ *self, PyObject *state)
{
const int len = PyString_Size(state);
unsigned char *pdata = (unsigned char*)PyString_AsString(state);
if (! PyString_Check(state) ||
len != _PyDateTime_TIME_DATASIZE) {
PyErr_SetString(PyExc_TypeError,
"bad argument to time.__setstate__");
return NULL;
}
memcpy(self->data, pdata, _PyDateTime_TIME_DATASIZE);
self->hashcode = -1;
Py_INCREF(Py_None);
return Py_None;
}
/* XXX This seems a ridiculously inefficient way to pickle a short string. */
static PyObject *
timetz_pickler(PyObject *module, PyDateTime_TimeTZ *time)
{
PyObject *state;
PyObject *result = NULL;
if (time->ob_type != &PyDateTime_TimeTZType) {
PyErr_Format(PyExc_TypeError,
"bad type passed to time pickler: %s",
time->ob_type->tp_name);
return NULL;
}
state = timetz_getstate(time);
if (state) {
result = Py_BuildValue("O(O)",
time_unpickler_object,
state);
Py_DECREF(state);
}
return result;
}
static PyObject *
timetz_unpickler(PyObject *module, PyObject *arg)
{
PyDateTime_TimeTZ *self;
if (! PyString_CheckExact(arg)) {
PyErr_Format(PyExc_TypeError,
"bad type passed to time unpickler: %s",
arg->ob_type->tp_name);
return NULL;
}
self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
if (self != NULL) {
PyObject *res = timetz_setstate(self, arg);
Py_XDECREF(res);
}
return (PyObject *)self;
}
static PyMethodDef timetz_methods[] = {
{"isoformat", (PyCFunction)timetz_isoformat, METH_KEYWORDS,
PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm].")},
{"strftime", (PyCFunction)timetz_strftime, METH_O,
PyDoc_STR("format -> strftime() style string.")},
{"__setstate__", (PyCFunction)timetz_setstate, METH_O,
PyDoc_STR("__setstate__(state)")},
{"__getstate__", (PyCFunction)timetz_getstate, METH_NOARGS,
PyDoc_STR("__getstate__() -> state")},
{NULL, NULL}
};
static char timetz_doc[] =
PyDoc_STR("Time type.");
static PyNumberMethods timetz_as_number = {
0, /* nb_add */
0, /* nb_subtract */
0, /* nb_multiply */
0, /* nb_divide */
0, /* nb_remainder */
0, /* nb_divmod */
0, /* nb_power */
0, /* nb_negative */
0, /* nb_positive */
0, /* nb_absolute */
(inquiry)time_nonzero, /* nb_nonzero */
};
statichere PyTypeObject PyDateTime_TimeTZType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
/* XXX When this module is renamed to datetime, change tp_name. */
"_datetime.time", /* tp_name */
sizeof(PyDateTime_TimeTZ), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PyObject_Del, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)timetz_repr, /* tp_repr */
&timetz_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)timetz_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)timetz_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
time_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
(richcmpfunc)time_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
time_methods, /* tp_methods */
0, /* tp_members */
time_getset, /* tp_getset */
&PyDateTime_TimeType, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
timetz_new, /* tp_new */
_PyObject_Del, /* tp_free */
};
Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** datetime.c 9 Dec 2002 21:37:37 -0000 1.52
--- datetime.c 10 Dec 2002 02:04:26 -0000 1.53
***************
*** 72,75 ****
--- 72,76 ----
static PyTypeObject PyDateTime_DeltaType;
static PyTypeObject PyDateTime_TimeType;
+ static PyTypeObject PyDateTime_TimeTZType;
/*
***************
*** 632,635 ****
--- 633,637 ----
static PyObject *datetime_unpickler_object = NULL;
static PyObject *time_unpickler_object = NULL;
+ static PyObject *timetz_unpickler_object = NULL;
/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
***************
*** 663,666 ****
--- 665,669 ----
#include "obj_datetime.c"
#include "obj_time.c"
+ #include "obj_timetz.c"
***************
*** 675,678 ****
--- 678,683 ----
{"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
{"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
+ {"_timetz_pickler", (PyCFunction)timetz_pickler, METH_O, NULL},
+ {"_timetz_unpickler", (PyCFunction)timetz_unpickler, METH_O, NULL},
{NULL, NULL}
};
***************
*** 699,702 ****
--- 704,709 ----
if (PyType_Ready(&PyDateTime_TimeType) < 0)
return;
+ if (PyType_Ready(&PyDateTime_TimeTZType) < 0)
+ return;
/* timedelta values */
***************
*** 796,799 ****
--- 803,809 ----
PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
+ Py_INCREF(&PyDateTime_TimeTZType);
+ PyModule_AddObject(m, "timetz", (PyObject *) &PyDateTime_TimeTZType);
+
/* A 4-year cycle has an extra leap day over what we'd get from
***************
*** 875,878 ****
--- 885,900 ----
Py_DECREF(pickler);
+ pickler = PyObject_GetAttrString(m, "_timetz_pickler");
+ assert(pickler);
+ timetz_unpickler_object = PyObject_GetAttrString(m,
+ "_timetz_unpickler");
+ assert(time_unpickler_object);
+ temp = PyObject_CallMethod(copyreg, "pickle", "OOO",
+ &PyDateTime_TimeTZType,
+ pickler,
+ timetz_unpickler_object);
+ assert(temp);
+ Py_DECREF(temp);
+ Py_DECREF(pickler);
Py_DECREF(copyreg);
}
Index: datetime.h
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** datetime.h 7 Dec 2002 18:34:39 -0000 1.12
--- datetime.h 10 Dec 2002 02:04:26 -0000 1.13
***************
*** 53,56 ****
--- 53,64 ----
{
PyObject_HEAD
+ long hashcode;
+ unsigned char data[_PyDateTime_TIME_DATASIZE];
+ PyObject *tzinfo;
+ } PyDateTime_TimeTZ;
+
+ typedef struct
+ {
+ PyObject_HEAD
long hashcode; /* -1 when unknown */
long days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
***************
*** 74,78 ****
((PyDateTime_DateTime*)o)->data[9])
! /* Apply for time instances. */
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])
--- 82,86 ----
((PyDateTime_DateTime*)o)->data[9])
! /* Apply for time and timetz instances. */
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])