12
12
#endif
13
13
14
14
#include "Python.h"
15
+ #include "pycore_interp.h"
15
16
#include "pycore_long.h" // _PyLong_GetOne()
16
17
#include "pycore_object.h" // _PyObject_Init()
17
18
#include "pycore_time.h" // _PyTime_ObjectToTime_t()
43
44
#define PyTimezone_Check (op ) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
44
45
45
46
typedef struct {
47
+ PyDateTime_CAPI capi ;
48
+
46
49
/* Conversion factors. */
47
50
PyObject * us_per_ms ; // 1_000
48
51
PyObject * us_per_second ; // 1_000_000
@@ -61,7 +64,29 @@ typedef struct {
61
64
62
65
static datetime_state _datetime_global_state ;
63
66
64
- #define STATIC_STATE () (&_datetime_global_state)
67
+ static inline datetime_state *
68
+ get_module_state (PyObject * module )
69
+ {
70
+ return & _datetime_global_state ;
71
+ }
72
+
73
+ static inline datetime_state *
74
+ get_module_state_by_interp (void )
75
+ {
76
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
77
+ void * state = interp -> datetime_module_state ;
78
+ assert (state != NULL );
79
+ return (datetime_state * )state ;
80
+ }
81
+
82
+ PyDateTime_CAPI *
83
+ get_datetime_capi (void )
84
+ {
85
+ return & get_module_state_by_interp ()-> capi ;
86
+ }
87
+
88
+ #define STATIC_STATE () get_module_state_by_interp()
89
+
65
90
66
91
/* We require that C int be at least 32 bits, and use int virtually
67
92
* everywhere. In just a few cases we use a temp long, where a Python
@@ -6701,44 +6726,27 @@ static PyMethodDef module_methods[] = {
6701
6726
{NULL , NULL }
6702
6727
};
6703
6728
6704
- /* Get a new C API by calling this function.
6705
- * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h.
6706
- */
6707
- static inline PyDateTime_CAPI *
6708
- get_datetime_capi (void )
6709
- {
6710
- PyDateTime_CAPI * capi = PyMem_Malloc (sizeof (PyDateTime_CAPI ));
6711
- if (capi == NULL ) {
6712
- PyErr_NoMemory ();
6713
- return NULL ;
6714
- }
6715
- capi -> DateType = & PyDateTime_DateType ;
6716
- capi -> DateTimeType = & PyDateTime_DateTimeType ;
6717
- capi -> TimeType = & PyDateTime_TimeType ;
6718
- capi -> DeltaType = & PyDateTime_DeltaType ;
6719
- capi -> TZInfoType = & PyDateTime_TZInfoType ;
6720
- capi -> Date_FromDate = new_date_ex ;
6721
- capi -> DateTime_FromDateAndTime = new_datetime_ex ;
6722
- capi -> Time_FromTime = new_time_ex ;
6723
- capi -> Delta_FromDelta = new_delta_ex ;
6724
- capi -> TimeZone_FromTimeZone = new_timezone ;
6725
- capi -> DateTime_FromTimestamp = datetime_fromtimestamp ;
6726
- capi -> Date_FromTimestamp = datetime_date_fromtimestamp_capi ;
6727
- capi -> DateTime_FromDateAndTimeAndFold = new_datetime_ex2 ;
6728
- capi -> Time_FromTimeAndFold = new_time_ex2 ;
6729
+ static void
6730
+ set_datetime_capi (datetime_state * st )
6731
+ {
6732
+ st -> capi .DateType = & PyDateTime_DateType ;
6733
+ st -> capi .DateTimeType = & PyDateTime_DateTimeType ;
6734
+ st -> capi .TimeType = & PyDateTime_TimeType ;
6735
+ st -> capi .DeltaType = & PyDateTime_DeltaType ;
6736
+ st -> capi .TZInfoType = & PyDateTime_TZInfoType ;
6737
+ st -> capi .Date_FromDate = new_date_ex ;
6738
+ st -> capi .DateTime_FromDateAndTime = new_datetime_ex ;
6739
+ st -> capi .Time_FromTime = new_time_ex ;
6740
+ st -> capi .Delta_FromDelta = new_delta_ex ;
6741
+ st -> capi .TimeZone_FromTimeZone = new_timezone ;
6742
+ st -> capi .DateTime_FromTimestamp = datetime_fromtimestamp ;
6743
+ st -> capi .Date_FromTimestamp = datetime_date_fromtimestamp_capi ;
6744
+ st -> capi .DateTime_FromDateAndTimeAndFold = new_datetime_ex2 ;
6745
+ st -> capi .Time_FromTimeAndFold = new_time_ex2 ;
6729
6746
// Make sure this function is called after utc has
6730
6747
// been initialized.
6731
- datetime_state * st = STATIC_STATE ();
6732
6748
assert (st -> utc != NULL );
6733
- capi -> TimeZone_UTC = st -> utc ; // borrowed ref
6734
- return capi ;
6735
- }
6736
-
6737
- static void
6738
- datetime_destructor (PyObject * op )
6739
- {
6740
- void * ptr = PyCapsule_GetPointer (op , PyDateTime_CAPSULE_NAME );
6741
- PyMem_Free (ptr );
6749
+ st -> capi .TimeZone_UTC = st -> utc ; // borrowed ref
6742
6750
}
6743
6751
6744
6752
static int
@@ -6823,6 +6831,10 @@ init_state(datetime_state *st)
6823
6831
static int
6824
6832
_datetime_exec (PyObject * module )
6825
6833
{
6834
+ datetime_state * st = get_module_state (module );
6835
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
6836
+ interp -> datetime_module_state = st ;
6837
+
6826
6838
// `&...` is not a constant expression according to a strict reading
6827
6839
// of C standards. Fill tp_base at run-time rather than statically.
6828
6840
// See https://bugs.python.org/issue40777
@@ -6889,7 +6901,6 @@ _datetime_exec(PyObject *module)
6889
6901
999999 , Py_None , 0 ));
6890
6902
DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
6891
6903
6892
- datetime_state * st = STATIC_STATE ();
6893
6904
if (init_state (st ) < 0 ) {
6894
6905
goto error ;
6895
6906
}
@@ -6924,18 +6935,12 @@ _datetime_exec(PyObject *module)
6924
6935
}
6925
6936
6926
6937
/* At last, set up and add the encapsulated C API */
6927
- PyDateTime_CAPI * capi = get_datetime_capi ();
6928
- if (capi == NULL ) {
6929
- goto error ;
6930
- }
6931
- PyObject * capsule = PyCapsule_New (capi , PyDateTime_CAPSULE_NAME ,
6932
- datetime_destructor );
6938
+ set_datetime_capi (st );
6939
+ PyObject * capsule = PyCapsule_New (& st -> capi , PyDateTime_CAPSULE_NAME , NULL );
6933
6940
if (capsule == NULL ) {
6934
- PyMem_Free (capi );
6935
6941
goto error ;
6936
6942
}
6937
6943
if (PyModule_Add (module , "datetime_CAPI" , capsule ) < 0 ) {
6938
- PyMem_Free (capi );
6939
6944
goto error ;
6940
6945
}
6941
6946
0 commit comments