gh-117398: Move types to datetime state (#118606)

Move types to the datetime_state structure of the _datetime
extension.
This commit is contained in:
Victor Stinner 2024-05-10 15:24:06 +02:00 committed by GitHub
parent 004db2170e
commit a895756aec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -25,24 +25,15 @@
# include <winsock2.h> /* struct timeval */ # include <winsock2.h> /* struct timeval */
#endif #endif
#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType)
#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType)
#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType)
#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
typedef struct { typedef struct {
PyTypeObject *date_type;
PyTypeObject *datetime_type;
PyTypeObject *delta_type;
PyTypeObject *isocalendar_date_type;
PyTypeObject *time_type;
PyTypeObject *tzinfo_type;
PyTypeObject *timezone_type;
/* Conversion factors. */ /* Conversion factors. */
PyObject *us_per_ms; // 1_000 PyObject *us_per_ms; // 1_000
PyObject *us_per_second; // 1_000_000 PyObject *us_per_second; // 1_000_000
@ -61,7 +52,27 @@ typedef struct {
static datetime_state _datetime_global_state; static datetime_state _datetime_global_state;
#define STATIC_STATE() (&_datetime_global_state) static inline datetime_state* get_datetime_state(void)
{
return &_datetime_global_state;
}
#define PyDate_Check(op) PyObject_TypeCheck(op, get_datetime_state()->date_type)
#define PyDate_CheckExact(op) Py_IS_TYPE(op, get_datetime_state()->date_type)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, get_datetime_state()->datetime_type)
#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, get_datetime_state()->datetime_type)
#define PyTime_Check(op) PyObject_TypeCheck(op, get_datetime_state()->time_type)
#define PyTime_CheckExact(op) Py_IS_TYPE(op, get_datetime_state()->time_type)
#define PyDelta_Check(op) PyObject_TypeCheck(op, get_datetime_state()->delta_type)
#define PyDelta_CheckExact(op) Py_IS_TYPE(op, get_datetime_state()->delta_type)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, get_datetime_state()->tzinfo_type)
#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, get_datetime_state()->tzinfo_type)
#define PyTimezone_Check(op) PyObject_TypeCheck(op, get_datetime_state()->timezone_type)
/* We require that C int be at least 32 bits, and use int virtually /* 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 * everywhere. In just a few cases we use a temp long, where a Python
@ -142,25 +153,16 @@ static datetime_state _datetime_global_state;
*/ */
#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12) #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
/* Forward declarations. */
static PyTypeObject PyDateTime_DateType;
static PyTypeObject PyDateTime_DateTimeType;
static PyTypeObject PyDateTime_DeltaType;
static PyTypeObject PyDateTime_IsoCalendarDateType;
static PyTypeObject PyDateTime_TimeType;
static PyTypeObject PyDateTime_TZInfoType;
static PyTypeObject PyDateTime_TimeZoneType;
static int check_tzinfo_subclass(PyObject *p); static int check_tzinfo_subclass(PyObject *p);
/*[clinic input] /*[clinic input]
module datetime module datetime
class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" class datetime.datetime "PyDateTime_DateTime *" "get_datetime_state()->datetime_type"
class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType" class datetime.date "PyDateTime_Date *" "get_datetime_state()->date_type"
class datetime.time "PyDateTime_Time *" "&PyDateTime_TimeType" class datetime.time "PyDateTime_Time *" "get_datetime_state()->time_type"
class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType" class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "get_datetime_state()->isocalendar_date_type"
[clinic start generated code]*/ [clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6f65a48dd22fa40f]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c8f3d834a860d50a]*/
#include "clinic/_datetimemodule.c.h" #include "clinic/_datetimemodule.c.h"
@ -979,7 +981,7 @@ new_date_ex(int year, int month, int day, PyTypeObject *type)
} }
#define new_date(year, month, day) \ #define new_date(year, month, day) \
new_date_ex(year, month, day, &PyDateTime_DateType) new_date_ex(year, month, day, get_datetime_state()->date_type)
// Forward declaration // Forward declaration
static PyObject * static PyObject *
@ -989,12 +991,13 @@ new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
static PyObject * static PyObject *
new_date_subclass_ex(int year, int month, int day, PyObject *cls) new_date_subclass_ex(int year, int month, int day, PyObject *cls)
{ {
datetime_state *st = get_datetime_state();
PyObject *result; PyObject *result;
// We have "fast path" constructors for two subclasses: date and datetime // We have "fast path" constructors for two subclasses: date and datetime
if ((PyTypeObject *)cls == &PyDateTime_DateType) { if ((PyTypeObject *)cls == st->date_type) {
result = new_date_ex(year, month, day, (PyTypeObject *)cls); result = new_date_ex(year, month, day, (PyTypeObject *)cls);
} }
else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) { else if ((PyTypeObject *)cls == st->datetime_type) {
result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None, result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
(PyTypeObject *)cls); (PyTypeObject *)cls);
} }
@ -1049,7 +1052,7 @@ new_datetime_ex(int year, int month, int day, int hour, int minute,
#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \ #define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \ new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
&PyDateTime_DateTimeType) get_datetime_state()->datetime_type)
static PyObject * static PyObject *
call_subclass_fold(PyObject *cls, int fold, const char *format, ...) call_subclass_fold(PyObject *cls, int fold, const char *format, ...)
@ -1088,9 +1091,11 @@ Done:
static PyObject * static PyObject *
new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute, new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
int second, int usecond, PyObject *tzinfo, int second, int usecond, PyObject *tzinfo,
int fold, PyObject *cls) { int fold, PyObject *cls)
{
datetime_state *st = get_datetime_state();
PyObject* dt; PyObject* dt;
if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) { if ((PyTypeObject*)cls == st->datetime_type) {
// Use the fast path constructor // Use the fast path constructor
dt = new_datetime(year, month, day, hour, minute, second, usecond, dt = new_datetime(year, month, day, hour, minute, second, usecond,
tzinfo, fold); tzinfo, fold);
@ -1152,14 +1157,15 @@ new_time_ex(int hour, int minute, int second, int usecond,
} }
#define new_time(hh, mm, ss, us, tzinfo, fold) \ #define new_time(hh, mm, ss, us, tzinfo, fold) \
new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType) new_time_ex2(hh, mm, ss, us, tzinfo, fold, get_datetime_state()->time_type)
static PyObject * static PyObject *
new_time_subclass_fold_ex(int hour, int minute, int second, int usecond, new_time_subclass_fold_ex(int hour, int minute, int second, int usecond,
PyObject *tzinfo, int fold, PyObject *cls) PyObject *tzinfo, int fold, PyObject *cls)
{ {
PyObject *t; PyObject *t;
if ((PyTypeObject*)cls == &PyDateTime_TimeType) { datetime_state *st = get_datetime_state();
if ((PyTypeObject*)cls == st->time_type) {
// Use the fast path constructor // Use the fast path constructor
t = new_time(hour, minute, second, usecond, tzinfo, fold); t = new_time(hour, minute, second, usecond, tzinfo, fold);
} }
@ -1203,7 +1209,7 @@ new_delta_ex(int days, int seconds, int microseconds, int normalize,
} }
#define new_delta(d, s, us, normalize) \ #define new_delta(d, s, us, normalize) \
new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) new_delta_ex(d, s, us, normalize, get_datetime_state()->delta_type)
typedef struct typedef struct
@ -1221,7 +1227,8 @@ static PyObject *
create_timezone(PyObject *offset, PyObject *name) create_timezone(PyObject *offset, PyObject *name)
{ {
PyDateTime_TimeZone *self; PyDateTime_TimeZone *self;
PyTypeObject *type = &PyDateTime_TimeZoneType; datetime_state *st = get_datetime_state();
PyTypeObject *type = st->timezone_type;
assert(offset != NULL); assert(offset != NULL);
assert(PyDelta_Check(offset)); assert(PyDelta_Check(offset));
@ -1246,7 +1253,7 @@ new_timezone(PyObject *offset, PyObject *name)
assert(name == NULL || PyUnicode_Check(name)); assert(name == NULL || PyUnicode_Check(name));
if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
return Py_NewRef(st->utc); return Py_NewRef(st->utc);
} }
if ((GET_TD_DAYS(offset) == -1 && if ((GET_TD_DAYS(offset) == -1 &&
@ -1460,7 +1467,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
if (rv == 1) { if (rv == 1) {
// Create a timezone from offset in seconds (0 returns UTC) // Create a timezone from offset in seconds (0 returns UTC)
if (tzoffset == 0) { if (tzoffset == 0) {
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
return Py_NewRef(st->utc); return Py_NewRef(st->utc);
} }
@ -1893,7 +1900,7 @@ delta_to_microseconds(PyDateTime_Delta *self)
x1 = PyLong_FromLong(GET_TD_DAYS(self)); x1 = PyLong_FromLong(GET_TD_DAYS(self));
if (x1 == NULL) if (x1 == NULL)
goto Done; goto Done;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
x2 = PyNumber_Multiply(x1, st->seconds_per_day); /* days in seconds */ x2 = PyNumber_Multiply(x1, st->seconds_per_day); /* days in seconds */
if (x2 == NULL) if (x2 == NULL)
goto Done; goto Done;
@ -1966,7 +1973,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
PyObject *num = NULL; PyObject *num = NULL;
PyObject *result = NULL; PyObject *result = NULL;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
tuple = checked_divmod(pyus, st->us_per_second); tuple = checked_divmod(pyus, st->us_per_second);
if (tuple == NULL) { if (tuple == NULL) {
goto Done; goto Done;
@ -2019,7 +2026,7 @@ BadDivmod:
} }
#define microseconds_to_delta(pymicros) \ #define microseconds_to_delta(pymicros) \
microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType) microseconds_to_delta_ex(pymicros, get_datetime_state()->delta_type)
static PyObject * static PyObject *
multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta) multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
@ -2585,7 +2592,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us); y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us);
CLEANUP; CLEANUP;
} }
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
if (ms) { if (ms) {
y = accum("milliseconds", x, ms, st->us_per_ms, &leftover_us); y = accum("milliseconds", x, ms, st->us_per_ms, &leftover_us);
CLEANUP; CLEANUP;
@ -2762,7 +2769,7 @@ delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
if (total_microseconds == NULL) if (total_microseconds == NULL)
return NULL; return NULL;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
total_seconds = PyNumber_TrueDivide(total_microseconds, st->us_per_second); total_seconds = PyNumber_TrueDivide(total_microseconds, st->us_per_second);
Py_DECREF(total_microseconds); Py_DECREF(total_microseconds);
@ -3475,8 +3482,9 @@ date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
week = 0; week = 0;
} }
PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, datetime_state *st = get_datetime_state();
year, week + 1, day + 1); PyObject *v = iso_calendar_date_new_impl(st->isocalendar_date_type,
year, week + 1, day + 1);
if (v == NULL) { if (v == NULL) {
return NULL; return NULL;
} }
@ -3945,8 +3953,9 @@ timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{ {
PyObject *offset; PyObject *offset;
PyObject *name = NULL; PyObject *name = NULL;
datetime_state *st = get_datetime_state();
if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws, if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
&PyDateTime_DeltaType, &offset, &name)) st->delta_type, &offset, &name))
return new_timezone(offset, name); return new_timezone(offset, name);
return NULL; return NULL;
@ -3999,7 +4008,7 @@ timezone_repr(PyDateTime_TimeZone *self)
to use Py_TYPE(self)->tp_name here. */ to use Py_TYPE(self)->tp_name here. */
const char *type_name = Py_TYPE(self)->tp_name; const char *type_name = Py_TYPE(self)->tp_name;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
if (((PyObject *)self) == st->utc) { if (((PyObject *)self) == st->utc) {
return PyUnicode_FromFormat("%s.utc", type_name); return PyUnicode_FromFormat("%s.utc", type_name);
} }
@ -4022,7 +4031,7 @@ timezone_str(PyDateTime_TimeZone *self)
if (self->name != NULL) { if (self->name != NULL) {
return Py_NewRef(self->name); return Py_NewRef(self->name);
} }
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
if ((PyObject *)self == st->utc || if ((PyObject *)self == st->utc ||
(GET_TD_DAYS(self->offset) == 0 && (GET_TD_DAYS(self->offset) == 0 &&
GET_TD_SECONDS(self->offset) == 0 && GET_TD_SECONDS(self->offset) == 0 &&
@ -4686,7 +4695,8 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) {
} }
PyObject *t; PyObject *t;
if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) { datetime_state *st = get_datetime_state();
if ( (PyTypeObject *)cls == st->time_type) {
t = new_time(hour, minute, second, microsecond, tzinfo, 0); t = new_time(hour, minute, second, microsecond, tzinfo, 0);
} else { } else {
t = PyObject_CallFunction(cls, "iiiiO", t = PyObject_CallFunction(cls, "iiiiO",
@ -5284,9 +5294,10 @@ datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
PyObject *tzinfo = NULL; PyObject *tzinfo = NULL;
PyObject *result = NULL; PyObject *result = NULL;
datetime_state *st = get_datetime_state();
if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords, if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
&PyDateTime_DateType, &date, st->date_type, &date,
&PyDateTime_TimeType, &time, &tzinfo)) { st->time_type, &time, &tzinfo)) {
if (tzinfo == NULL) { if (tzinfo == NULL) {
if (HASTZINFO(time)) if (HASTZINFO(time))
tzinfo = ((PyDateTime_Time *)time)->tzinfo; tzinfo = ((PyDateTime_Time *)time)->tzinfo;
@ -6116,6 +6127,7 @@ local_timezone_from_timestamp(time_t timestamp)
delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1); delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
#else /* HAVE_STRUCT_TM_TM_ZONE */ #else /* HAVE_STRUCT_TM_TM_ZONE */
{ {
datetime_state *st = get_datetime_state();
PyObject *local_time, *utc_time; PyObject *local_time, *utc_time;
struct tm utc_time_tm; struct tm utc_time_tm;
char buf[100]; char buf[100];
@ -6170,10 +6182,11 @@ local_timezone(PyDateTime_DateTime *utc_time)
PyObject *one_second; PyObject *one_second;
PyObject *seconds; PyObject *seconds;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
delta = datetime_subtract((PyObject *)utc_time, st->epoch); delta = datetime_subtract((PyObject *)utc_time, st->epoch);
if (delta == NULL) if (delta == NULL)
return NULL; return NULL;
one_second = new_delta(0, 1, 0, 0); one_second = new_delta(0, 1, 0, 0);
if (one_second == NULL) { if (one_second == NULL) {
Py_DECREF(delta); Py_DECREF(delta);
@ -6283,7 +6296,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
if (result == NULL) if (result == NULL)
return NULL; return NULL;
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
/* Make sure result is aware and UTC. */ /* Make sure result is aware and UTC. */
if (!HASTZINFO(result)) { if (!HASTZINFO(result)) {
temp = (PyObject *)result; temp = (PyObject *)result;
@ -6408,7 +6421,7 @@ datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
PyObject *result; PyObject *result;
if (HASTZINFO(self) && self->tzinfo != Py_None) { if (HASTZINFO(self) && self->tzinfo != Py_None) {
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
PyObject *delta; PyObject *delta;
delta = datetime_subtract((PyObject *)self, st->epoch); delta = datetime_subtract((PyObject *)self, st->epoch);
if (delta == NULL) if (delta == NULL)
@ -6712,16 +6725,18 @@ static PyMethodDef module_methods[] = {
static inline PyDateTime_CAPI * static inline PyDateTime_CAPI *
get_datetime_capi(void) get_datetime_capi(void)
{ {
datetime_state *st = get_datetime_state();
PyDateTime_CAPI *capi = PyMem_Malloc(sizeof(PyDateTime_CAPI)); PyDateTime_CAPI *capi = PyMem_Malloc(sizeof(PyDateTime_CAPI));
if (capi == NULL) { if (capi == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
capi->DateType = &PyDateTime_DateType; capi->DateType = st->date_type;
capi->DateTimeType = &PyDateTime_DateTimeType; capi->DateTimeType = st->datetime_type;
capi->TimeType = &PyDateTime_TimeType; capi->TimeType = st->time_type;
capi->DeltaType = &PyDateTime_DeltaType; capi->DeltaType = st->delta_type;
capi->TZInfoType = &PyDateTime_TZInfoType; capi->TZInfoType = st->tzinfo_type;
capi->Date_FromDate = new_date_ex; capi->Date_FromDate = new_date_ex;
capi->DateTime_FromDateAndTime = new_datetime_ex; capi->DateTime_FromDateAndTime = new_datetime_ex;
capi->Time_FromTime = new_time_ex; capi->Time_FromTime = new_time_ex;
@ -6733,7 +6748,6 @@ get_datetime_capi(void)
capi->Time_FromTimeAndFold = new_time_ex2; capi->Time_FromTimeAndFold = new_time_ex2;
// Make sure this function is called after utc has // Make sure this function is called after utc has
// been initialized. // been initialized.
datetime_state *st = STATIC_STATE();
assert(st->utc != NULL); assert(st->utc != NULL);
capi->TimeZone_UTC = st->utc; // borrowed ref capi->TimeZone_UTC = st->utc; // borrowed ref
return capi; return capi;
@ -6749,7 +6763,7 @@ datetime_destructor(PyObject *op)
static int static int
datetime_clear(PyObject *module) datetime_clear(PyObject *module)
{ {
datetime_state *st = STATIC_STATE(); datetime_state *st = get_datetime_state();
Py_CLEAR(st->us_per_ms); Py_CLEAR(st->us_per_ms);
Py_CLEAR(st->us_per_second); Py_CLEAR(st->us_per_second);
@ -6778,6 +6792,14 @@ create_timezone_from_delta(int days, int sec, int ms, int normalize)
static int static int
init_state(datetime_state *st) init_state(datetime_state *st)
{ {
st->date_type = &PyDateTime_DateType;
st->datetime_type = &PyDateTime_DateTimeType;
st->delta_type = &PyDateTime_DeltaType;
st->isocalendar_date_type = &PyDateTime_IsoCalendarDateType;
st->time_type = &PyDateTime_TimeType;
st->tzinfo_type = &PyDateTime_TZInfoType;
st->timezone_type = &PyDateTime_TimeZoneType;
st->us_per_ms = PyLong_FromLong(1000); st->us_per_ms = PyLong_FromLong(1000);
if (st->us_per_ms == NULL) { if (st->us_per_ms == NULL) {
return -1; return -1;
@ -6854,6 +6876,11 @@ _datetime_exec(PyObject *module)
goto error; goto error;
} }
datetime_state *st = get_datetime_state();
if (init_state(st) < 0) {
goto error;
}
#define DATETIME_ADD_MACRO(dict, c, value_expr) \ #define DATETIME_ADD_MACRO(dict, c, value_expr) \
do { \ do { \
PyObject *value = (value_expr); \ PyObject *value = (value_expr); \
@ -6868,39 +6895,34 @@ _datetime_exec(PyObject *module)
} while(0) } while(0)
/* timedelta values */ /* timedelta values */
PyObject *d = PyDateTime_DeltaType.tp_dict; PyObject *d = st->delta_type->tp_dict;
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0)); DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
DATETIME_ADD_MACRO(d, "max", DATETIME_ADD_MACRO(d, "max",
new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0)); new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
/* date values */ /* date values */
d = PyDateTime_DateType.tp_dict; d = st->date_type->tp_dict;
DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1)); DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31)); DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
/* time values */ /* time values */
d = PyDateTime_TimeType.tp_dict; d = st->time_type->tp_dict;
DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0)); DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0)); DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
/* datetime values */ /* datetime values */
d = PyDateTime_DateTimeType.tp_dict; d = st->datetime_type->tp_dict;
DATETIME_ADD_MACRO(d, "min", DATETIME_ADD_MACRO(d, "min",
new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0)); new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59, DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
999999, Py_None, 0)); 999999, Py_None, 0));
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
datetime_state *st = STATIC_STATE();
if (init_state(st) < 0) {
goto error;
}
/* timezone values */ /* timezone values */
d = PyDateTime_TimeZoneType.tp_dict; d = st->timezone_type->tp_dict;
if (PyDict_SetItemString(d, "utc", st->utc) < 0) { if (PyDict_SetItemString(d, "utc", st->utc) < 0) {
goto error; goto error;
} }