SF patch 876130: add C API to datetime module, from Anthony Tuininga.

The LaTeX is untested (well, so is the new API, for that matter).
Note that I also changed NULL to get spelled consistently in concrete.tex.
If that was a wrong thing to do, Fred should yell at me.
This commit is contained in:
Tim Peters 2004-06-20 22:41:32 +00:00
parent 873a277eb4
commit 9ddf40b4e1
5 changed files with 287 additions and 36 deletions

View File

@ -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
@ -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}
@ -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}
@ -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,
@ -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}

View File

@ -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

View File

@ -569,6 +569,7 @@ Richard Townsend
Laurence Tratt
John Tromp
Jason Trowbridge
Anthony Tuininga
Stephen Turner
Bill Tutt
Doobee R. Tzeck

View File

@ -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

View File

@ -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.
*/