1414#include "pycore_object.h" // _PyObject_Init()
1515#include "pycore_time.h" // _PyTime_ObjectToTime_t()
1616#include "pycore_unicodeobject.h" // _PyUnicode_Copy()
17+ #include "pycore_initconfig.h" // _PyStatus_OK()
1718
1819#include "datetime.h"
1920
@@ -124,10 +125,9 @@ get_module_state(PyObject *module)
124125#define INTERP_KEY ((PyObject *)&_Py_ID(cached_datetime_module))
125126
126127static PyObject *
127- get_current_module (PyInterpreterState * interp , int * p_reloading )
128+ get_current_module (PyInterpreterState * interp )
128129{
129130 PyObject * mod = NULL ;
130- int reloading = 0 ;
131131
132132 PyObject * dict = PyInterpreterState_GetDict (interp );
133133 if (dict == NULL ) {
@@ -138,7 +138,6 @@ get_current_module(PyInterpreterState *interp, int *p_reloading)
138138 goto error ;
139139 }
140140 if (ref != NULL ) {
141- reloading = 1 ;
142141 if (ref != Py_None ) {
143142 (void )PyWeakref_GetRef (ref , & mod );
144143 if (mod == Py_None ) {
@@ -147,9 +146,6 @@ get_current_module(PyInterpreterState *interp, int *p_reloading)
147146 Py_DECREF (ref );
148147 }
149148 }
150- if (p_reloading != NULL ) {
151- * p_reloading = reloading ;
152- }
153149 return mod ;
154150
155151error :
@@ -163,7 +159,7 @@ static datetime_state *
163159_get_current_state (PyObject * * p_mod )
164160{
165161 PyInterpreterState * interp = PyInterpreterState_Get ();
166- PyObject * mod = get_current_module (interp , NULL );
162+ PyObject * mod = get_current_module (interp );
167163 if (mod == NULL ) {
168164 assert (!PyErr_Occurred ());
169165 if (PyErr_Occurred ()) {
@@ -4482,7 +4478,7 @@ static PyTypeObject PyDateTime_TimeZoneType = {
44824478 timezone_methods , /* tp_methods */
44834479 0 , /* tp_members */
44844480 0 , /* tp_getset */
4485- 0 , /* tp_base; filled in PyInit__datetime */
4481+ & PyDateTime_TZInfoType , /* tp_base */
44864482 0 , /* tp_dict */
44874483 0 , /* tp_descr_get */
44884484 0 , /* tp_descr_set */
@@ -7147,8 +7143,7 @@ static PyTypeObject PyDateTime_DateTimeType = {
71477143 datetime_methods , /* tp_methods */
71487144 0 , /* tp_members */
71497145 datetime_getset , /* tp_getset */
7150- 0 , /* tp_base; filled in
7151- PyInit__datetime */
7146+ & PyDateTime_DateType , /* tp_base */
71527147 0 , /* tp_dict */
71537148 0 , /* tp_descr_get */
71547149 0 , /* tp_descr_set */
@@ -7329,29 +7324,82 @@ clear_state(datetime_state *st)
73297324}
73307325
73317326
7332- static int
7333- init_static_types (PyInterpreterState * interp , int reloading )
7327+ PyStatus
7328+ _PyDateTime_InitTypes (PyInterpreterState * interp )
73347329{
7335- if (reloading ) {
7336- return 0 ;
7337- }
7338-
7339- // `&...` is not a constant expression according to a strict reading
7340- // of C standards. Fill tp_base at run-time rather than statically.
7341- // See https://bugs.python.org/issue40777
7342- PyDateTime_TimeZoneType .tp_base = & PyDateTime_TZInfoType ;
7343- PyDateTime_DateTimeType .tp_base = & PyDateTime_DateType ;
7344-
73457330 /* Bases classes must be initialized before subclasses,
73467331 * so capi_types must have the types in the appropriate order. */
73477332 for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
73487333 PyTypeObject * type = capi_types [i ];
73497334 if (_PyStaticType_InitForExtension (interp , type ) < 0 ) {
7350- return -1 ;
7335+ return _PyStatus_ERR ( "could not initialize static types" ) ;
73517336 }
73527337 }
73537338
7354- return 0 ;
7339+ #define DATETIME_ADD_MACRO (dict , c , value_expr ) \
7340+ do { \
7341+ assert(!PyErr_Occurred()); \
7342+ PyObject *value = (value_expr); \
7343+ if (value == NULL) { \
7344+ goto error; \
7345+ } \
7346+ if (PyDict_SetItemString(dict, c, value) < 0) { \
7347+ Py_DECREF(value); \
7348+ goto error; \
7349+ } \
7350+ Py_DECREF(value); \
7351+ } while(0)
7352+
7353+ /* timedelta values */
7354+ PyObject * d = _PyType_GetDict (& PyDateTime_DeltaType );
7355+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7356+ DATETIME_ADD_MACRO (d , "min" , new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 ));
7357+ DATETIME_ADD_MACRO (d , "max" ,
7358+ new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 ));
7359+
7360+ /* date values */
7361+ d = _PyType_GetDict (& PyDateTime_DateType );
7362+ DATETIME_ADD_MACRO (d , "min" , new_date (1 , 1 , 1 ));
7363+ DATETIME_ADD_MACRO (d , "max" , new_date (MAXYEAR , 12 , 31 ));
7364+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (1 , 0 , 0 , 0 ));
7365+
7366+ /* time values */
7367+ d = _PyType_GetDict (& PyDateTime_TimeType );
7368+ DATETIME_ADD_MACRO (d , "min" , new_time (0 , 0 , 0 , 0 , Py_None , 0 ));
7369+ DATETIME_ADD_MACRO (d , "max" , new_time (23 , 59 , 59 , 999999 , Py_None , 0 ));
7370+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7371+
7372+ /* datetime values */
7373+ d = _PyType_GetDict (& PyDateTime_DateTimeType );
7374+ DATETIME_ADD_MACRO (d , "min" ,
7375+ new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 ));
7376+ DATETIME_ADD_MACRO (d , "max" , new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 ,
7377+ 999999 , Py_None , 0 ));
7378+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7379+
7380+ /* timezone values */
7381+ d = _PyType_GetDict (& PyDateTime_TimeZoneType );
7382+ if (PyDict_SetItemString (d , "utc" , (PyObject * )& utc_timezone ) < 0 ) {
7383+ goto error ;
7384+ }
7385+
7386+ /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7387+ * compatibility, even though the constructor will accept a wider range of
7388+ * values. This may change in the future.*/
7389+
7390+ /* -23:59 */
7391+ DATETIME_ADD_MACRO (d , "min" , create_timezone_from_delta (-1 , 60 , 0 , 1 ));
7392+
7393+ /* +23:59 */
7394+ DATETIME_ADD_MACRO (
7395+ d , "max" , create_timezone_from_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ));
7396+
7397+ #undef DATETIME_ADD_MACRO
7398+
7399+ return _PyStatus_OK ();
7400+
7401+ error :
7402+ return _PyStatus_NO_MEMORY ();
73557403}
73567404
73577405
@@ -7369,20 +7417,15 @@ _datetime_exec(PyObject *module)
73697417{
73707418 int rc = -1 ;
73717419 datetime_state * st = get_module_state (module );
7372- int reloading = 0 ;
73737420
73747421 PyInterpreterState * interp = PyInterpreterState_Get ();
7375- PyObject * old_module = get_current_module (interp , & reloading );
7422+ PyObject * old_module = get_current_module (interp );
73767423 if (PyErr_Occurred ()) {
73777424 assert (old_module == NULL );
73787425 goto error ;
73797426 }
73807427 /* We actually set the "current" module right before a successful return. */
73817428
7382- if (init_static_types (interp , reloading ) < 0 ) {
7383- goto error ;
7384- }
7385-
73867429 for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
73877430 PyTypeObject * type = capi_types [i ];
73887431 const char * name = _PyType_Name (type );
@@ -7396,68 +7439,6 @@ _datetime_exec(PyObject *module)
73967439 goto error ;
73977440 }
73987441
7399- #define DATETIME_ADD_MACRO (dict , c , value_expr ) \
7400- do { \
7401- assert(!PyErr_Occurred()); \
7402- PyObject *value = (value_expr); \
7403- if (value == NULL) { \
7404- goto error; \
7405- } \
7406- if (PyDict_SetItemString(dict, c, value) < 0) { \
7407- Py_DECREF(value); \
7408- goto error; \
7409- } \
7410- Py_DECREF(value); \
7411- } while(0)
7412-
7413- if (!reloading ) {
7414- /* timedelta values */
7415- PyObject * d = _PyType_GetDict (& PyDateTime_DeltaType );
7416- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7417- DATETIME_ADD_MACRO (d , "min" , new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 ));
7418- DATETIME_ADD_MACRO (d , "max" ,
7419- new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 ));
7420-
7421- /* date values */
7422- d = _PyType_GetDict (& PyDateTime_DateType );
7423- DATETIME_ADD_MACRO (d , "min" , new_date (1 , 1 , 1 ));
7424- DATETIME_ADD_MACRO (d , "max" , new_date (MAXYEAR , 12 , 31 ));
7425- DATETIME_ADD_MACRO (d , "resolution" , new_delta (1 , 0 , 0 , 0 ));
7426-
7427- /* time values */
7428- d = _PyType_GetDict (& PyDateTime_TimeType );
7429- DATETIME_ADD_MACRO (d , "min" , new_time (0 , 0 , 0 , 0 , Py_None , 0 ));
7430- DATETIME_ADD_MACRO (d , "max" , new_time (23 , 59 , 59 , 999999 , Py_None , 0 ));
7431- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7432-
7433- /* datetime values */
7434- d = _PyType_GetDict (& PyDateTime_DateTimeType );
7435- DATETIME_ADD_MACRO (d , "min" ,
7436- new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 ));
7437- DATETIME_ADD_MACRO (d , "max" , new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 ,
7438- 999999 , Py_None , 0 ));
7439- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7440-
7441- /* timezone values */
7442- d = _PyType_GetDict (& PyDateTime_TimeZoneType );
7443- if (PyDict_SetItemString (d , "utc" , (PyObject * )& utc_timezone ) < 0 ) {
7444- goto error ;
7445- }
7446-
7447- /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7448- * compatibility, even though the constructor will accept a wider range of
7449- * values. This may change in the future.*/
7450-
7451- /* -23:59 */
7452- DATETIME_ADD_MACRO (d , "min" , create_timezone_from_delta (-1 , 60 , 0 , 1 ));
7453-
7454- /* +23:59 */
7455- DATETIME_ADD_MACRO (
7456- d , "max" , create_timezone_from_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ));
7457- }
7458-
7459- #undef DATETIME_ADD_MACRO
7460-
74617442 /* Add module level attributes */
74627443 if (PyModule_AddIntMacro (module , MINYEAR ) < 0 ) {
74637444 goto error ;
0 commit comments