diff options
-rw-r--r-- | Doc/api/concrete.tex | 193 | ||||
-rw-r--r-- | Include/datetime.h | 95 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 30 |
5 files changed, 287 insertions, 36 deletions
diff --git a/Doc/api/concrete.tex b/Doc/api/concrete.tex index 63f9667..176d786 100644 --- a/Doc/api/concrete.tex +++ b/Doc/api/concrete.tex @@ -137,7 +137,7 @@ There is no \cfunction{PyNone_Check()} function for the same reason. int base} Return a new \ctype{PyIntObject} or \ctype{PyLongObject} based on the string value in \var{str}, which is interpreted according to the radix in - \var{base}. If \var{pend} is non-\NULL, \code{*\var{pend}} will point to + \var{base}. If \var{pend} is non-\NULL{}, \code{*\var{pend}} will point to the first character in \var{str} which follows the representation of the number. If \var{base} is \code{0}, the radix will be determined based on the leading characters of \var{str}: if \var{str} starts with \code{'0x'} @@ -248,7 +248,7 @@ There is no \cfunction{PyNone_Check()} function for the same reason. int base} Return a new \ctype{PyLongObject} based on the string value in \var{str}, which is interpreted according to the radix in - \var{base}. If \var{pend} is non-\NULL, \code{*\var{pend}} will + \var{base}. If \var{pend} is non-\NULL{}, \code{*\var{pend}} will point to the first character in \var{str} which follows the representation of the number. If \var{base} is \code{0}, the radix will be determined based on the leading characters of \var{str}: if @@ -538,7 +538,7 @@ parameter and are called with a non-string parameter. \begin{cfuncdesc}{PyObject*}{PyString_FromString}{const char *v} Returns a new string object with the value \var{v} on success, and - \NULL{} on failure. The parameter \var{v} must not be \NULL; it + \NULL{} on failure. The parameter \var{v} must not be \NULL{}; it will not be checked. \end{cfuncdesc} @@ -546,7 +546,7 @@ parameter and are called with a non-string parameter. int len} Returns a new string object with the value \var{v} and length \var{len} on success, and \NULL{} on failure. If \var{v} is - \NULL, the contents of the string are uninitialized. + \NULL{}, the contents of the string are uninitialized. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyString_FromFormat}{const char *format, ...} @@ -615,7 +615,7 @@ parameter and are called with a non-string parameter. The function accepts both string and Unicode objects as input. For Unicode objects it returns the default encoded version of the - object. If \var{length} is \NULL, the resulting buffer may not + object. If \var{length} is \NULL{}, the resulting buffer may not contain NUL characters; if it does, the function returns \code{-1} and a \exception{TypeError} is raised. @@ -636,7 +636,7 @@ parameter and are called with a non-string parameter. new reference. The reference to the old value of \var{string} will be stolen. If the new string cannot be created, the old reference to \var{string} will still be discarded and the value of - \var{*string} will be set to \NULL; the appropriate exception will + \var{*string} will be set to \NULL{}; the appropriate exception will be set. \end{cfuncdesc} @@ -898,9 +898,9 @@ use these APIs: given size. \var{u} may be \NULL{} which causes the contents to be undefined. It is the user's responsibility to fill in the needed data. The buffer is copied into the new object. If the buffer is - not \NULL, the return value might be a shared object. Therefore, + not \NULL{}, the return value might be a shared object. Therefore, modification of the resulting Unicode object is only allowed when - \var{u} is \NULL. + \var{u} is \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{Py_UNICODE*}{PyUnicode_AsUnicode}{PyObject *unicode} @@ -1070,9 +1070,9 @@ These are the UTF-16 codec APIs: int *byteorder} Decodes \var{length} bytes from a UTF-16 encoded buffer string and returns the corresponding Unicode object. \var{errors} (if - non-\NULL) defines the error handling. It defaults to ``strict''. + non-\NULL{}) defines the error handling. It defaults to ``strict''. - If \var{byteorder} is non-\NULL, the decoder starts decoding using + If \var{byteorder} is non-\NULL{}, the decoder starts decoding using the given byte order: \begin{verbatim} @@ -1086,7 +1086,7 @@ These are the UTF-16 codec APIs: string. After completion, \var{*byteorder} is set to the current byte order at the end of input data. - If \var{byteorder} is \NULL, the codec starts in native order mode. + If \var{byteorder} is \NULL{}, the codec starts in native order mode. Returns \NULL{} if an exception was raised by the codec. \end{cfuncdesc} @@ -1351,7 +1351,7 @@ They all return \NULL{} or \code{-1} if an exception occurs. \begin{cfuncdesc}{PyObject*}{PyUnicode_Split}{PyObject *s, PyObject *sep, int maxsplit} - Split a string giving a list of Unicode strings. If sep is \NULL, + Split a string giving a list of Unicode strings. If sep is \NULL{}, splitting will be done at all whitespace substrings. Otherwise, splits occur at the given separator. At most \var{maxsplit} splits will be done. If negative, no limit is set. Separators are not @@ -1605,7 +1605,7 @@ format. The tuple values are initialized to the subsequent \var{n} C arguments pointing to Python objects. \samp{PyTuple_Pack(2, \var{a}, \var{b})} is equivalent to \samp{Py_BuildValue("(OO)", \var{a}, \var{b})}. - \versionadded{2.4} + \versionadded{2.4} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyTuple_Size}{PyObject *p} @@ -1661,7 +1661,7 @@ format. \code{*\var{p}} will be the same as before calling this function. If the object referenced by \code{*\var{p}} is replaced, the original \code{*\var{p}} is destroyed. On failure, returns - \code{-1} and sets \code{*\var{p}} to \NULL, and raises + \code{-1} and sets \code{*\var{p}} to \NULL{}, and raises \exception{MemoryError} or \exception{SystemError}. \versionchanged[Removed unused third parameter, \var{last_is_sticky}]{2.2} @@ -1841,7 +1841,7 @@ format. in \var{p} is matches \var{key}, return \code{1}, otherwise return \code{0}. On error, return \code{-1}. This is equivalent to the Python expression \samp{\var{key} in \var{p}}. - \versionadded{2.4} + \versionadded{2.4} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyDict_Copy}{PyObject *p} @@ -1923,7 +1923,7 @@ format. dictionary, and false once all pairs have been reported. The parameters \var{pkey} and \var{pvalue} should either point to \ctype{PyObject*} variables that will be filled in with each key and - value, respectively, or may be \NULL. Any references returned through + value, respectively, or may be \NULL{}. Any references returned through them are borrowed. \var{ppos} should not be altered during iteration. Its value represents offsets within the internal dictionary structure, and since the structure is sparse, the offsets are not consecutive. @@ -2040,7 +2040,7 @@ implementation detail and may change in future releases of Python. On success, returns a new file object that is opened on the file given by \var{filename}, with a file mode given by \var{mode}, where \var{mode} has the same semantics as the standard C routine - \cfunction{fopen()}\ttindex{fopen()}. On failure, returns \NULL. + \cfunction{fopen()}\ttindex{fopen()}. On failure, returns \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyFile_FromFile}{FILE *fp, @@ -2143,7 +2143,7 @@ There are very few functions specific to instance objects. Create a new instance of a specific class without calling it's constructor. \var{class} is the class of new object. The \var{dict} parameter will be used as the object's \member{__dict__}; - if \NULL, a new dictionary will be created for the instance. + if \NULL{}, a new dictionary will be created for the instance. \end{cfuncdesc} @@ -2161,7 +2161,7 @@ method objects. \begin{cfuncdesc}{int}{PyMethod_Check}{PyObject *o} Return true if \var{o} is a method object (has type - \cdata{PyMethod_Type}). The parameter must not be \NULL. + \cdata{PyMethod_Type}). The parameter must not be \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMethod_New}{PyObject *func. @@ -2196,7 +2196,7 @@ method objects. \begin{cfuncdesc}{PyObject*}{PyMethod_Self}{PyObject *meth} Return the instance associated with the method \var{meth} if it is - bound, otherwise return \NULL. + bound, otherwise return \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMethod_GET_SELF}{PyObject *meth} @@ -2260,7 +2260,7 @@ There are only a few functions special to module objects. Return the name of the file from which \var{module} was loaded using \var{module}'s \member{__file__} attribute. If this is not defined, or if it is not a string, raise \exception{SystemError} and return - \NULL. + \NULL{}. \withsubitem{(module attribute)}{\ttindex{__file__}} \withsubitem{(built-in exception)}{\ttindex{SystemError}} \end{cfuncdesc} @@ -2401,7 +2401,7 @@ They are found in the dictionary of type objects. \begin{cfuncdesc}{int}{PySlice_Check}{PyObject *ob} Returns true if \var{ob} is a slice object; \var{ob} must not be - \NULL. + \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySlice_New}{PyObject *start, PyObject *stop, @@ -2409,7 +2409,7 @@ They are found in the dictionary of type objects. Return a new slice object with the given values. The \var{start}, \var{stop}, and \var{step} parameters are used as the values of the slice object attributes of the same names. Any of the values may be - \NULL, in which case the \code{None} will be used for the + \NULL{}, in which case the \code{None} will be used for the corresponding attribute. Returns \NULL{} if the new object could not be allocated. \end{cfuncdesc} @@ -2431,7 +2431,7 @@ suitably renamed, in the source of your extension. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySlice_GetIndicesEx}{PySliceObject *slice, int length, - int *start, int *stop, int *step, + int *start, int *stop, int *step, int *slicelength} Usable replacement for \cfunction{PySlice_GetIndices}. Retrieve the start, stop, and step indices from the slice object \var{slice} @@ -2475,9 +2475,9 @@ acts as a proxy for the original object as much as it can. parameter, \var{callback}, can be a callable object that receives notification when \var{ob} is garbage collected; it should accept a single parameter, which will be the weak reference object itself. - \var{callback} may also be \code{None} or \NULL. If \var{ob} + \var{callback} may also be \code{None} or \NULL{}. If \var{ob} is not a weakly-referencable object, or if \var{callback} is not - callable, \code{None}, or \NULL, this will return \NULL{} and + callable, \code{None}, or \NULL{}, this will return \NULL{} and raise \exception{TypeError}. \versionadded{2.2} \end{cfuncdesc} @@ -2490,9 +2490,9 @@ acts as a proxy for the original object as much as it can. parameter, \var{callback}, can be a callable object that receives notification when \var{ob} is garbage collected; it should accept a single parameter, which will be the weak reference object itself. - \var{callback} may also be \code{None} or \NULL. If \var{ob} is not + \var{callback} may also be \code{None} or \NULL{}. If \var{ob} is not a weakly-referencable object, or if \var{callback} is not callable, - \code{None}, or \NULL, this will return \NULL{} and raise + \code{None}, or \NULL{}, this will return \NULL{} and raise \exception{TypeError}. \versionadded{2.2} \end{cfuncdesc} @@ -2535,7 +2535,7 @@ information on using these objects. void (*destr)(void *)} Create a \ctype{PyCObject} from the \code{void *}\var{cobj}. The \var{destr} function will be called when the object is reclaimed, - unless it is \NULL. + unless it is \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtrAndDesc}{void* cobj, @@ -2557,7 +2557,7 @@ information on using these objects. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyCObject_SetVoidPtr}{PyObject* self, void* cobj} - Set the void pointer inside \var{self} to \var{cobj}. + Set the void pointer inside \var{self} to \var{cobj}. The \ctype{PyCObject} must not have an associated destructor. Return true on success, false on failure. \end{cfuncdesc} @@ -2585,12 +2585,12 @@ when accessed. Cell objects are not likely to be useful elsewhere. \begin{cfuncdesc}{int}{PyCell_Check}{ob} Return true if \var{ob} is a cell object; \var{ob} must not be - \NULL. + \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyCell_New}{PyObject *ob} Create and return a new cell object containing the value \var{ob}. - The parameter may be \NULL. + The parameter may be \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyCell_Get}{PyObject *cell} @@ -2605,7 +2605,7 @@ when accessed. Cell objects are not likely to be useful elsewhere. \begin{cfuncdesc}{int}{PyCell_Set}{PyObject *cell, PyObject *value} Set the contents of the cell object \var{cell} to \var{value}. This releases the reference to any current content of the cell. - \var{value} may be \NULL. \var{cell} must be non-\NULL; if it is + \var{value} may be \NULL{}. \var{cell} must be non-\NULL{}; if it is not a cell object, \code{-1} will be returned. On success, \code{0} will be returned. \end{cfuncdesc} @@ -2633,16 +2633,137 @@ rather than explicitly calling \cfunction{PyGen_New}. \begin{cfuncdesc}{int}{PyGen_Check}{ob} Return true if \var{ob} is a generator object; \var{ob} must not be - \NULL. + \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyGen_CheckExact}{ob} Return true if \var{ob}'s type is \var{PyGen_Type} is a generator object; \var{ob} must not be - \NULL. + \NULL{}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyGen_New}{PyFrameObject *frame} Create and return a new generator object based on the \var{frame} object. - The parameter must not be \NULL. + The parameter must not be \NULL{}. +\end{cfuncdesc} + + +\subsection{DateTime Objects \label{datetime-objects}} + +Various date and time objects are supplied by the \module{datetime} +module. Before using any of these functions, the header file +\file{datetime.h} must be included in your source (note that this is +not include by \file{Python.h}), and macro \cfunction{PyDateTime_IMPORT()} +must be invoked. The macro arranges to put a pointer to a C structure +in a static variable \code{PyDateTimeAPI}, which is used by the following +macros: + +\begin{cfuncdesc}{int}{PyDate_Check}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DateType} or + a subtype of \cdata{PyDateTime_DateType}. \var{ob} must not be + \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyDate_CheckExact}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DateType}. + \var{ob} must not be \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyDateTime_Check}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType} or + a subtype of \cdata{PyDateTime_DateTimeType}. \var{ob} must not be + \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyDateTime_CheckExact}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType}. + \var{ob} must not be \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyTime_Check}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_TimeType} or + a subtype of \cdata{PyDateTime_TimeType}. \var{ob} must not be + \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyTime_CheckExact}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_TimeType}. + \var{ob} must not be \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyDelta_Check}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType} or + a subtype of \cdata{PyDateTime_DeltaType}. \var{ob} must not be + \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyDelta_CheckExact}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType}. + \var{ob} must not be \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyTZInfo_Check}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType} or + a subtype of \cdata{PyDateTime_TZInfoType}. \var{ob} must not be + \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyTZInfo_CheckExact}{ob} + Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType}. + \var{ob} must not be \NULL{}. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyDate_FromDate}{int year, int month, int day} + Return a \code{datetime.date} object with the specified year, month + and day. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyDate_FromDateAndTime}{int year, int month, + int day, int hour, int minute, int second, int usecond} + Return a \code{datetime.datetime} object with the specified year, month, + day, hour, minute, second and microsecond. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyTime_FromTime}{int hour, int minute, + int second, int usecond} + Return a \code{datetime.time} object with the specified hour, minute, + second and microsecond. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyDelta_FromDSU}{int days, int seconds, + int useconds} + Return a \code{datetime.timedelta} object representing the given number + of days, seconds and microseconds. Normalization is performed so that + the resulting number of microseconds and seconds lie in the ranges + documented for \code{datetime.timedelta} objects. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyDateTime_FromTimestamp}{PyObject *args} + Create and return a new \code{datetime.datetime} object given an argument + tuple suitable for passing to \code{datetime.datetime.fromtimestamp()}. + This macro is included for the convenience of modules implementing the + DB API. + \versionadded{2.4} +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyDate_FromTimestamp}{PyObject *args} + Create and return a new \code{datetime.date} object given an argument + tuple suitable for passing to \code{datetime.date.fromtimestamp()}. + This macro is included for the convenience of modules implementing the + DB API. + \versionadded{2.4} \end{cfuncdesc} diff --git a/Include/datetime.h b/Include/datetime.h index 9364e24..1b8ebb9 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -3,6 +3,9 @@ #ifndef DATETIME_H #define DATETIME_H +#ifdef __cplusplus +extern "C" { +#endif /* Fields are packed into successive bytes, each viewed as unsigned and * big-endian, unless otherwise noted: @@ -132,6 +135,36 @@ typedef struct (((PyDateTime_Time*)o)->data[4] << 8) | \ ((PyDateTime_Time*)o)->data[5]) + +/* Define structure for C API. */ +typedef struct { + /* type objects */ + PyTypeObject *DateType; + PyTypeObject *DateTimeType; + PyTypeObject *TimeType; + PyTypeObject *DeltaType; + PyTypeObject *TZInfoType; + + /* constructors */ + PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); + PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, + PyObject*, PyTypeObject*); + PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); + PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); + +} PyDateTime_CAPI; + + +/* "magic" constant used to partially protect against developer mistakes. */ +#define DATETIME_API_MAGIC 0x414548d5 + +#ifdef Py_BUILD_CORE + +/* Macros for type checking when building the Python core. */ #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) #define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType) @@ -147,4 +180,66 @@ typedef struct #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) #define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType) +#else + +/* Define global variable for the C API and a macro for setting it. */ +static PyDateTime_CAPI *PyDateTimeAPI; + +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \ + "datetime_CAPI") + +/* This macro would be used if PyCObject_ImportEx() was created. +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \ + "datetime_CAPI", \ + DATETIME_API_MAGIC) +*/ + +/* Macros for type checking when not building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType) + +/* Macros for accessing constructors in a simplified fashion. */ +#define PyDate_FromDate(year, month, day) \ + PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + +#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ + PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ + min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + +#define PyTime_FromTime(hour, minute, second, usecond) \ + PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + Py_None, PyDateTimeAPI->TimeType) + +#define PyDelta_FromDSU(days, seconds, useconds) \ + PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, + PyDateTimeAPI->DeltaType) + +/* Macros supporting the DB API. */ +#define PyDateTime_FromTimestamp(args) \ + PyDateTimeAPI->DateTime_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + +#define PyDate_FromTimestamp(args) \ + PyDateTimeAPI->Date_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateType), args) + +#endif /* Py_BUILD_CORE */ + +#ifdef __cplusplus +} +#endif #endif @@ -569,6 +569,7 @@ Richard Townsend Laurence Tratt John Tromp Jason Trowbridge +Anthony Tuininga Stephen Turner Bill Tutt Doobee R. Tzeck @@ -559,6 +559,10 @@ Build C API ----- +- Thanks to Anthony Tuininga, the datetime module now supplies a C API + containing type-check macros and constructors. See new docs in the + Python/C API Reference Manual for details. + - Private function _PyTime_DoubleToTimet added, to convert a Python timestamp (C double) to platform time_t with some out-of-bounds checking. Declared in new header file timefuncs.h. It would be diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index d9cf604..ee7387c 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -9,7 +9,13 @@ #include <time.h> #include "timefuncs.h" + +/* Differentiate between building the core module and building extension + * modules. + */ +#define Py_BUILD_CORE #include "datetime.h" +#undef Py_BUILD_CORE /* We require that C int be at least 32 bits, and use int virtually * everywhere. In just a few cases we use a temp long, where a Python @@ -4520,6 +4526,24 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; +/* C API. Clients get at this via PyDateTime_IMPORT, defined in + * datetime.h. + */ +static PyDateTime_CAPI CAPI = { + &PyDateTime_DateType, + &PyDateTime_DateTimeType, + &PyDateTime_TimeType, + &PyDateTime_DeltaType, + &PyDateTime_TZInfoType, + new_date_ex, + new_datetime_ex, + new_time_ex, + new_delta_ex, + datetime_fromtimestamp, + date_fromtimestamp +}; + + PyMODINIT_FUNC initdatetime(void) { @@ -4633,6 +4657,12 @@ initdatetime(void) Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); + x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC, + NULL); + if (x == NULL) + return; + PyModule_AddObject(m, "datetime_CAPI", x); + /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. */ |