Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5a037b7

Browse filesBrowse files
[3.13] gh-117398: Convert datetime.IsoCalendarDate To A Heap Type (gh-119637) (gh-119695)
This is the only static type in the module that we will not keep static. (cherry picked from commit 548a11d) (cherry-picked from commit 34f9b3e) Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com> Co-authored by: Kirill Podoprigora <kirill.bast9@mail.ru>
1 parent a7327b3 commit 5a037b7
Copy full SHA for 5a037b7

File tree

1 file changed

+63
-22
lines changed
Filter options

1 file changed

+63
-22
lines changed

‎Modules/_datetimemodule.c

Copy file name to clipboardExpand all lines: Modules/_datetimemodule.c
+63-22Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@
2626
#endif
2727

2828
typedef struct {
29+
/* Static types exposed by the datetime C-API. */
2930
PyTypeObject *date_type;
3031
PyTypeObject *datetime_type;
3132
PyTypeObject *delta_type;
32-
PyTypeObject *isocalendar_date_type;
3333
PyTypeObject *time_type;
3434
PyTypeObject *tzinfo_type;
35+
/* Exposed indirectly via TimeZone_UTC. */
3536
PyTypeObject *timezone_type;
3637

38+
/* Other module classes. */
39+
PyTypeObject *isocalendar_date_type;
40+
3741
/* Conversion factors. */
3842
PyObject *us_per_ms; // 1_000
3943
PyObject *us_per_second; // 1_000_000
@@ -3460,17 +3464,40 @@ static PyMethodDef iso_calendar_date_methods[] = {
34603464
{NULL, NULL},
34613465
};
34623466

3463-
static PyTypeObject PyDateTime_IsoCalendarDateType = {
3464-
PyVarObject_HEAD_INIT(NULL, 0)
3465-
.tp_name = "datetime.IsoCalendarDate",
3466-
.tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
3467-
.tp_repr = (reprfunc) iso_calendar_date_repr,
3468-
.tp_flags = Py_TPFLAGS_DEFAULT,
3469-
.tp_doc = iso_calendar_date__doc__,
3470-
.tp_methods = iso_calendar_date_methods,
3471-
.tp_getset = iso_calendar_date_getset,
3472-
// .tp_base = &PyTuple_Type, // filled in PyInit__datetime
3473-
.tp_new = iso_calendar_date_new,
3467+
static int
3468+
iso_calendar_date_traverse(PyDateTime_IsoCalendarDate *self, visitproc visit,
3469+
void *arg)
3470+
{
3471+
Py_VISIT(Py_TYPE(self));
3472+
return PyTuple_Type.tp_traverse((PyObject *)self, visit, arg);
3473+
}
3474+
3475+
static void
3476+
iso_calendar_date_dealloc(PyDateTime_IsoCalendarDate *self)
3477+
{
3478+
PyTypeObject *tp = Py_TYPE(self);
3479+
PyTuple_Type.tp_dealloc((PyObject *)self); // delegate GC-untrack as well
3480+
Py_DECREF(tp);
3481+
}
3482+
3483+
static PyType_Slot isocal_slots[] = {
3484+
{Py_tp_repr, iso_calendar_date_repr},
3485+
{Py_tp_doc, (void *)iso_calendar_date__doc__},
3486+
{Py_tp_methods, iso_calendar_date_methods},
3487+
{Py_tp_getset, iso_calendar_date_getset},
3488+
{Py_tp_new, iso_calendar_date_new},
3489+
{Py_tp_dealloc, iso_calendar_date_dealloc},
3490+
{Py_tp_traverse, iso_calendar_date_traverse},
3491+
{0, NULL},
3492+
};
3493+
3494+
static PyType_Spec isocal_spec = {
3495+
.name = "datetime.IsoCalendarDate",
3496+
.basicsize = sizeof(PyDateTime_IsoCalendarDate),
3497+
.flags = (Py_TPFLAGS_DEFAULT |
3498+
Py_TPFLAGS_HAVE_GC |
3499+
Py_TPFLAGS_IMMUTABLETYPE),
3500+
.slots = isocal_slots,
34743501
};
34753502

34763503
/*[clinic input]
@@ -6842,22 +6869,25 @@ create_timezone_from_delta(int days, int sec, int ms, int normalize)
68426869
}
68436870

68446871
static int
6845-
init_state(datetime_state *st)
6872+
init_state(datetime_state *st, PyTypeObject *PyDateTime_IsoCalendarDateType)
68466873
{
68476874
// While datetime uses global module "state", we unly initialize it once.
68486875
// The PyLong objects created here (once per process) are not decref'd.
68496876
if (st->initialized) {
68506877
return 0;
68516878
}
68526879

6880+
/* Static types exposed by the C-API. */
68536881
st->date_type = &PyDateTime_DateType;
68546882
st->datetime_type = &PyDateTime_DateTimeType;
68556883
st->delta_type = &PyDateTime_DeltaType;
6856-
st->isocalendar_date_type = &PyDateTime_IsoCalendarDateType;
68576884
st->time_type = &PyDateTime_TimeType;
68586885
st->tzinfo_type = &PyDateTime_TZInfoType;
68596886
st->timezone_type = &PyDateTime_TimeZoneType;
68606887

6888+
/* Per-module heap types. */
6889+
st->isocalendar_date_type = PyDateTime_IsoCalendarDateType;
6890+
68616891
st->us_per_ms = PyLong_FromLong(1000);
68626892
if (st->us_per_ms == NULL) {
68636893
return -1;
@@ -6914,11 +6944,10 @@ _datetime_exec(PyObject *module)
69146944
// `&...` is not a constant expression according to a strict reading
69156945
// of C standards. Fill tp_base at run-time rather than statically.
69166946
// See https://bugs.python.org/issue40777
6917-
PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
69186947
PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
69196948
PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
69206949

6921-
PyTypeObject *types[] = {
6950+
PyTypeObject *capi_types[] = {
69226951
&PyDateTime_DateType,
69236952
&PyDateTime_DateTimeType,
69246953
&PyDateTime_TimeType,
@@ -6927,18 +6956,30 @@ _datetime_exec(PyObject *module)
69276956
&PyDateTime_TimeZoneType,
69286957
};
69296958

6930-
for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
6931-
if (PyModule_AddType(module, types[i]) < 0) {
6959+
for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
6960+
if (PyModule_AddType(module, capi_types[i]) < 0) {
69326961
goto error;
69336962
}
69346963
}
69356964

6936-
if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
6937-
goto error;
6938-
}
6965+
#define CREATE_TYPE(VAR, SPEC, BASE) \
6966+
do { \
6967+
VAR = (PyTypeObject *)PyType_FromModuleAndSpec( \
6968+
module, SPEC, (PyObject *)BASE); \
6969+
if (VAR == NULL) { \
6970+
goto error; \
6971+
} \
6972+
} while (0)
69396973

6974+
PyTypeObject *PyDateTime_IsoCalendarDateType = NULL;
69406975
datetime_state *st = get_datetime_state();
6941-
if (init_state(st) < 0) {
6976+
6977+
if (!st->initialized) {
6978+
CREATE_TYPE(PyDateTime_IsoCalendarDateType, &isocal_spec, &PyTuple_Type);
6979+
}
6980+
#undef CREATE_TYPE
6981+
6982+
if (init_state(st, PyDateTime_IsoCalendarDateType) < 0) {
69426983
goto error;
69436984
}
69446985

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.