@@ -6494,32 +6494,9 @@ static PyDateTime_CAPI CAPI = {
64946494 new_time_ex2
64956495};
64966496
6497-
6498-
6499- static struct PyModuleDef datetimemodule = {
6500- PyModuleDef_HEAD_INIT ,
6501- "_datetime" ,
6502- "Fast implementation of the datetime type." ,
6503- -1 ,
6504- module_methods ,
6505- NULL ,
6506- NULL ,
6507- NULL ,
6508- NULL
6509- };
6510-
6511- PyMODINIT_FUNC
6512- PyInit__datetime (void )
6497+ static int
6498+ _datetime_exec (PyObject * module )
65136499{
6514- PyObject * m ; /* a module object */
6515- PyObject * d ; /* its dict */
6516- PyObject * x ;
6517- PyObject * delta ;
6518-
6519- m = PyModule_Create (& datetimemodule );
6520- if (m == NULL )
6521- return NULL ;
6522-
65236500 // `&...` is not a constant expression according to a strict reading
65246501 // of C standards. Fill tp_base at run-time rather than statically.
65256502 // See https://bugs.python.org/issue40777
@@ -6537,136 +6514,120 @@ PyInit__datetime(void)
65376514 };
65386515
65396516 for (size_t i = 0 ; i < Py_ARRAY_LENGTH (types ); i ++ ) {
6540- if (PyModule_AddType (m , types [i ]) < 0 ) {
6541- return NULL ;
6517+ if (PyModule_AddType (module , types [i ]) < 0 ) {
6518+ return -1 ;
65426519 }
65436520 }
65446521
65456522 if (PyType_Ready (& PyDateTime_IsoCalendarDateType ) < 0 ) {
6546- return NULL ;
6523+ return -1 ;
65476524 }
6548- Py_INCREF (& PyDateTime_IsoCalendarDateType );
6549-
6550- /* timedelta values */
6551- d = PyDateTime_DeltaType .tp_dict ;
6552-
6553- x = new_delta (0 , 0 , 1 , 0 );
6554- if (x == NULL || PyDict_SetItemString (d , "resolution" , x ) < 0 )
6555- return NULL ;
6556- Py_DECREF (x );
65576525
6558- x = new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 );
6559- if (x == NULL || PyDict_SetItemString (d , "min" , x ) < 0 )
6560- return NULL ;
6561- Py_DECREF (x );
6526+ #define DATETIME_ADD_MACRO (dict , c , value_expr ) \
6527+ do { \
6528+ PyObject *value = (value_expr); \
6529+ if (value == NULL) { \
6530+ return -1; \
6531+ } \
6532+ if (PyDict_SetItemString(dict, c, value) < 0) { \
6533+ Py_DECREF(value); \
6534+ return -1; \
6535+ } \
6536+ Py_DECREF(value); \
6537+ } while(0)
65626538
6563- x = new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 );
6564- if (x == NULL || PyDict_SetItemString (d , "max" , x ) < 0 )
6565- return NULL ;
6566- Py_DECREF (x );
6539+ /* timedelta values */
6540+ PyObject * d = PyDateTime_DeltaType .tp_dict ;
6541+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
6542+ DATETIME_ADD_MACRO (d , "min" , new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 ));
6543+ DATETIME_ADD_MACRO (d , "max" ,
6544+ new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 ));
65676545
65686546 /* date values */
65696547 d = PyDateTime_DateType .tp_dict ;
6570-
6571- x = new_date (1 , 1 , 1 );
6572- if (x == NULL || PyDict_SetItemString (d , "min" , x ) < 0 )
6573- return NULL ;
6574- Py_DECREF (x );
6575-
6576- x = new_date (MAXYEAR , 12 , 31 );
6577- if (x == NULL || PyDict_SetItemString (d , "max" , x ) < 0 )
6578- return NULL ;
6579- Py_DECREF (x );
6580-
6581- x = new_delta (1 , 0 , 0 , 0 );
6582- if (x == NULL || PyDict_SetItemString (d , "resolution" , x ) < 0 )
6583- return NULL ;
6584- Py_DECREF (x );
6548+ DATETIME_ADD_MACRO (d , "min" , new_date (1 , 1 , 1 ));
6549+ DATETIME_ADD_MACRO (d , "max" , new_date (MAXYEAR , 12 , 31 ));
6550+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (1 , 0 , 0 , 0 ));
65856551
65866552 /* time values */
65876553 d = PyDateTime_TimeType .tp_dict ;
6588-
6589- x = new_time (0 , 0 , 0 , 0 , Py_None , 0 );
6590- if (x == NULL || PyDict_SetItemString (d , "min" , x ) < 0 )
6591- return NULL ;
6592- Py_DECREF (x );
6593-
6594- x = new_time (23 , 59 , 59 , 999999 , Py_None , 0 );
6595- if (x == NULL || PyDict_SetItemString (d , "max" , x ) < 0 )
6596- return NULL ;
6597- Py_DECREF (x );
6598-
6599- x = new_delta (0 , 0 , 1 , 0 );
6600- if (x == NULL || PyDict_SetItemString (d , "resolution" , x ) < 0 )
6601- return NULL ;
6602- Py_DECREF (x );
6554+ DATETIME_ADD_MACRO (d , "min" , new_time (0 , 0 , 0 , 0 , Py_None , 0 ));
6555+ DATETIME_ADD_MACRO (d , "max" , new_time (23 , 59 , 59 , 999999 , Py_None , 0 ));
6556+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
66036557
66046558 /* datetime values */
66056559 d = PyDateTime_DateTimeType .tp_dict ;
6606-
6607- x = new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 );
6608- if (x == NULL || PyDict_SetItemString (d , "min" , x ) < 0 )
6609- return NULL ;
6610- Py_DECREF (x );
6611-
6612- x = new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 , 999999 , Py_None , 0 );
6613- if (x == NULL || PyDict_SetItemString (d , "max" , x ) < 0 )
6614- return NULL ;
6615- Py_DECREF (x );
6616-
6617- x = new_delta (0 , 0 , 1 , 0 );
6618- if (x == NULL || PyDict_SetItemString (d , "resolution" , x ) < 0 )
6619- return NULL ;
6620- Py_DECREF (x );
6560+ DATETIME_ADD_MACRO (d , "min" ,
6561+ new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 ));
6562+ DATETIME_ADD_MACRO (d , "max" , new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 ,
6563+ 999999 , Py_None , 0 ));
6564+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
66216565
66226566 /* timezone values */
66236567 d = PyDateTime_TimeZoneType .tp_dict ;
6568+ PyObject * delta = new_delta (0 , 0 , 0 , 0 );
6569+ if (delta == NULL ) {
6570+ return -1 ;
6571+ }
66246572
6625- delta = new_delta (0 , 0 , 0 , 0 );
6626- if (delta == NULL )
6627- return NULL ;
6628- x = create_timezone (delta , NULL );
6573+ PyObject * x = create_timezone (delta , NULL );
66296574 Py_DECREF (delta );
6630- if (x == NULL || PyDict_SetItemString (d , "utc" , x ) < 0 )
6631- return NULL ;
6575+ if (x == NULL ) {
6576+ return -1 ;
6577+ }
6578+ if (PyDict_SetItemString (d , "utc" , x ) < 0 ) {
6579+ Py_DECREF (x );
6580+ return -1 ;
6581+ }
6582+
66326583 PyDateTime_TimeZone_UTC = x ;
66336584 CAPI .TimeZone_UTC = PyDateTime_TimeZone_UTC ;
66346585
66356586 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
66366587 * compatibility, even though the constructor will accept a wider range of
66376588 * values. This may change in the future.*/
66386589 delta = new_delta (-1 , 60 , 0 , 1 ); /* -23:59 */
6639- if (delta == NULL )
6640- return NULL ;
6590+ if (delta == NULL ) {
6591+ return -1 ;
6592+ }
6593+
66416594 x = create_timezone (delta , NULL );
66426595 Py_DECREF (delta );
6643- if (x == NULL || PyDict_SetItemString (d , "min" , x ) < 0 )
6644- return NULL ;
6645- Py_DECREF (x );
6596+ DATETIME_ADD_MACRO (d , "min" , x );
66466597
66476598 delta = new_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ); /* +23:59 */
6648- if (delta == NULL )
6649- return NULL ;
6599+ if (delta == NULL ) {
6600+ return -1 ;
6601+ }
6602+
66506603 x = create_timezone (delta , NULL );
66516604 Py_DECREF (delta );
6652- if (x == NULL || PyDict_SetItemString (d , "max" , x ) < 0 )
6653- return NULL ;
6654- Py_DECREF (x );
6605+ DATETIME_ADD_MACRO (d , "max" , x );
66556606
66566607 /* Epoch */
66576608 PyDateTime_Epoch = new_datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 ,
66586609 PyDateTime_TimeZone_UTC , 0 );
6659- if (PyDateTime_Epoch == NULL )
6660- return NULL ;
6610+ if (PyDateTime_Epoch == NULL ) {
6611+ return -1 ;
6612+ }
66616613
66626614 /* module initialization */
6663- PyModule_AddIntMacro (m , MINYEAR );
6664- PyModule_AddIntMacro (m , MAXYEAR );
6615+ if (PyModule_AddIntMacro (module , MINYEAR ) < 0 ) {
6616+ return -1 ;
6617+ }
6618+ if (PyModule_AddIntMacro (module , MAXYEAR ) < 0 ) {
6619+ return -1 ;
6620+ }
66656621
66666622 x = PyCapsule_New (& CAPI , PyDateTime_CAPSULE_NAME , NULL );
6667- if (x == NULL )
6668- return NULL ;
6669- PyModule_AddObject (m , "datetime_CAPI" , x );
6623+ if (x == NULL ) {
6624+ return -1 ;
6625+ }
6626+
6627+ if (PyModule_AddObject (module , "datetime_CAPI" , x ) < 0 ) {
6628+ Py_DECREF (x );
6629+ return -1 ;
6630+ }
66706631
66716632 /* A 4-year cycle has an extra leap day over what we'd get from
66726633 * pasting together 4 single years.
@@ -6691,18 +6652,43 @@ PyInit__datetime(void)
66916652 us_per_minute = PyLong_FromLong (60000000 );
66926653 seconds_per_day = PyLong_FromLong (24 * 3600 );
66936654 if (us_per_ms == NULL || us_per_second == NULL ||
6694- us_per_minute == NULL || seconds_per_day == NULL )
6695- return NULL ;
6655+ us_per_minute == NULL || seconds_per_day == NULL ) {
6656+ return -1 ;
6657+ }
66966658
66976659 /* The rest are too big for 32-bit ints, but even
66986660 * us_per_week fits in 40 bits, so doubles should be exact.
66996661 */
67006662 us_per_hour = PyLong_FromDouble (3600000000.0 );
67016663 us_per_day = PyLong_FromDouble (86400000000.0 );
67026664 us_per_week = PyLong_FromDouble (604800000000.0 );
6703- if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL )
6665+ if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL ) {
6666+ return -1 ;
6667+ }
6668+ return 0 ;
6669+ }
6670+
6671+ static struct PyModuleDef datetimemodule = {
6672+ PyModuleDef_HEAD_INIT ,
6673+ .m_name = "_datetime" ,
6674+ .m_doc = "Fast implementation of the datetime type." ,
6675+ .m_size = -1 ,
6676+ .m_methods = module_methods ,
6677+ };
6678+
6679+ PyMODINIT_FUNC
6680+ PyInit__datetime (void )
6681+ {
6682+ PyObject * mod = PyModule_Create (& datetimemodule );
6683+ if (mod == NULL )
67046684 return NULL ;
6705- return m ;
6685+
6686+ if (_datetime_exec (mod ) < 0 ) {
6687+ Py_DECREF (mod );
6688+ return NULL ;
6689+ }
6690+
6691+ return mod ;
67066692}
67076693
67086694/* ---------------------------------------------------------------------------
0 commit comments