@@ -6473,26 +6473,44 @@ static PyMethodDef module_methods[] = {
6473
6473
{NULL , NULL }
6474
6474
};
6475
6475
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.
6478
6478
*/
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
+ }
6496
6514
6497
6515
static int
6498
6516
_datetime_exec (PyObject * module )
@@ -6581,7 +6599,6 @@ _datetime_exec(PyObject *module)
6581
6599
}
6582
6600
6583
6601
PyDateTime_TimeZone_UTC = x ;
6584
- CAPI .TimeZone_UTC = PyDateTime_TimeZone_UTC ;
6585
6602
6586
6603
/* bpo-37642: These attributes are rounded to the nearest minute for backwards
6587
6604
* compatibility, even though the constructor will accept a wider range of
@@ -6619,8 +6636,13 @@ _datetime_exec(PyObject *module)
6619
6636
return -1 ;
6620
6637
}
6621
6638
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 );
6623
6644
if (x == NULL ) {
6645
+ PyMem_Free (capi );
6624
6646
return -1 ;
6625
6647
}
6626
6648
0 commit comments