Skip to content

Commit 64be5ab

Browse files
gh-101277: Add combinations and cwr types to module state
1 parent aca9ef5 commit 64be5ab

File tree

1 file changed

+57
-93
lines changed

1 file changed

+57
-93
lines changed

Modules/itertoolsmodule.c

+57-93
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
*/
1212

1313
typedef struct {
14+
PyTypeObject *combinations_type;
15+
PyTypeObject *cwr_type;
1416
PyTypeObject *cycle_type;
1517
PyTypeObject *dropwhile_type;
1618
PyTypeObject *groupby_type;
@@ -49,22 +51,20 @@ class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
4951
class itertools.takewhile "takewhileobject *" "clinic_state()->takewhile_type"
5052
class itertools.starmap "starmapobject *" "clinic_state()->starmap_type"
5153
class itertools.chain "chainobject *" "&chain_type"
52-
class itertools.combinations "combinationsobject *" "&combinations_type"
53-
class itertools.combinations_with_replacement "cwr_object *" "&cwr_type"
54+
class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type"
55+
class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type"
5456
class itertools.permutations "permutationsobject *" "&permutations_type"
5557
class itertools.accumulate "accumulateobject *" "&accumulate_type"
5658
class itertools.compress "compressobject *" "&compress_type"
5759
class itertools.filterfalse "filterfalseobject *" "&filterfalse_type"
5860
class itertools.count "countobject *" "&count_type"
5961
class itertools.pairwise "pairwiseobject *" "&pairwise_type"
6062
[clinic start generated code]*/
61-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3b9f0718b7d49b01]*/
63+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d44fee9ebae461fb]*/
6264

