Skip to content

Commit 27ee72c

Browse files
pythongh-101277: Add chain type to module state
1 parent 4a30327 commit 27ee72c

File tree

1 file changed

+38
-58
lines changed

1 file changed

+38
-58
lines changed

Modules/itertoolsmodule.c

+38-58
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
typedef struct {
1414
PyTypeObject *accumulate_type;
15+
PyTypeObject *chain_type;
1516
PyTypeObject *combinations_type;
1617
PyTypeObject *compress_type;
1718
PyTypeObject *count_type;
@@ -60,7 +61,7 @@ class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
6061
class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
6162
class itertools.takewhile "takewhileobject *" "clinic_state()->takewhile_type"
6263
class itertools.starmap "starmapobject *" "clinic_state()->starmap_type"
63-
class itertools.chain "chainobject *" "&chain_type"
64+
class itertools.chain "chainobject *" "clinic_state()->chain_type"
6465
class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type"
6566
class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type"
6667
class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type"
@@ -70,7 +71,7 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
7071
class itertools.count "countobject *" "clinic_state()->count_type"
7172
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
7273
[clinic start generated code]*/
73-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=28ffff5c0c93eed7]*/
74+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=102319065d3e090b]*/
7475

7576
static PyTypeObject teedataobject_type;
7677
static PyTypeObject tee_type;
@@ -2024,8 +2025,6 @@ typedef struct {
20242025
PyObject *active; /* Currently running input iterator */
20252026
} chainobject;
20262027

2027-
static PyTypeObject chain_type;
2028-
20292028
static PyObject *
20302029
chain_new_internal(PyTypeObject *type, PyObject *source)
20312030
{
@@ -2047,9 +2046,12 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20472046
{
20482047
PyObject *source;
20492048

2050-
if ((type == &chain_type || type->tp_init == chain_type.tp_init) &&
2051-
!_PyArg_NoKeywords("chain", kwds))
2049+
itertools_state *st = find_state_by_type(type);
2050+
if ((type == st->chain_type || type->tp_init == st->chain_type->tp_init)
2051+
&& !_PyArg_NoKeywords("chain", kwds))
2052+
{
20522053
return NULL;
2054+
}
20532055

20542056
source = PyObject_GetIter(args);
20552057
if (source == NULL)
@@ -2082,15 +2084,18 @@ itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg)
20822084
static void
20832085
chain_dealloc(chainobject *lz)
20842086
{
2087+
PyTypeObject *tp = Py_TYPE(lz);
20852088
PyObject_GC_UnTrack(lz);
20862089
Py_XDECREF(lz->active);
20872090
Py_XDECREF(lz->source);
2088-
Py_TYPE(lz)->tp_free(lz);
2091+
tp->tp_free(lz);
2092+
Py_DECREF(tp);
20892093
}
20902094

20912095
static int
20922096
chain_traverse(chainobject *lz, visitproc visit, void *arg)
20932097
{
2098+
Py_VISIT(Py_TYPE(lz));
20942099
Py_VISIT(lz->source);
20952100
Py_VISIT(lz->active);
20962101
return 0;
@@ -2195,48 +2200,24 @@ static PyMethodDef chain_methods[] = {
21952200
{NULL, NULL} /* sentinel */
21962201
};
21972202

2198-
static PyTypeObject chain_type = {
2199-
PyVarObject_HEAD_INIT(NULL, 0)
2200-
"itertools.chain", /* tp_name */
2201-
sizeof(chainobject), /* tp_basicsize */
2202-
0, /* tp_itemsize */
2203-
/* methods */
2204-
(destructor)chain_dealloc, /* tp_dealloc */
2205-
0, /* tp_vectorcall_offset */
2206-
0, /* tp_getattr */
2207-
0, /* tp_setattr */
2208-
0, /* tp_as_async */
2209-
0, /* tp_repr */
2210-
0, /* tp_as_number */
2211-
0, /* tp_as_sequence */
2212-
0, /* tp_as_mapping */
2213-
0, /* tp_hash */
2214-
0, /* tp_call */
2215-
0, /* tp_str */
2216-
PyObject_GenericGetAttr, /* tp_getattro */
2217-
0, /* tp_setattro */
2218-
0, /* tp_as_buffer */
2219-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2220-
Py_TPFLAGS_BASETYPE, /* tp_flags */
2221-
chain_doc, /* tp_doc */
2222-
(traverseproc)chain_traverse, /* tp_traverse */
2223-
0, /* tp_clear */
2224-
0, /* tp_richcompare */
2225-
0, /* tp_weaklistoffset */
2226-
PyObject_SelfIter, /* tp_iter */
2227-
(iternextfunc)chain_next, /* tp_iternext */
2228-
chain_methods, /* tp_methods */
2229-
0, /* tp_members */
2230-
0, /* tp_getset */
2231-
0, /* tp_base */
2232-
0, /* tp_dict */
2233-
0, /* tp_descr_get */
2234-
0, /* tp_descr_set */
2235-
0, /* tp_dictoffset */
2236-
0, /* tp_init */
2237-
0, /* tp_alloc */
2238-
chain_new, /* tp_new */
2239-
PyObject_GC_Del, /* tp_free */
2203+
static PyType_Slot chain_slots[] = {
2204+
{Py_tp_dealloc, chain_dealloc},
2205+
{Py_tp_getattro, PyObject_GenericGetAttr},
2206+
{Py_tp_doc, (void *)chain_doc},
2207+
{Py_tp_traverse, chain_traverse},
2208+
{Py_tp_iter, PyObject_SelfIter},
2209+
{Py_tp_iternext, chain_next},
2210+
{Py_tp_methods, chain_methods},
2211+
{Py_tp_new, chain_new},
2212+
{Py_tp_free, PyObject_GC_Del},
2213+
{0, NULL},
2214+
};
2215+
2216+
static PyType_Spec chain_spec = {
2217+
.name = "itertools.chain",
2218+
.basicsize = sizeof(chainobject),
2219+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
2220+
.slots = chain_slots,
22402221
};
22412222

22422223

@@ -3642,13 +3623,14 @@ accumulate_next(accumulateobject *lz)
36423623
static PyObject *
36433624
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36443625
{
3626+
PyTypeObject *tp = Py_TYPE(lz);
3627+
itertools_state *state = find_state_by_type(tp);
3628+
36453629
if (lz->initial != Py_None) {
36463630
PyObject *it;
36473631

36483632
assert(lz->total == NULL);
3649-
if (PyType_Ready(&chain_type) < 0)
3650-
return NULL;
3651-
it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3633+
it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
36523634
lz->initial, lz->it);
36533635
if (it == NULL)
36543636
return NULL;
@@ -3658,9 +3640,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36583640
if (lz->total == Py_None) {
36593641
PyObject *it;
36603642

3661-
if (PyType_Ready(&chain_type) < 0)
3662-
return NULL;
3663-
it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3643+
it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
36643644
lz->total, lz->it);
36653645
if (it == NULL)
36663646
return NULL;
@@ -3669,8 +3649,6 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36693649
if (it == NULL)
36703650
return NULL;
36713651

3672-
PyTypeObject *tp = Py_TYPE(lz);
3673-
itertools_state *state = find_state_by_type(tp);
36743652
return Py_BuildValue("O(NiO)", state->islice_type, it, 1, Py_None);
36753653
}
36763654
return Py_BuildValue("O(OO)O", Py_TYPE(lz),
@@ -4642,6 +4620,7 @@ itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
46424620
{
46434621
itertools_state *state = get_module_state(mod);
46444622
Py_VISIT(state->accumulate_type);
4623+
Py_VISIT(state->chain_type);
46454624
Py_VISIT(state->combinations_type);
46464625
Py_VISIT(state->compress_type);
46474626
Py_VISIT(state->count_type);
@@ -4666,6 +4645,7 @@ itertoolsmodule_clear(PyObject *mod)
46664645
{
46674646
itertools_state *state = get_module_state(mod);
46684647
Py_CLEAR(state->accumulate_type);
4648+
Py_CLEAR(state->chain_type);
46694649
Py_CLEAR(state->combinations_type);
46704650
Py_CLEAR(state->compress_type);
46714651
Py_CLEAR(state->count_type);
@@ -4707,6 +4687,7 @@ itertoolsmodule_exec(PyObject *mod)
47074687
{
47084688
itertools_state *state = get_module_state(mod);
47094689
ADD_TYPE(mod, state->accumulate_type, &accumulate_spec);
4690+
ADD_TYPE(mod, state->chain_type, &chain_spec);
47104691
ADD_TYPE(mod, state->combinations_type, &combinations_spec);
47114692
ADD_TYPE(mod, state->compress_type, &compress_spec);
47124693
ADD_TYPE(mod, state->count_type, &count_spec);
@@ -4727,7 +4708,6 @@ itertoolsmodule_exec(PyObject *mod)
47274708

47284709
PyTypeObject *typelist[] = {
47294710
&batched_type,
4730-
&chain_type,
47314711
&tee_type,
47324712
&teedataobject_type
47334713
};

0 commit comments

Comments
 (0)