8000 bpo-1635741: Port _datetime module to multiphase initialization (PEP … · python/cpython@9a42428 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9a42428

Browse files
author
Paulo Henrique Silva
committed
bpo-1635741: Port _datetime module to multiphase initialization (PEP 489)
1 parent 5c3cda0 commit 9a42428

File tree

2 files changed

+82
-57
lines changed

2 files changed

+82
-57
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Port _datetime module to multiphase initialization (:pep:`489`). Patch by
2+
Paulo Henrique Silva.

Modules/_datetimemodule.c

Lines changed: 80 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6335,7 +6335,7 @@ static PyTypeObject PyDateTime_DateTimeType = {
63356335
* Module methods and initialization.
63366336
*/
63376337

6338-
static PyMethodDef module_methods[] = {
6338+
static PyMethodDef datetimemodule_methods[] = {
63396339
{NULL, NULL}
63406340
};
63416341

@@ -6360,32 +6360,13 @@ static PyDateTime_CAPI CAPI = {
63606360
new_time_ex2
63616361
};
63626362

6363-
6364-
6365-
static struct PyModuleDef datetimemodule = {
6366-
PyModuleDef_HEAD_INIT,
6367-
"_datetime",
6368-
"Fast implementation of the datetime type.",
6369-
-1,
6370-
module_methods,
6371-
NULL,
6372-
NULL,
6373-
NULL,
6374-
NULL
6375-
};
6376-
6377-
PyMODINIT_FUNC
6378-
PyInit__datetime(void)
6363+
static int
6364+
datetimemodule_exec(PyObject *module)
63796365
{
6380-
PyObject *m; /* a module object */
63816366
PyObject *d; /* its dict */
63826367
PyObject *x;
63836368
PyObject *delta;
63846369

6385-
m = PyModule_Create(&datetimemodule);
6386-
if (m == NULL)
6387-
return NULL;
6388-
63896370
PyTypeObject *types[] = {
63906371
&PyDateTime_DateType,
63916372
&PyDateTime_DateTimeType,
@@ -6396,8 +6377,8 @@ PyInit__datetime(void)
63966377
};
63976378

63986379
for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
6399-
if (PyModule_AddType(m, types[i]) < 0) {
6400-
return NULL;
6380+
if (PyModule_AddType(module, types[i]) < 0) {
6381+
return -1;
64016382
}
64026383
}
64036384

@@ -6406,83 +6387,83 @@ PyInit__datetime(void)
64066387

64076388
x = new_delta(0, 0, 1, 0);
64086389
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6409-
return NULL;
6390+
return -1;
64106391
Py_DECREF(x);
64116392

64126393
x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
64136394
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6414-
return NULL;
6395+
return -1;
64156396
Py_DECREF(x);
64166397

64176398
x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
< A3E2 /td>
64186399
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6419-
return NULL;
6400+
return -1;
64206401
Py_DECREF(x);
64216402

64226403
/* date values */
64236404
d = PyDateTime_DateType.tp_dict;
64246405

64256406
x = new_date(1, 1, 1);
64266407
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6427-
return NULL;
6408+
return -1;
64286409
Py_DECREF(x);
64296410

64306411
x = new_date(MAXYEAR, 12, 31);
64316412
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6432-
return NULL;
6413+
return -1;
64336414
Py_DECREF(x);
64346415

64356416
x = new_delta(1, 0, 0, 0);
64366417
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6437-
return NULL;
6418+
return -1;
64386419
Py_DECREF(x);
64396420

64406421
/* time values */
64416422
d = PyDateTime_TimeType.tp_dict;
64426423

64436424
x = new_time(0, 0, 0, 0, Py_None, 0);
64446425
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6445-
return NULL;
6426+
return -1;
64466427
Py_DECREF(x);
64476428

64486429
x = new_time(23, 59, 59, 999999, Py_None, 0);
64496430
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6450-
return NULL;
6431+
return -1;
64516432
Py_DECREF(x);
64526433

64536434
x = new_delta(0, 0, 1, 0);
64546435
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6455-
return NULL;
6436+
return -1;
64566437
Py_DECREF(x);
64576438

64586439
/* datetime values */
64596440
d = PyDateTime_DateTimeType.tp_dict;
64606441

64616442
x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
64626443
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6463-
return NULL;
6444+
return -1;
64646445
Py_DECREF(x);
64656446

64666447
x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
64676448
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6468-
return NULL;
6449+
return -1;
64696450
Py_DECREF(x);
64706451

64716452
x = new_delta(0, 0, 1, 0);
64726453
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6473-
return NULL;
6454+
return -1;
64746455
Py_DECREF(x);
64756456

64766457
/* timezone values */
64776458
d = PyDateTime_TimeZoneType.tp_dict;
64786459

64796460
delta = new_delta(0, 0, 0, 0);
64806461
if (delta == NULL)
6481-
return NULL;
6462+
return -1;
64826463
x = create_timezone(delta, NULL);
64836464
Py_DECREF(delta);
64846465
if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6485-
return NULL;
6466+
return -1;
64866467
PyDateTime_TimeZone_UTC = x;
64876468
CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
64886469

@@ -6491,36 +6472,36 @@ PyInit__datetime(void)
64916472
* values. This may change in the future.*/
64926473
delta = new_delta(-1, 60, 0, 1); /* -23:59 */
64936474
if (delta == NULL)
6494-
return NULL;
6475+
return -1;
64956476
x = create_timezone(delta, NULL);
64966477
Py_DECREF(delta);
64976478
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6498-
return NULL;
6479+
return -1;
64996480
Py_DECREF(x);
65006481

65016482
delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
65026483
if (delta == NULL)
6503-
return NULL;
6484+
return -1;
65046485
x = create_timezone(delta, NULL);
65056486
Py_DECREF(delta);
65066487
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6507-
return NULL;
6488+
return -1;
65086489
Py_DECREF(x);
65096490

65106491
/* Epoch */
65116492
PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
65126493
PyDateTime_TimeZone_UTC, 0);
65136494
if (PyDateTime_Epoch == NULL)
6514-
return NULL;
6495+
return -1;
65156496

65166497
/* module initialization */
6517-
PyModule_AddIntMacro(m, MINYEAR);
6518-
PyModule_AddIntMacro(m, MAXYEAR);
6498+
PyModule_AddIntMacro(module, MINYEAR);
6499+
PyModule_AddIntMacro(module, MAXYEAR);
65196500

65206501
x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
65216502
if (x == NULL)
6522-
return NULL;
6523-
PyModule_AddObject(m, "datetime_CAPI", x);
6503+
return -1;
6504+
PyModule_AddObject(module, "datetime_CAPI", x);
65246505

65256506
/* A 4-year cycle has an extra leap day over what we'd get from
65266507
* pasting together 4 single years.
@@ -6540,23 +6521,65 @@ PyInit__datetime(void)
65406521
Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
65416522
assert(DI100Y == days_before_year(100+1));
65426523

6543-
us_per_ms = PyLong_FromLong(1000);
6544-
us_per_second = PyLong_FromLong(1000000);
6545-
us_per_minute = PyLong_FromLong(60000000);
6546-
seconds_per_day = PyLong_FromLong(24 * 3600);
6524+
if (!us_per_ms) {
6525+
us_per_ms = PyLong_FromLong(1000);
6526+
}
6527+
if (!us_per_second) {
6528+
us_per_second = PyLong_FromLong(1000000);
6529+
}
6530+
if (!us_per_minute) {
6531+
us_per_minute = PyLong_FromLong(60000000);
6532+
}
6533+
if (!seconds_per_day) {
6534+
seconds_per_day = PyLong_FromLong(24 * 3600);
6535+
}
65476536
if (us_per_ms == NULL || us_per_second == NULL ||
65486537
us_per_minute == NULL || seconds_per_day == NULL)
6549-
return NULL;
6538+
return -1;
65506539

65516540
/* The rest are too big for 32-bit ints, but even
65526541
* us_per_week fits in 40 bits, so doubles should be exact.
65536542
*/
6554-
us_per_hour = PyLong_FromDouble(3600000000.0);
6555-
us_per_day = PyLong_FromDouble(86400000000.0);
6556-
us_per_week = PyLong_FromDouble(604800000000.0);
6543+
if (!us_per_hour) {
6544+
us_per_hour = PyLong_FromDouble(3600000000.0);
6545+
}
6546+
if (!us_per_day) {
6547+
us_per_day = PyLong_FromDouble(86400000000.0);
6548+
}
6549+
if (!us_per_week) {
6550+
us_per_week = PyLong_FromDouble(604800000000.0);
6551+
}
65576552
if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6558-
return NULL;
6559-
return m;
6553+
return -1;
6554+
6555+
// Workaround to allow static PyTypeObjects to have they dict redefined.
6556+
// XXX: to be removed once _datetime moves to heap allocated PyTypeObjects.
6557+
PyType_ClearCache();
6558+
6559+
return 0;
6560+
}
6561+
6562+
static PyModuleDef_Slot datetimemodule_slots[] = {
6563+
{Py_mod_exec, datetimemodule_exec},
6564+
{0, NULL}
6565+
};
6566+
6567+
static struct PyModuleDef datetimemodule = {
6568+
PyModuleDef_HEAD_INIT,
6569+
"_datetime",
6570+
"Fast implementation of the datetime type.",
6571+
0,
6572+
datetimemodule_methods,
6573+
datetimemodule_slots,
6574+
NULL,
6575+
NULL,
6576+
NULL
6577+
};
6578+
6579+
PyMODINIT_FUNC
6580+
PyInit__datetime(void)
6581+
{
6582+
return PyModuleDef_Init(&datetimemodule);
65606583
}
65616584

65626585
/* ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)
0