mirror of https://github.com/python/cpython
gh-117398: Convert datetime.IsoCalendarDate To A Heap Type (gh-119637)
This is the only static type in the module that we will not keep static.
This commit is contained in:
parent
606be66362
commit
548a11d5cf
|
@ -26,14 +26,18 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/* Static types exposed by the datetime C-API. */
|
||||||
PyTypeObject *date_type;
|
PyTypeObject *date_type;
|
||||||
PyTypeObject *datetime_type;
|
PyTypeObject *datetime_type;
|
||||||
PyTypeObject *delta_type;
|
PyTypeObject *delta_type;
|
||||||
PyTypeObject *isocalendar_date_type;
|
|
||||||
PyTypeObject *time_type;
|
PyTypeObject *time_type;
|
||||||
PyTypeObject *tzinfo_type;
|
PyTypeObject *tzinfo_type;
|
||||||
|
/* Exposed indirectly via TimeZone_UTC. */
|
||||||
PyTypeObject *timezone_type;
|
PyTypeObject *timezone_type;
|
||||||
|
|
||||||
|
/* Other module classes. */
|
||||||
|
PyTypeObject *isocalendar_date_type;
|
||||||
|
|
||||||
/* Conversion factors. */
|
/* Conversion factors. */
|
||||||
PyObject *us_per_ms; // 1_000
|
PyObject *us_per_ms; // 1_000
|
||||||
PyObject *us_per_second; // 1_000_000
|
PyObject *us_per_second; // 1_000_000
|
||||||
|
@ -3460,17 +3464,40 @@ static PyMethodDef iso_calendar_date_methods[] = {
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject PyDateTime_IsoCalendarDateType = {
|
static int
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
iso_calendar_date_traverse(PyDateTime_IsoCalendarDate *self, visitproc visit,
|
||||||
.tp_name = "datetime.IsoCalendarDate",
|
void *arg)
|
||||||
.tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
|
{
|
||||||
.tp_repr = (reprfunc) iso_calendar_date_repr,
|
Py_VISIT(Py_TYPE(self));
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
return PyTuple_Type.tp_traverse((PyObject *)self, visit, arg);
|
||||||
.tp_doc = iso_calendar_date__doc__,
|
}
|
||||||
.tp_methods = iso_calendar_date_methods,
|
|
||||||
.tp_getset = iso_calendar_date_getset,
|
static void
|
||||||
// .tp_base = &PyTuple_Type, // filled in PyInit__datetime
|
iso_calendar_date_dealloc(PyDateTime_IsoCalendarDate *self)
|
||||||
.tp_new = iso_calendar_date_new,
|
{
|
||||||
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
|
PyTuple_Type.tp_dealloc((PyObject *)self); // delegate GC-untrack as well
|
||||||
|
Py_DECREF(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyType_Slot isocal_slots[] = {
|
||||||
|
{Py_tp_repr, iso_calendar_date_repr},
|
||||||
|
{Py_tp_doc, (void *)iso_calendar_date__doc__},
|
||||||
|
{Py_tp_methods, iso_calendar_date_methods},
|
||||||
|
{Py_tp_getset, iso_calendar_date_getset},
|
||||||
|
{Py_tp_new, iso_calendar_date_new},
|
||||||
|
{Py_tp_dealloc, iso_calendar_date_dealloc},
|
||||||
|
{Py_tp_traverse, iso_calendar_date_traverse},
|
||||||
|
{0, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyType_Spec isocal_spec = {
|
||||||
|
.name = "datetime.IsoCalendarDate",
|
||||||
|
.basicsize = sizeof(PyDateTime_IsoCalendarDate),
|
||||||
|
.flags = (Py_TPFLAGS_DEFAULT |
|
||||||
|
Py_TPFLAGS_HAVE_GC |
|
||||||
|
Py_TPFLAGS_IMMUTABLETYPE),
|
||||||
|
.slots = isocal_slots,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -6842,7 +6869,7 @@ create_timezone_from_delta(int days, int sec, int ms, int normalize)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_state(datetime_state *st)
|
init_state(datetime_state *st, PyTypeObject *PyDateTime_IsoCalendarDateType)
|
||||||
{
|
{
|
||||||
// While datetime uses global module "state", we unly initialize it once.
|
// While datetime uses global module "state", we unly initialize it once.
|
||||||
// The PyLong objects created here (once per process) are not decref'd.
|
// The PyLong objects created here (once per process) are not decref'd.
|
||||||
|
@ -6850,14 +6877,17 @@ init_state(datetime_state *st)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Static types exposed by the C-API. */
|
||||||
st->date_type = &PyDateTime_DateType;
|
st->date_type = &PyDateTime_DateType;
|
||||||
st->datetime_type = &PyDateTime_DateTimeType;
|
st->datetime_type = &PyDateTime_DateTimeType;
|
||||||
st->delta_type = &PyDateTime_DeltaType;
|
st->delta_type = &PyDateTime_DeltaType;
|
||||||
st->isocalendar_date_type = &PyDateTime_IsoCalendarDateType;
|
|
||||||
st->time_type = &PyDateTime_TimeType;
|
st->time_type = &PyDateTime_TimeType;
|
||||||
st->tzinfo_type = &PyDateTime_TZInfoType;
|
st->tzinfo_type = &PyDateTime_TZInfoType;
|
||||||
st->timezone_type = &PyDateTime_TimeZoneType;
|
st->timezone_type = &PyDateTime_TimeZoneType;
|
||||||
|
|
||||||
|
/* Per-module heap types. */
|
||||||
|
st->isocalendar_date_type = PyDateTime_IsoCalendarDateType;
|
||||||
|
|
||||||
st->us_per_ms = PyLong_FromLong(1000);
|
st->us_per_ms = PyLong_FromLong(1000);
|
||||||
if (st->us_per_ms == NULL) {
|
if (st->us_per_ms == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -6914,11 +6944,10 @@ _datetime_exec(PyObject *module)
|
||||||
// `&...` is not a constant expression according to a strict reading
|
// `&...` is not a constant expression according to a strict reading
|
||||||
// of C standards. Fill tp_base at run-time rather than statically.
|
// of C standards. Fill tp_base at run-time rather than statically.
|
||||||
// See https://bugs.python.org/issue40777
|
// See https://bugs.python.org/issue40777
|
||||||
PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
|
|
||||||
PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
|
PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
|
||||||
PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
|
PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
|
||||||
|
|
||||||
PyTypeObject *types[] = {
|
PyTypeObject *capi_types[] = {
|
||||||
&PyDateTime_DateType,
|
&PyDateTime_DateType,
|
||||||
&PyDateTime_DateTimeType,
|
&PyDateTime_DateTimeType,
|
||||||
&PyDateTime_TimeType,
|
&PyDateTime_TimeType,
|
||||||
|
@ -6927,18 +6956,27 @@ _datetime_exec(PyObject *module)
|
||||||
&PyDateTime_TimeZoneType,
|
&PyDateTime_TimeZoneType,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
|
for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
|
||||||
if (PyModule_AddType(module, types[i]) < 0) {
|
if (PyModule_AddType(module, capi_types[i]) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
|
#define CREATE_TYPE(VAR, SPEC, BASE) \
|
||||||
goto error;
|
do { \
|
||||||
}
|
VAR = (PyTypeObject *)PyType_FromModuleAndSpec( \
|
||||||
|
module, SPEC, (PyObject *)BASE); \
|
||||||
|
if (VAR == NULL) { \
|
||||||
|
goto error; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
PyTypeObject *PyDateTime_IsoCalendarDateType = NULL;
|
||||||
|
CREATE_TYPE(PyDateTime_IsoCalendarDateType, &isocal_spec, &PyTuple_Type);
|
||||||
|
#undef CREATE_TYPE
|
||||||
|
|
||||||
datetime_state *st = get_datetime_state();
|
datetime_state *st = get_datetime_state();
|
||||||
if (init_state(st) < 0) {
|
if (init_state(st, PyDateTime_IsoCalendarDateType) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue