14
14
#include "pycore_object.h" // _PyObject_Init()
15
15
#include "pycore_time.h" // _PyTime_ObjectToTime_t()
16
16
#include "pycore_unicodeobject.h" // _PyUnicode_Copy()
17
+ #include "pycore_initconfig.h" // _PyStatus_OK()
17
18
18
19
#include "datetime.h"
19
20
@@ -124,10 +125,9 @@ get_module_state(PyObject *module)
124
125
#define INTERP_KEY ((PyObject *)&_Py_ID(cached_datetime_module))
125
126
126
127
static PyObject *
127
- get_current_module (PyInterpreterState * interp , int * p_reloading )
128
+ get_current_module (PyInterpreterState * interp )
128
129
{
129
130
PyObject * mod = NULL ;
130
- int reloading = 0 ;
131
131
132
132
PyObject * dict = PyInterpreterState_GetDict (interp );
133
133
if (dict == NULL ) {
@@ -138,7 +138,6 @@ get_current_module(PyInterpreterState *interp, int *p_reloading)
138
138
goto error ;
139
139
}
140
140
if (ref != NULL ) {
141
- reloading = 1 ;
142
141
if (ref != Py_None ) {
143
142
(void )PyWeakref_GetRef (ref , & mod );
144
143
if (mod == Py_None ) {
@@ -147,9 +146,6 @@ get_current_module(PyInterpreterState *interp, int *p_reloading)
147
146
Py_DECREF (ref );
148
147
}
149
148
}
150
- if (p_reloading != NULL ) {
151
- * p_reloading = reloading ;
152
- }
153
149
return mod ;
154
150
155
151
error :
@@ -163,7 +159,7 @@ static datetime_state *
163
159
_get_current_state (PyObject * * p_mod )
164
160
{
165
161
PyInterpreterState * interp = PyInterpreterState_Get ();
166
- PyObject * mod = get_current_module (interp , NULL );
162
+ PyObject * mod = get_current_module (interp );
167
163
if (mod == NULL ) {
168
164
assert (!PyErr_Occurred ());
169
165
if (PyErr_Occurred ()) {
@@ -4476,7 +4472,7 @@ static PyTypeObject PyDateTime_TimeZoneType = {
4476
4472
timezone_methods , /* tp_methods */
4477
4473
0 , /* tp_members */
4478
4474
0 , /* tp_getset */
4479
- 0 , /* tp_base; filled in PyInit__datetime */
4475
+ & PyDateTime_TZInfoType , /* tp_base */
4480
4476
0 , /* tp_dict */
4481
4477
0 , /* tp_descr_get */
4482
4478
0 , /* tp_descr_set */
@@ -7131,8 +7127,7 @@ static PyTypeObject PyDateTime_DateTimeType = {
7131
7127
datetime_methods , /* tp_methods */
7132
7128
0 , /* tp_members */
7133
7129
datetime_getset , /* tp_getset */
7134
- 0 , /* tp_base; filled in
7135
- PyInit__datetime */
7130
+ & PyDateTime_DateType , /* tp_base */
7136
7131
0 , /* tp_dict */
7137
7132
0 , /* tp_descr_get */
7138
7133
0 , /* tp_descr_set */
@@ -7313,29 +7308,82 @@ clear_state(datetime_state *st)
7313
7308
}
7314
7309
7315
7310
7316
- static int
7317
- init_static_types (PyInterpreterState * interp , int reloading )
7311
+ PyStatus
7312
+ _PyDateTime_InitTypes (PyInterpreterState * interp )
7318
7313
{
7319
- if (reloading ) {
7320
- return 0 ;
7321
- }
7322
-
7323
- // `&...` is not a constant expression according to a strict reading
7324
- // of C standards. Fill tp_base at run-time rather than statically.
7325
- // See https://bugs.python.org/issue40777
7326
- PyDateTime_TimeZoneType .tp_base = & PyDateTime_TZInfoType ;
7327
- PyDateTime_DateTimeType .tp_base = & PyDateTime_DateType ;
7328
-
7329
7314
/* Bases classes must be initialized before subclasses,
7330
7315
* so capi_types must have the types in the appropriate order. */
7331
7316
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
7332
7317
PyTypeObject * type = capi_types [i ];
7333
7318
if (_PyStaticType_InitForExtension (interp , type ) < 0 ) {
7334
- return -1 ;
7319
+ return _PyStatus_ERR ( "could not initialize static types" ) ;
7335
7320
}
7336
7321
}
7337
7322
7338
- return 0 ;
7323
+ #define DATETIME_ADD_MACRO (dict , c , value_expr ) \
7324
+ do { \
7325
+ assert(!PyErr_Occurred()); \
7326
+ PyObject *value = (value_expr); \
7327
+ if (value == NULL) { \
7328
+ goto error; \
7329
+ } \
7330
+ if (PyDict_SetItemString(dict, c, value) < 0) { \
7331
+ Py_DECREF(value); \
7332
+ goto error; \
7333
+ } \
7334
+ Py_DECREF(value); \
7335
+ } while(0)
7336
+
7337
+ /* timedelta values */
7338
+ PyObject * d = _PyType_GetDict (& PyDateTime_DeltaType );
7339
+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7340
+ DATETIME_ADD_MACRO (d , "min" , new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 ));
7341
+ DATETIME_ADD_MACRO (d , "max" ,
7342
+ new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 ));
7343
+
7344
+ /* date values */
7345
+ d = _PyType_GetDict (& PyDateTime_DateType );
7346
+ DATETIME_ADD_MACRO (d , "min" , new_date (1 , 1 , 1 ));
7347
+ DATETIME_ADD_MACRO (d , "max" , new_date (MAXYEAR , 12 , 31 ));
7348
+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (1 , 0 , 0 , 0 ));
7349
+
7350
+ /* time values */
7351
+ d = _PyType_GetDict (& PyDateTime_TimeType );
7352
+ DATETIME_ADD_MACRO (d , "min" , new_time (0 , 0 , 0 , 0 , Py_None , 0 ));
7353
+ DATETIME_ADD_MACRO (d , "max" , new_time (23 , 59 , 59 , 999999 , Py_None , 0 ));
7354
+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7355
+
7356
+ /* datetime values */
7357
+ d = _PyType_GetDict (& PyDateTime_DateTimeType );
7358
+ DATETIME_ADD_MACRO (d , "min" ,
7359
+ new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 ));
7360
+ DATETIME_ADD_MACRO (d , "max" , new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 ,
7361
+ 999999 , Py_None , 0 ));
7362
+ DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7363
+
7364
+ /* timezone values */
7365
+ d = _PyType_GetDict (& PyDateTime_TimeZoneType );
7366
+ if (PyDict_SetItemString (d , "utc" , (PyObject * )& utc_timezone ) < 0 ) {
7367
+ goto error ;
7368
+ }
7369
+
7370
+ /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7371
+ * compatibility, even though the constructor will accept a wider range of
7372
+ * values. This may change in the future.*/
7373
+
7374
+ /* -23:59 */
7375
+ DATETIME_ADD_MACRO (d , "min" , create_timezone_from_delta (-1 , 60 , 0 , 1 ));
7376
+
7377
+ /* +23:59 */
7378
+ DATETIME_ADD_MACRO (
7379
+ d , "max" , create_timezone_from_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ));
7380
+
7381
+ #undef DATETIME_ADD_MACRO
7382
+
7383
+ return _PyStatus_OK ();
7384
+
7385
+ error :
7386
+ return _PyStatus_NO_MEMORY ();
7339
7387
}
7340
7388
7341
7389
@@ -7353,20 +7401,15 @@ _datetime_exec(PyObject *module)
7353
7401
{
7354
7402
int rc = -1 ;
7355
7403
datetime_state * st = get_module_state (module );
7356
- int reloading = 0 ;
7357
7404
7358
7405
PyInterpreterState * interp = PyInterpreterState_Get ();
7359
- PyObject * old_module = get_current_module (interp , & reloading );
7406
+ PyObject * old_module = get_current_module (interp );
7360
7407
if (PyErr_Occurred ()) {
7361
7408
assert (old_module == NULL );
7362
7409
goto error ;
7363
7410
}
7364
7411
/* We actually set the "current" module right before a successful return. */
7365
7412
7366
- if (init_static_types (interp , reloading ) < 0 ) {
7367
- goto error ;
7368
- }
7369
-
7370
7413
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
7371
7414
PyTypeObject * type = capi_types [i ];
7372
7415
const char * name = _PyType_Name (type );
@@ -7380,68 +7423,6 @@ _datetime_exec(PyObject *module)
7380
7423
goto error ;
7381
7424
}
7382
7425
7383
- #define DATETIME_ADD_MACRO (dict , c , value_expr ) \
7384
- do { \
7385
- assert(!PyErr_Occurred()); \
7386
- PyObject *value = (value_expr); \
7387
- if (value == NULL) { \
7388
- goto error; \
7389
- } \
7390
- if (PyDict_SetItemString(dict, c, value) < 0) { \
7391
- Py_DECREF(value); \
7392
- goto error; \
7393
- } \
7394
- Py_DECREF(value); \
7395
- } while(0)
7396
-
7397
- if (!reloading ) {
7398
- /* timedelta values */
7399
- PyObject * d = _PyType_GetDict (& PyDateTime_DeltaType );
7400
- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7401
- DATETIME_ADD_MACRO (d , "min" , new_delta (- MAX_DELTA_DAYS , 0 , 0 , 0 ));
7402
- DATETIME_ADD_MACRO (d , "max" ,
7403
- new_delta (MAX_DELTA_DAYS , 24 * 3600 - 1 , 1000000 - 1 , 0 ));
7404
-
7405
- /* date values */
7406
- d = _PyType_GetDict (& PyDateTime_DateType );
7407
- DATETIME_ADD_MACRO (d , "min" , new_date (1 , 1 , 1 ));
7408
- DATETIME_ADD_MACRO (d , "max" , new_date (MAXYEAR , 12 , 31 ));
7409
- DATETIME_ADD_MACRO (d , "resolution" , new_delta (1 , 0 , 0 , 0 ));
7410
-
7411
- /* time values */
7412
- d = _PyType_GetDict (& PyDateTime_TimeType );
7413
- DATETIME_ADD_MACRO (d , "min" , new_time (0 , 0 , 0 , 0 , Py_None , 0 ));
7414
- DATETIME_ADD_MACRO (d , "max" , new_time (23 , 59 , 59 , 999999 , Py_None , 0 ));
7415
- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7416
-
7417
- /* datetime values */
7418
- d = _PyType_GetDict (& PyDateTime_DateTimeType );
7419
- DATETIME_ADD_MACRO (d , "min" ,
7420
- new_datetime (1 , 1 , 1 , 0 , 0 , 0 , 0 , Py_None , 0 ));
7421
- DATETIME_ADD_MACRO (d , "max" , new_datetime (MAXYEAR , 12 , 31 , 23 , 59 , 59 ,
7422
- 999999 , Py_None , 0 ));
7423
- DATETIME_ADD_MACRO (d , "resolution" , new_delta (0 , 0 , 1 , 0 ));
7424
-
7425
- /* timezone values */
7426
- d = _PyType_GetDict (& PyDateTime_TimeZoneType );
7427
- if (PyDict_SetItemString (d , "utc" , (PyObject * )& utc_timezone ) < 0 ) {
7428
- goto error ;
7429
- }
7430
-
7431
- /* bpo-37642: These attributes are rounded to the nearest minute for backwards
7432
- * compatibility, even though the constructor will accept a wider range of
7433
- * values. This may change in the future.*/
7434
-
7435
- /* -23:59 */
7436
- DATETIME_ADD_MACRO (d , "min" , create_timezone_from_delta (-1 , 60 , 0 , 1 ));
7437
-
7438
- /* +23:59 */
7439
- DATETIME_ADD_MACRO (
7440
- d , "max" , create_timezone_from_delta (0 , (23 * 60 + 59 ) * 60 , 0 , 0 ));
7441
- }
7442
-
7443
- #undef DATETIME_ADD_MACRO
7444
-
7445
7426
/* Add module level attributes */
7446
7427
if (PyModule_AddIntMacro (module , MINYEAR ) < 0 ) {
7447
7428
goto error ;
0 commit comments