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 ()) {
@@ -4482,7 +4478,7 @@ static PyTypeObject PyDateTime_TimeZoneType = {
4482
4478
timezone_methods , /* tp_methods */
4483
4479
0 , /* tp_members */
4484
4480
0 , /* tp_getset */
4485
- 0 , /* tp_base; filled in PyInit__datetime */
4481
+ & PyDateTime_TZInfoType , /* tp_base */
4486
4482
0 , /* tp_dict */
4487
4483
0 , /* tp_descr_get */
4488
4484
0 , /* tp_descr_set */
@@ -7147,8 +7143,7 @@ static PyTypeObject PyDateTime_DateTimeType = {
7147
7143
datetime_methods , /* tp_methods */
7148
7144
0 , /* tp_members */
7149
7145
datetime_getset , /* tp_getset */
7150
- 0 , /* tp_base; filled in
7151
- PyInit__datetime */
7146
+ & PyDateTime_DateType , /* tp_base */
7152
7147
0 , /* tp_dict */
7153
7148
0 , /* tp_descr_get */
7154
7149
0 , /* tp_descr_set */
@@ -7329,29 +7324,82 @@ clear_state(datetime_state *st)
7329
7324
}
7330
7325
7331
7326
7332
- static int
7333
- init_static_types (PyInterpreterState * interp , int reloading )
7327
+ PyStatus
7328
+ _PyDateTime_InitTypes (PyInterpreterState * interp )
7334
7329
{
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
-
7345
7330
/* Bases classes must be initialized before subclasses,
7346
7331
* so capi_types must have the types in the appropriate order. */
7347
7332
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
7348
7333
PyTypeObject * type = capi_types [i ];
7349
7334
if (_PyStaticType_InitForExtension (interp , type ) < 0 ) {
7350
- return -1 ;
7335
+ return _PyStatus_ERR ( "could not initialize static types" ) ;
7351
7336
}
7352
7337
}
7353
7338
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 ();
7355
7403
}
7356
7404
7357
7405
@@ -7369,20 +7417,15 @@ _datetime_exec(PyObject *module)
7369
7417
{
7370
7418
int rc = -1 ;
7371
7419
datetime_state * st = get_module_state (module );
7372
- int reloading = 0 ;
7373
7420
7374
7421
PyInterpreterState * interp = PyInterpreterState_Get ();
7375
- PyObject * old_module = get_current_module (interp , & reloading );
7422
+ PyObject * old_module = get_current_module (interp );
7376
7423
if (PyErr_Occurred ()) {
7377
7424
assert (old_module == NULL );
7378
7425
goto error ;
7379
7426
}
7380
7427
/* We actually set the "current" module right before a successful return. */
7381
7428
7382
- if (init_static_types (interp , reloading ) < 0 ) {
7383
- goto error ;
7384
- }
7385
-
7386
7429
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (capi_types ); i ++ ) {
7387
7430
PyTypeObject * type = capi_types [i ];
7388
7431
const char * name = _PyType_Name (type );
@@ -7396,68 +7439,6 @@ _datetime_exec(PyObject *module)
7396
7439
goto error ;
7397
7440
}
7398
7441
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
-
7461
7442
/* Add module level attributes */
7462
7443
if (PyModule_AddIntMacro (module , MINYEAR ) < 0 ) {
7463
7444
goto error ;
0 commit comments