David M. Cookie writes: > You don't check for errors: an exception being thrown by > PyObject_CallMethod will return obj == NULL.
Oops, missed that one. Thanks. > If there's a module in sys.path called time that overrides the stdlib > time, things will fail, and you should be able to catch that. Maybe someone really does want to override the time module, and then we shouldn't get in their way? For example, if someone adds a new field descriptor for nanoseconds to time.strptime, then it'd be nice to have it work with datetime.datetime.strptime as well. Incidentally, this is the way that the rest of datetime does it. > Are you positive those PySequence_GetItem calls will succeed? That > they will return Python integers? Well, without interfaces, I can't be sure :). Throwing an exception is cool (especially if we do allow user implemented time.strptime).
--- Modules/datetimemodule.c.orig 2003-10-20 10:34:46.000000000 -0400 +++ Modules/datetimemodule.c 2005-01-11 10:42:23.000000000 -0500 @@ -3774,6 +3774,47 @@ return result; } +/* Return new datetime from time.strptime(). */ +static PyObject * +datetime_strptime(PyObject *cls, PyObject *args) +{ + PyObject *result = NULL, *obj, *module; + const char *string, *format; + + if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format)) + return NULL; + + if ((module = PyImport_ImportModule("time")) == NULL) + return NULL; + obj = PyObject_CallMethod(module, "strptime", "ss", string, format); + Py_DECREF(module); + + if (obj != NULL) { + int good_timetuple = 1; + if (PySequence_Check(obj) && PySequence_Size(obj) > 6) { + int i; + for (i=0; i <= 6; i++) + if (!PyInt_Check(PySequence_GetItem(obj, i))) + good_timetuple = 0; + } else + good_timetuple = 0; + if (good_timetuple) + result = PyObject_CallFunction(cls, "iiiiiii", + PyInt_AsLong(PySequence_GetItem(obj, 0)), + PyInt_AsLong(PySequence_GetItem(obj, 1)), + PyInt_AsLong(PySequence_GetItem(obj, 2)), + PyInt_AsLong(PySequence_GetItem(obj, 3)), + PyInt_AsLong(PySequence_GetItem(obj, 4)), + PyInt_AsLong(PySequence_GetItem(obj, 5)), + PyInt_AsLong(PySequence_GetItem(obj, 6))); + else + PyErr_SetString(PyExc_ValueError, + "unexpected value from time.strptime"); + Py_DECREF(obj); + } + return result; +} + /* Return new datetime from date/datetime and time arguments. */ static PyObject * datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) @@ -4385,6 +4426,11 @@ PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp " "(like time.time()).")}, + {"strptime", (PyCFunction)datetime_strptime, + METH_VARARGS | METH_CLASS, + PyDoc_STR("strptime -> new datetime parsed from a string" + "(like time.strptime()).")}, + {"combine", (PyCFunction)datetime_combine, METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("date, time -> datetime with same date and time fields")}, --- Doc/lib/libdatetime.tex.orig 2003-09-06 01:36:56.000000000 -0400 +++ Doc/lib/libdatetime.tex 2005-01-11 11:06:22.699348152 -0500 @@ -624,6 +624,13 @@ ignored. \end{methoddesc} +\begin{methoddesc}{strptime}{date_string, format} + Return the date corresponding to date_string, parsed according + to format. This is equivalent to \code{datetime(*(time.strptime( + date_string, format)[0:7]))}. \exception{ValueError} is raised if + \code{time.strptime()} returns a value which isn't a timetuple. +\end{methoddesc} + Class attributes: \begin{memberdesc}{min}
-- http://mail.python.org/mailman/listinfo/python-list