6365
static PyTypeObject teedataobject_type;
6466
static PyTypeObject tee_type;
6567
static PyTypeObject batched_type;
66-
static PyTypeObject combinations_type;
67-
static PyTypeObject cwr_type;
6868
static PyTypeObject permutations_type;
6969
static PyTypeObject accumulate_type;
7070
static PyTypeObject compress_type;
@@ -2705,12 +2705,14 @@ itertools_combinations_impl(PyTypeObject *type, PyObject *iterable,
27052705
static void
27062706
combinations_dealloc(combinationsobject *co)
27072707
{
2708+
PyTypeObject *tp = Py_TYPE(co);
27082709
PyObject_GC_UnTrack(co);
27092710
Py_XDECREF(co->pool);
27102711
Py_XDECREF(co->result);
27112712
if (co->indices != NULL)
27122713
PyMem_Free(co->indices);
2713-
Py_TYPE(co)->tp_free(co);
2714+
tp->tp_free(co);
2715+
Py_DECREF(tp);
27142716
}
27152717

27162718
static PyObject *
@@ -2724,6 +2726,7 @@ combinations_sizeof(combinationsobject *co, void *unused)
27242726
static int
27252727
combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
27262728
{
2729+
Py_VISIT(Py_TYPE(co));
27272730
Py_VISIT(co->pool);
27282731
Py_VISIT(co->result);
27292732
return 0;
@@ -2894,48 +2897,25 @@ static PyMethodDef combinations_methods[] = {
28942897
{NULL, NULL} /* sentinel */
28952898
};
28962899

2897-
static PyTypeObject combinations_type = {
2898-
PyVarObject_HEAD_INIT(NULL, 0)
2899-
"itertools.combinations", /* tp_name */
2900-
sizeof(combinationsobject), /* tp_basicsize */
2901-
0, /* tp_itemsize */
2902-
/* methods */
2903-
(destructor)combinations_dealloc, /* tp_dealloc */
2904-
0, /* tp_vectorcall_offset */
2905-
0, /* tp_getattr */
2906-
0, /* tp_setattr */
2907-
0, /* tp_as_async */
2908-
0, /* tp_repr */
2909-
0, /* tp_as_number */
2910-
0, /* tp_as_sequence */
2911-
0, /* tp_as_mapping */
2912-
0, /* tp_hash */
2913-
0, /* tp_call */
2914-
0, /* tp_str */
2915-
PyObject_GenericGetAttr, /* tp_getattro */
2916-
0, /* tp_setattro */
2917-
0, /* tp_as_buffer */
2918-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2919-
Py_TPFLAGS_BASETYPE, /* tp_flags */
2920-
itertools_combinations__doc__, /* tp_doc */
2921-
(traverseproc)combinations_traverse,/* tp_traverse */
2922-
0, /* tp_clear */
2923-
0, /* tp_richcompare */
2924-
0, /* tp_weaklistoffset */
2925-
PyObject_SelfIter, /* tp_iter */
2926-
(iternextfunc)combinations_next, /* tp_iternext */
2927-
combinations_methods, /* tp_methods */
2928-
0, /* tp_members */
2929-
0, /* tp_getset */
2930-
0, /* tp_base */
2931-
0, /* tp_dict */
2932-
0, /* tp_descr_get */
2933-
0, /* tp_descr_set */
2934-
0, /* tp_dictoffset */
2935-
0, /* tp_init */
2936-
0, /* tp_alloc */
2937-
itertools_combinations, /* tp_new */
2938-
PyObject_GC_Del, /* tp_free */
2900+
static PyType_Slot combinations_slots[] = {
2901+
{Py_tp_dealloc, combinations_dealloc},
2902+
{Py_tp_getattro, PyObject_GenericGetAttr},
2903+
{Py_tp_doc, (void *)itertools_combinations__doc__},
2904+
{Py_tp_traverse, combinations_traverse},
2905+
{Py_tp_iter, PyObject_SelfIter},
2906+
{Py_tp_iternext, combinations_next},
2907+
{Py_tp_methods, combinations_methods},
2908+
{Py_tp_new, itertools_combinations},
2909+
{Py_tp_free, PyObject_GC_Del},
2910+
{0, NULL},
2911+
};
2912+
2913+
static PyType_Spec combinations_spec = {
2914+
.name = "itertools.combinations",
2915+
.basicsize = sizeof(combinationsobject),
2916+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
2917+
Py_TPFLAGS_IMMUTABLETYPE),
2918+
.slots = combinations_slots,
29392919
};
29402920

29412921

@@ -3039,12 +3019,14 @@ itertools_combinations_with_replacement_impl(PyTypeObject *type,
30393019
static void
30403020
cwr_dealloc(cwrobject *co)
30413021
{
3022+
PyTypeObject *tp = Py_TYPE(co);
30423023
PyObject_GC_UnTrack(co);
30433024
Py_XDECREF(co->pool);
30443025
Py_XDECREF(co->result);
30453026
if (co->indices != NULL)
30463027
PyMem_Free(co->indices);
3047-
Py_TYPE(co)->tp_free(co);
3028+
tp->tp_free(co);
3029+
Py_DECREF(tp);
30483030
}
30493031

30503032
static PyObject *
@@ -3058,6 +3040,7 @@ cwr_sizeof(cwrobject *co, void *unused)
30583040
static int
30593041
cwr_traverse(cwrobject *co, visitproc visit, void *arg)
30603042
{
3043+
Py_VISIT(Py_TYPE(co));
30613044
Py_VISIT(co->pool);
30623045
Py_VISIT(co->result);
30633046
return 0;
@@ -3218,48 +3201,25 @@ static PyMethodDef cwr_methods[] = {
32183201
{NULL, NULL} /* sentinel */
32193202
};
32203203

3221-
static PyTypeObject cwr_type = {
3222-
PyVarObject_HEAD_INIT(NULL, 0)
3223-
"itertools.combinations_with_replacement", /* tp_name */
3224-
sizeof(cwrobject), /* tp_basicsize */
3225-
0, /* tp_itemsize */
3226-
/* methods */
3227-
(destructor)cwr_dealloc, /* tp_dealloc */
3228-
0, /* tp_vectorcall_offset */
3229-
0, /* tp_getattr */
3230-
0, /* tp_setattr */
3231-
0, /* tp_as_async */
3232-
0, /* tp_repr */
3233-
0, /* tp_as_number */
3234-
0, /* tp_as_sequence */
3235-
0, /* tp_as_mapping */
3236-
0, /* tp_hash */
3237-
0, /* tp_call */
3238-
0, /* tp_str */
3239-
PyObject_GenericGetAttr, /* tp_getattro */
3240-
0, /* tp_setattro */
3241-
0, /* tp_as_buffer */
3242-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3243-
Py_TPFLAGS_BASETYPE, /* tp_flags */
3244-
itertools_combinations_with_replacement__doc__, /* tp_doc */
3245-
(traverseproc)cwr_traverse, /* tp_traverse */
3246-
0, /* tp_clear */
3247-
0, /* tp_richcompare */
3248-
0, /* tp_weaklistoffset */
3249-
PyObject_SelfIter, /* tp_iter */
3250-
(iternextfunc)cwr_next, /* tp_iternext */
3251-
cwr_methods, /* tp_methods */
3252-
0, /* tp_members */
3253-
0, /* tp_getset */
3254-
0, /* tp_base */
3255-
0, /* tp_dict */
3256-
0, /* tp_descr_get */
3257-
0, /* tp_descr_set */
3258-
0, /* tp_dictoffset */
3259-
0, /* tp_init */
3260-
0, /* tp_alloc */
3261-
itertools_combinations_with_replacement, /* tp_new */
3262-
PyObject_GC_Del, /* tp_free */
3204+
static PyType_Slot cwr_slots[] = {
3205+
{Py_tp_dealloc, cwr_dealloc},
3206+
{Py_tp_getattro, PyObject_GenericGetAttr},
3207+
{Py_tp_doc, (void *)itertools_combinations_with_replacement__doc__},
3208+
{Py_tp_traverse, cwr_traverse},
3209+
{Py_tp_iter, PyObject_SelfIter},
3210+
{Py_tp_iternext, cwr_next},
3211+
{Py_tp_methods, cwr_methods},
3212+
{Py_tp_new, itertools_combinations_with_replacement},
3213+
{Py_tp_free, PyObject_GC_Del},
3214+
{0, NULL},
3215+
};
3216+
3217+
static PyType_Spec cwr_spec = {
3218+
.name = "itertools.combinations_with_replacement",
3219+
.basicsize = sizeof(cwrobject),
3220+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
3221+
Py_TPFLAGS_IMMUTABLETYPE),
3222+
.slots = cwr_slots,
32633223
};
32643224

32653225

@@ -4881,6 +4841,8 @@ static int
48814841
itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
48824842
{
48834843
itertools_state *state = get_module_state(mod);
4844+
Py_VISIT(state->combinations_type);
4845+
Py_VISIT(state->cwr_type);
48844846
Py_VISIT(state->cycle_type);
48854847
Py_VISIT(state->dropwhile_type);
48864848
Py_VISIT(state->groupby_type);
@@ -4894,6 +4856,8 @@ static int
48944856
itertoolsmodule_clear(PyObject *mod)
48954857
{
48964858
itertools_state *state = get_module_state(mod);
4859+
Py_CLEAR(state->combinations_type);
4860+
Py_CLEAR(state->cwr_type);
48974861
Py_CLEAR(state->cycle_type);
48984862
Py_CLEAR(state->dropwhile_type);
48994863
Py_CLEAR(state->groupby_type);
@@ -4924,6 +4888,8 @@ static int
49244888
itertoolsmodule_exec(PyObject *mod)
49254889
{
49264890
itertools_state *state = get_module_state(mod);
4891+
ADD_TYPE(mod, state->combinations_type, &combinations_spec);
4892+
ADD_TYPE(mod, state->cwr_type, &cwr_spec);
49274893
ADD_TYPE(mod, state->cycle_type, &cycle_spec);
49284894
ADD_TYPE(mod, state->dropwhile_type, &dropwhile_spec);
49294895
ADD_TYPE(mod, state->groupby_type, &groupby_spec);
@@ -4934,8 +4900,6 @@ itertoolsmodule_exec(PyObject *mod)
49344900
PyTypeObject *typelist[] = {
49354901
&accumulate_type,
49364902
&batched_type,
4937-
&combinations_type,
4938-
&cwr_type,
49394903
&islice_type,
49404904
&chain_type,
49414905
&compress_type,

0 commit comments

Comments
 (0)