mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	gh-117398: Move types to datetime state (#118606)
Move types to the datetime_state structure of the _datetime extension.
This commit is contained in:
		
							parent
							
								
									004db2170e
								
							
						
					
					
						commit
						a895756aec
					
				
					 1 changed files with 99 additions and 77 deletions
				
			
		| 
						 | 
					@ -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 @@ call_subclass_fold(PyObject *cls, int fold, const char *format, ...)
 | 
				
			||||||
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 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue