Skip to content

Commit d18169b

Browse files
pythongh-101277: Add chain type to module state
1 parent a66b888 commit d18169b

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
@@ -13,6 +13,7 @@
1313

1414
typedef struct {
1515
PyTypeObject *accumulate_type;
16+
PyTypeObject *chain_type;
1617
PyTypeObject *combinations_type;
1718
PyTypeObject *compress_type;
1819
PyTypeObject *count_type;
@@ -69,7 +70,7 @@ class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
6970
class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
7071
class itertools.takewhile "takewhileobject *" "clinic_state()->takewhile_type"
7172
class itertools.starmap "starmapobject *" "clinic_state()->starmap_type"
72-
class itertools.chain "chainobject *" "&chain_type"
73+
class itertools.chain "chainobject *" "clinic_state()->chain_type"
7374
class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type"
7475
class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type"
7576
class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type"
@@ -79,7 +80,7 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
7980
class itertools.count "countobject *" "clinic_state()->count_type"
8081
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
8182
[clinic start generated code]*/
82-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=28ffff5c0c93eed7]*/
83+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=102319065d3e090b]*/
8384

8485
static PyTypeObject teedataobject_type;
8586
static PyTypeObject tee_type;
@@ -2038,8 +2039,6 @@ typedef struct {
20382039
PyObject *active; /* Currently running input iterator */
20392040
} chainobject;
20402041

2041-
static PyTypeObject chain_type;
2042-
20432042
static PyObject *
20442043
chain_new_internal(PyTypeObject *type, PyObject *source)
20452044
{
@@ -2061,9 +2060,12 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20612060
{
20622061
PyObject *source;
20632062

2064-
if ((type == &chain_type || type->tp_init == chain_type.tp_init) &&
2065-
!_PyArg_NoKeywords("chain", kwds))
2063+
itertools_state *st = find_state_by_type(type);
2064+
if ((type == st->chain_type || type->tp_init == st->chain_type->tp_init)
2065+
&& !_PyArg_NoKeywords("chain", kwds))
2066+
{
20662067
return NULL;
2068+
}
20672069

20682070
source = PyObject_GetIter(args);
20692071
if (source == NULL)
@@ -2096,15 +2098,18 @@ itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg)
20962098
static void
20972099
chain_dealloc(chainobject *lz)
20982100
{
2101+
PyTypeObject *tp = Py_TYPE(lz);
20992102
PyObject_GC_UnTrack(lz);
21002103
Py_XDECREF(lz->active);
21012104
Py_XDECREF(lz->source);
2102-
Py_TYPE(lz)->tp_free(lz);
2105+
tp->tp_free(lz);
2106+
Py_DECREF(tp);
21032107
}
21042108

21052109
static int
21062110
chain_traverse(chainobject *lz, visitproc visit, void *arg)
21072111
{
2112+
Py_VISIT(Py_TYPE(lz));
21082113
Py_VISIT(lz->source);
21092114
Py_VISIT(lz->active);
21102115
return 0;
@@ -2209,48 +2214,24 @@ static PyMethodDef chain_methods[] = {
22092214
{NULL, NULL} /* sentinel */
22102215
};
22112216

2212-
static PyTypeObject chain_type = {
2213-
PyVarObject_HEAD_INIT(NULL, 0)
2214-
"itertools.chain", /* tp_name */
2215-
sizeof(chainobject), /* tp_basicsize */
2216-
0, /* tp_itemsize */
2217-
/* methods */
2218-
(destructor)chain_dealloc, /* tp_dealloc */
2219-
0, /* tp_vectorcall_offset */
2220-
0, /* tp_getattr */
2221-
0, /* tp_setattr */
2222-
0, /* tp_as_async */
2223-
0, /* tp_repr */
2224-
0, /* tp_as_number */
2225-
0, /* tp_as_sequence */
2226-
0, /* tp_as_mapping */
2227-
0, /* tp_hash */
2228-
0, /* tp_call */
2229-
0, /* tp_str */
2230-
PyObject_GenericGetAttr, /* tp_getattro */
2231-
0, /* tp_setattro */
2232-
0, /* tp_as_buffer */
2233-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2234-
Py_TPFLAGS_BASETYPE, /* tp_flags */
2235-
chain_doc, /* tp_doc */
2236-
(traverseproc)chain_traverse, /* tp_traverse */
2237-
0, /* tp_clear */
2238-
0, /* tp_richcompare */
2239-
0, /* tp_weaklistoffset */
2240-
PyObject_SelfIter, /* tp_iter */
2241-
(iternextfunc)chain_next, /* tp_iternext */
2242-
chain_methods, /* tp_methods */
2243-
0, /* tp_members */
2244-
0, /* tp_getset */
2245-
0, /* tp_base */
2246-
0, /* tp_dict */
2247-
0, /* tp_descr_get */
2248-
0, /* tp_descr_set */
2249-
0, /* tp_dictoffset */
2250-
0, /* tp_init */
2251-
0, /* tp_alloc */
2252-
chain_new, /* tp_new */
2253-
PyObject_GC_Del, /* tp_free */
2217+
static PyType_Slot chain_slots[] = {
2218+
{Py_tp_dealloc, chain_dealloc},
2219+
{Py_tp_getattro, PyObject_GenericGetAttr},
2220+
{Py_tp_doc, (void *)chain_doc},
2221+
{Py_tp_traverse, chain_traverse},
2222+
{Py_tp_iter, PyObject_SelfIter},
2223+
{Py_tp_iternext, chain_next},
2224+
{Py_tp_methods, chain_methods},
2225+
{Py_tp_new, chain_new},
2226+
{Py_tp_free, PyObject_GC_Del},
2227+
{0, NULL},
2228+
};
2229+
2230+
static PyType_Spec chain_spec = {
2231+
.name = "itertools.chain",
2232+
.basicsize = sizeof(chainobject),
2233+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
2234+
.slots = chain_slots,
22542235
};
22552236

22562237

@@ -3656,13 +3637,14 @@ accumulate_next(accumulateobject *lz)
36563637
static PyObject *
36573638
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36583639
{
3640+
PyTypeObject *tp = Py_TYPE(lz);
3641+
itertools_state *state = find_state_by_type(tp);
3642+
36593643
if (lz->initial != Py_None) {
36603644
PyObject *it;
36613645

36623646
assert(lz->total == NULL);
3663-
if (PyType_Ready(&chain_type) < 0)
3664-
return NULL;
3665-
it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3647+
it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
36663648
lz->initial, lz->it);
36673649
if (it == NULL)
36683650
return NULL;
@@ -3672,9 +3654,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36723654
if (lz->total == Py_None) {
36733655
PyObject *it;
36743656

3675-
if (PyType_Ready(&chain_type) < 0)
3676-
return NULL;
3677-
it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3657+
it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
36783658
lz->total, lz->it);
36793659
if (it == NULL)
36803660
return NULL;
@@ -3683,8 +3663,6 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
36833663
if (it == NULL)
36843664
return NULL;
36853665

3686-
PyTypeObject *tp = Py_TYPE(lz);
3687-
itertools_state *state = find_state_by_type(tp);
36883666
return Py_BuildValue("O(NiO)", state->islice_type, it, 1, Py_None);
36893667
}
36903668
return Py_BuildValue("O(OO)O", Py_TYPE(lz),
@@ -4656,6 +4634,7 @@ itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
46564634
{
46574635
itertools_state *state = get_module_state(mod);
46584636
Py_VISIT(state->accumulate_type);
4637+
Py_VISIT(state->chain_type);
46594638
Py_VISIT(state->combinations_type);
46604639
Py_VISIT(state->compress_type);
46614640
Py_VISIT(state->count_type);
@@ -4681,6 +4660,7 @@ itertoolsmodule_clear(PyObject *mod)
46814660
{
46824661
itertools_state *state = get_module_state(mod);
46834662
Py_CLEAR(state->accumulate_type);
4663+
Py_CLEAR(state->chain_type);
46844664
Py_CLEAR(state->combinations_type);
46854665
Py_CLEAR(state->compress_type);
46864666
Py_CLEAR(state->count_type);
@@ -4723,6 +4703,7 @@ itertoolsmodule_exec(PyObject *mod)
47234703
{
47244704
itertools_state *state = get_module_state(mod);
47254705
ADD_TYPE(mod, state->accumulate_type, &accumulate_spec);
4706+
ADD_TYPE(mod, state->chain_type, &chain_spec);
47264707
ADD_TYPE(mod, state->combinations_type, &combinations_spec);
47274708
ADD_TYPE(mod, state->compress_type, &compress_spec);
47284709
ADD_TYPE(mod, state->count_type, &count_spec);
@@ -4743,7 +4724,6 @@ itertoolsmodule_exec(PyObject *mod)
47434724

47444725
PyTypeObject *typelist[] = {
47454726
&batched_type,
4746-
&chain_type,
47474727
&tee_type,
47484728
&teedataobject_type
47494729
};

0 commit comments

Comments
 (0)