@@ -6473,26 +6473,44 @@ static PyMethodDef module_methods[] = {
64736473 {NULL , NULL }
64746474};
64756475
6476- /* C API. Clients get at this via PyDateTime_IMPORT, defined in
6477- * datetime.h.
6476+ /* Get a new C API by calling this function.
6477+ * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h.
64786478 */
6479- static PyDateTime_CAPI CAPI = {
6480- & PyDateTime_DateType ,
6481- & PyDateTime_DateTimeType ,
6482- & PyDateTime_TimeType ,
6483- & PyDateTime_DeltaType ,
6484- & PyDateTime_TZInfoType ,
6485- NULL , // PyDatetime_TimeZone_UTC not initialized yet
6486- new_date_ex ,
6487- new_datetime_ex ,
6488- new_time_ex ,
6489- new_delta_ex ,
6490- new_timezone ,
6491- datetime_fromtimestamp ,
6492- datetime_date_fromtimestamp_capi ,
6493- new_datetime_ex2 ,
6494- new_time_ex2
6495- };
6479+ static inline PyDateTime_CAPI *
6480+ get_datetime_capi (void )
6481+ {
6482+ PyDateTime_CAPI * capi = PyMem_Malloc (sizeof (PyDateTime_CAPI ));
6483+ if (capi == NULL ) {
6484+ PyErr_NoMemory ();
6485+ return NULL ;
6486+ }
6487+ capi -> DateType = & PyDateTime_DateType ;
6488+ capi -> DateTimeType = & PyDateTime_DateTimeType ;
6489+ capi -> TimeType = & PyDateTime_TimeType ;
6490+ capi -> DeltaType = & PyDateTime_DeltaType ;
6491+ capi -> TZInfoType = & PyDateTime_TZInfoType ;
6492+ capi -> Date_FromDate = new_date_ex ;
6493+ capi -> DateTime_FromDateAndTime = new_datetime_ex ;
6494+ capi -> Time_FromTime = new_time_ex ;
6495+ capi -> Delta_FromDelta = new_delta_ex ;
6496+ capi -> TimeZone_FromTimeZone = new_timezone ;
6497+ capi -> DateTime_FromTimestamp = datetime_fromtimestamp ;
6498+ capi -> Date_FromTimestamp = datetime_date_fromtimestamp_capi ;
6499+ capi -> DateTime_FromDateAndTimeAndFold = new_datetime_ex2 ;
6500+ capi -> Time_FromTimeAndFold = new_time_ex2 ;
6501+ // Make sure this function is called after PyDateTime_TimeZone_UTC has
6502+ // been initialized.
6503+ assert (PyDateTime_TimeZone_UTC != NULL );
6504+ capi -> TimeZone_UTC = PyDateTime_TimeZone_UTC ; // borrowed ref
6505+ return capi ;
6506+ }
6507+
6508+ static void
6509+ datetime_destructor (PyObject * op )
6510+ {
6511+ void * ptr = PyCapsule_GetPointer (op , PyDateTime_CAPSULE_NAME );
6512+ PyMem_Free (ptr );
6513+ }
64966514
64976515static int
64986516_datetime_exec (PyObject * module )
@@ -6581,7 +6599,6 @@ _datetime_exec(PyObject *module)
65816599 }
65826600
65836601 PyDateTime_TimeZone_UTC = x ;
6584- CAPI .TimeZone_UTC = PyDateTime_TimeZone_UTC ;
65856602
65866603 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
65876604 * compatibility, even though the constructor will accept a wider range of
@@ -6619,8 +6636,13 @@ _datetime_exec(PyObject *module)
66196636 return -1 ;
66206637 }
66216638
6622- x = PyCapsule_New (& CAPI , PyDateTime_CAPSULE_NAME , NULL );
6639+ PyDateTime_CAPI * capi = get_datetime_capi ();
6640+ if (capi == NULL ) {
6641+ return -1 ;
6642+ }
6643+ x = PyCapsule_New (capi , PyDateTime_CAPSULE_NAME , datetime_destructor );
66236644 if (x == NULL ) {
6645+ PyMem_Free (capi );
66246646 return -1 ;
66256647 }
66266648
0 commit comments