@@ -6741,6 +6741,68 @@ datetime_clear(PyObject *module)
67416741 return 0 ;
67426742}
67436743
6744+ static PyObject *
6745+ create_timezone_from_delta (int days , int sec , int ms , int normalize )
6746+ {
6747+ PyObject * delta = new_delta (days , sec , ms , normalize );
6748+ if (delta == NULL ) {
6749+ return NULL ;
6750+ }
6751+ PyObject * tz = create_timezone (delta , NULL );
6752+ Py_DECREF (delta );
6753+ return tz ;
6754+ }
6755+
6756+ static int
6757+ init_state (datetime_state * st )
6758+ {
6759+ st -> us_per_ms = PyLong_FromLong (1000 );
6760+ if (st -> us_per_ms == NULL ) {
6761+ return -1 ;
6762+ }
6763+ st -> us_per_second = PyLong_FromLong (1000000 );
6764+ if (st -> us_per_second == NULL ) {
6765+ return -1 ;
6766+ }
6767+ st -> us_per_minute = PyLong_FromLong (60000000 );
6768+ if (st -> us_per_minute == NULL ) {
6769+ return -1 ;
6770+ }
6771+ st -> seconds_per_day = PyLong_FromLong (24 * 3600 );
6772+ if (st -> seconds_per_day == NULL ) {
6773+ return -1 ;
6774+ }
6775+
6776+ /* The rest are too big for 32-bit ints, but even
6777+ * us_per_week fits in 40 bits, so doubles should be exact.
6778+ */
6779+ st -> us_per_hour = PyLong_FromDouble (3600000000.0 );
6780+ if (st -> us_per_hour == NULL ) {
6781+ return -1 ;
6782+ }
6783+ st -> us_per_day = PyLong_FromDouble (86400000000.0 );
6784+ if (st -> us_per_day == NULL ) {
6785+ return -1 ;
6786+ }
6787+ st -> us_per_week = PyLong_FromDouble (604800000000.0 );
6788+ if (st -> us_per_week == NULL ) {
6789+ return -1 ;
6790+ }
6791+
6792+ /* Init UTC timezone */
6793+ st -> utc = create_timezone_from_delta (0 , 0 , 0 , 0 );
6794+ if (st -> utc == NULL ) {
6795+ return -1 ;
6796+ }
6797+
6798+ /* Init Unix epoch */
6799+ st -> epoch = new_datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 , st -> utc , 0 );
6800+ if (st -> epoch == NULL ) {
6801+ return -1 ;
6802+ }
6803+ return 0 ;
6804+ }
6805+
67446806static int
67456807_datetime_exec (PyObject * module )
67466808{
@@ -6762,23 +6824,23 @@ _datetime_exec(PyObject *module)
67626824
67636825 for (size_t i = 0 ; i < Py_ARRAY_LENGTH (types ); i ++ ) {
67646826 if (PyModule_AddType (module , types [i ]) < 0 ) {
6765- return -1 ;
6827+ goto error ;
67666828 }
67676829 }
67686830
67696831 if (PyType_Ready (& PyDateTime_IsoCalendarDateType ) < 0 ) {
6770- return -1 ;
6832+ goto error ;
67716833 }
67726834
67736835#define DATETIME_ADD_MACRO (dict , c , value_expr ) \
67746836 do { \
67756837 PyObject *value = (value_expr); \
67766838 if (value == NULL) { \
6777- return -1; \
6839+ goto error; \
67786840 } \
67796841 if (PyDict_SetItemString(dict, c, value) < 0) { \
67806842 Py_DECREF(value); \
6781- return -1; \
6843+ goto error; \
67826844 } \
67836845 Py_DECREF(value); \
67846846 } while(0)
@@ -6810,73 +6872,53 @@ _datetime_exec(PyObject *module)
68106872 999999 , Py_None , 0 ));
68116873 DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
68126874
6813- /* timezone values */
6814- d = PyDateTime_TimeZoneType .tp_dict ;
6815- PyObject * delta = new_delta (0 , 0 , 0 , 0 );
6816- if (delta == NULL ) {
6817- return -1 ;
6818- }
6819-
68206875 datetime_state * st = STATIC_STATE ();
6821- st -> utc = create_timezone (delta , NULL );
6822- Py_DECREF (delta );
6823- if (st -> utc == NULL ) {
6876+ if (init_state (st ) < 0 ) {
68246877 goto error ;
68256878 }
6879+
6880+ /* timezone values */
6881+ d = PyDateTime_TimeZoneType .tp_dict ;
68266882 if (PyDict_SetItemString (d , "utc" , st -> utc ) < 0 ) {
68276883 goto error ;
68286884 }
68296885
68306886 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
68316887 * compatibility, even though the constructor will accept a wider range of
68326888 * values. This may change in the future.*/
6833- delta = new_delta (-1 , 60 , 0 , 1 ); /* -23:59 */
6834- if (delta == NULL ) {
6835- goto error ;
6836- }
6837-
6838- PyObject * x = create_timezone (delta , NULL );
6839- Py_DECREF (delta );
6840- DATETIME_ADD_MACRO (d , "min" , x );
68416889
6842- delta = new_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ); /* +23:59 */
6843- if (delta == NULL ) {
6844- goto error ;
6845- }
6890+ /* -23:59 */
6891+ PyObject * min = create_timezone_from_delta (-1 , 60 , 0 , 1 );
6892+ DATETIME_ADD_MACRO (d , "min" , min );
68466893
6847- x = create_timezone ( delta , NULL );
6848- Py_DECREF ( delta );
6849- DATETIME_ADD_MACRO (d , "max" , x );
6894+ /* 23:59 */
6895+ PyObject * max = create_timezone_from_delta ( 0 , ( 23 * 60 + 59 ) * 60 , 0 , 0 );
6896+ DATETIME_ADD_MACRO (d , "max" , max );
68506897
6851- /* Epoch */
6852- st -> epoch = new_datetime (1970 , 1 , 1 , 0 , 0 , 0 , 0 , st -> utc , 0 );
6853- if (st -> epoch == NULL ) {
6854- goto error ;
6855- }
6856-
6857- /* module initialization */
6898+ /* Add module level attributes */
68586899 if (PyModule_AddIntMacro (module , MINYEAR ) < 0 ) {
68596900 goto error ;
68606901 }
68616902 if (PyModule_AddIntMacro (module , MAXYEAR ) < 0 ) {
68626903 goto error ;
68636904 }
6905+ if (PyModule_AddObjectRef (module , "UTC" , st -> utc ) < 0 ) {
6906+ goto error ;
6907+ }
68646908
6909+ /* At last, set up and add the encapsulated C API */
68656910 PyDateTime_CAPI * capi = get_datetime_capi ();
68666911 if (capi == NULL ) {
68676912 goto error ;
68686913 }
6869- x = PyCapsule_New (capi , PyDateTime_CAPSULE_NAME , datetime_destructor );
6870- if (x == NULL ) {
6914+ PyObject * capsule = PyCapsule_New (capi , PyDateTime_CAPSULE_NAME ,
6915+ datetime_destructor );
6916+ if (capsule == NULL ) {
68716917 PyMem_Free (capi );
68726918 goto error ;
68736919 }
6874-
6875- if (PyModule_Add (module , "datetime_CAPI" , x ) < 0 ) {
6876- goto error ;
6877- }
6878-
6879- if (PyModule_AddObjectRef (module , "UTC" , st -> utc ) < 0 ) {
6920+ if (PyModule_Add (module , "datetime_CAPI" , capsule ) < 0 ) {
6921+ PyMem_Free (capi );
68806922 goto error ;
68816923 }
68826924
@@ -6898,45 +6940,13 @@ _datetime_exec(PyObject *module)
68986940 static_assert (DI100Y == 25 * DI4Y - 1 , "DI100Y" );
68996941 assert (DI100Y == days_before_year (100 + 1 ));
69006942
6901- st -> us_per_ms = PyLong_FromLong (1000 );
6902- if (st -> us_per_ms == NULL ) {
6903- goto error ;
6904- }
6905- st -> us_per_second = PyLong_FromLong (1000000 );
6906- if (st -> us_per_second == NULL ) {
6907- goto error ;
6908- }
6909- st -> us_per_minute = PyLong_FromLong (60000000 );
6910- if (st -> us_per_minute == NULL ) {
6911- goto error ;
6912- }
6913- st -> seconds_per_day = PyLong_FromLong (24 * 3600 );
6914- if (st -> seconds_per_day == NULL ) {
6915- goto error ;
6916- }
6917-
6918- /* The rest are too big for 32-bit ints, but even
6919- * us_per_week fits in 40 bits, so doubles should be exact.
6920- */
6921- st -> us_per_hour = PyLong_FromDouble (3600000000.0 );
6922- if (st -> us_per_hour == NULL ) {
6923- goto error ;
6924- }
6925- st -> us_per_day = PyLong_FromDouble (86400000000.0 );
6926- if (st -> us_per_day == NULL ) {
6927- goto error ;
6928- }
6929- st -> us_per_week = PyLong_FromDouble (604800000000.0 );
6930- if (st -> us_per_week == NULL ) {
6931- goto error ;
6932- }
6933-
69346943 return 0 ;
69356944
69366945error :
69376946 datetime_clear (module );
69386947 return -1 ;
69396948}
6949+ #undef DATETIME_ADD_MACRO
69406950
69416951static struct PyModuleDef datetimemodule = {
69426952 .m_base = PyModuleDef_HEAD_INIT ,
0 commit comments