Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
31fbfa7
Merge pull request #1 from mjp41/regions-main
CaQtiml Jan 26, 2026
245179f
Merge pull request #2 from mjp41/regions-main
CaQtiml Jan 26, 2026
1ddccba
Merge pull request #3 from mjp41/regions-main
CaQtiml Jan 29, 2026
a0c4e23
add script for cleaning old cpython installation after merging update…
CaQtiml Jan 29, 2026
77b0e22
Merge pull request #4 from mjp41/regions-main
CaQtiml Feb 7, 2026
e5949a9
Add support to "range" object - version 1 (incomplete)
CaQtiml Feb 18, 2026
5ee2b63
update to support tp_new, tp_vectorcall, tp_dealloc, and range_repr f…
CaQtiml Feb 19, 2026
c7fa2c6
add barrier for iter(range) and reverse(range) with the support to de…
CaQtiml Feb 19, 2026
9c55a11
migrate range_as_mapping and decide that range_as_number and range_as…
CaQtiml Feb 21, 2026
d3f0310
Merge pull request #5 from mjp41/regions-main
CaQtiml Feb 23, 2026
a134c2f
Merge pull request #6 from CaQtiml/regions-main
CaQtiml Feb 23, 2026
078c9e2
finalizing range data structure migration
CaQtiml Feb 23, 2026
21781b9
add test cases for rnage data structure
CaQtiml Feb 24, 2026
47bf1f3
fix assert _Py_IsImmutable bug
CaQtiml Feb 24, 2026
44c8ddb
add and update testcases
CaQtiml Mar 2, 2026
cdccb3f
update set migration on new, dealloc, repr, and setiter (not finished)
CaQtiml Mar 2, 2026
129afcf
Merge pull request #7 from mjp41/regions-main
CaQtiml Mar 3, 2026
0df3e2a
Merge pull request #8 from CaQtiml/regions-main
CaQtiml Mar 3, 2026
30e4bcc
Merge pull request #9 from mjp41/regions-main
CaQtiml Mar 3, 2026
a86b4bf
Merge pull request #10 from CaQtiml/regions-main
CaQtiml Mar 3, 2026
b1358b6
update set_sub and set_and with testcases
CaQtiml Mar 4, 2026
4c8910d
finish migrating set_as_number
CaQtiml Mar 4, 2026
dad52e4
migrate more set data structure
CaQtiml Mar 5, 2026
d7de1b4
add basic unit test for testing region of set data structure
CaQtiml Mar 5, 2026
8b96506
update set migration with unit-test
CaQtiml Mar 6, 2026
4ee5d7b
Merge pull request #11 from fxpl/regions-main
CaQtiml Mar 6, 2026
40d6185
Merge pull request #12 from CaQtiml/regions-main
CaQtiml Mar 6, 2026
f6dd87c
update unit test
CaQtiml Mar 8, 2026
15f2e5d
update set unit test for intersection and intersection_update
CaQtiml Mar 8, 2026
94e360b
update set unit test in intersectupdate
CaQtiml Mar 8, 2026
df8d051
update set unit test and testcase
CaQtiml Mar 10, 2026
bd635e9
update test cases and unit test
CaQtiml Mar 10, 2026
6be539f
update test cases and unit test for set
CaQtiml Mar 10, 2026
7a03554
update setior and update to work correctly. set_swap_bodies still has…
CaQtiml Mar 11, 2026
845327d
update set_swap_body
CaQtiml Mar 11, 2026
7db8d92
update set_swap_bodies comment
CaQtiml Mar 12, 2026
f62f829
update test code
CaQtiml Mar 16, 2026
0b41cc3
PyObject_SelfIter should be migrated. Add test for this in test_set. …
CaQtiml Mar 23, 2026
bf2e159
update test_set
CaQtiml Mar 23, 2026
01ec042
update set unit test and add enumerate unit test
CaQtiml Mar 24, 2026
d84632d
add comment in context.c for better understanding
CaQtiml Mar 25, 2026
39270ff
update set_add_entry_takeref by adding bool to tell if TakeRef is req…
CaQtiml Mar 25, 2026
4b6329b
update test file
CaQtiml Mar 26, 2026
eca89fb
update enumobject and testcases
CaQtiml Mar 30, 2026
2494094
update itertools batched and pairwise (need to be refined, but I thin…
CaQtiml Mar 31, 2026
d456e28
Merge pull request #13 from fxpl/regions-main
CaQtiml Mar 31, 2026
6ec7c38
Merge pull request #14 from fxpl/regions-main
CaQtiml Mar 31, 2026
eea9c17
Merge pull request #15 from CaQtiml/regions-main
CaQtiml Mar 31, 2026
3d786ec
update testcases and itertools.pairwise
CaQtiml Apr 1, 2026
fdeed59
migrate to support printing the np array in numpy
CaQtiml Apr 2, 2026
9b4c222
fix bug in setiter_iternext.
CaQtiml Apr 3, 2026
3a62493
update XSETLOCALREF and XSETREF to handle error from firing the barrier
CaQtiml Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
525 changes: 525 additions & 0 deletions Lib/test/test_regions/test_enum.py

Large diffs are not rendered by default.

831 changes: 831 additions & 0 deletions Lib/test/test_regions/test_itertools.py

Large diffs are not rendered by default.

1,595 changes: 1,595 additions & 0 deletions Lib/test/test_regions/test_set.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Modules/clinic/itertoolsmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

155 changes: 126 additions & 29 deletions Modules/itertoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,18 @@ batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n,
/* create batchedobject structure */
bo = (batchedobject *)type->tp_alloc(type, 0);
if (bo == NULL) {
PyRegion_RemoveLocalRef(it);
Py_DECREF(it);
return NULL;
}
bo->batch_size = n;
if(PyRegion_TakeRef(bo, it)) {
PyRegion_RemoveLocalRef(bo);
PyRegion_RemoveLocalRef(it);
Py_DECREF(bo);
Py_DECREF(it);
return NULL;
}
bo->it = it;
bo->strict = (bool) strict;
return (PyObject *)bo;
Expand All @@ -172,8 +180,10 @@ batched_dealloc(PyObject *op)
batchedobject *bo = batchedobject_CAST(op);
PyTypeObject *tp = Py_TYPE(bo);
PyObject_GC_UnTrack(bo);
PyRegion_RemoveRef(bo, bo->it);
Py_XDECREF(bo->it);
tp->tp_free(bo);
PyRegion_RemoveLocalRef(tp);
Py_DECREF(tp);
}

Expand Down Expand Up @@ -220,8 +230,9 @@ batched_next(PyObject *op)
/* Input raised an exception other than StopIteration */
FT_ATOMIC_STORE_SSIZE_RELAXED(bo->batch_size, -1);
#ifndef Py_GIL_DISABLED
Py_CLEAR(bo->it);
PyRegion_CLEAR(bo, bo->it);
#endif
PyRegion_RemoveLocalRef(result);
Py_DECREF(result);
return NULL;
}
Expand All @@ -230,16 +241,18 @@ batched_next(PyObject *op)
if (i == 0) {
FT_ATOMIC_STORE_SSIZE_RELAXED(bo->batch_size, -1);
#ifndef Py_GIL_DISABLED
Py_CLEAR(bo->it);
PyRegion_CLEAR(bo, bo->it);
#endif
PyRegion_RemoveLocalRef(result);
Py_DECREF(result);
return NULL;
}
if (bo->strict) {
FT_ATOMIC_STORE_SSIZE_RELAXED(bo->batch_size, -1);
#ifndef Py_GIL_DISABLED
Py_CLEAR(bo->it);
PyRegion_CLEAR(bo, bo->it);
#endif
PyRegion_RemoveLocalRef(result);
Py_DECREF(result);
PyErr_SetString(PyExc_ValueError, "batched(): incomplete batch");
return NULL;
Expand Down Expand Up @@ -305,13 +318,22 @@ pairwise_new_impl(PyTypeObject *type, PyObject *iterable)
}
po = (pairwiseobject *)type->tp_alloc(type, 0);
if (po == NULL) {
PyRegion_RemoveLocalRef(it);
Py_DECREF(it);
return NULL;
}
if(PyRegion_TakeRef(po, it)) {
PyRegion_RemoveLocalRef(po);
PyRegion_RemoveLocalRef(it);
Py_DECREF(po);
Py_DECREF(it);
return NULL;
}
po->it = it;
po->old = NULL;
po->result = PyTuple_Pack(2, Py_None, Py_None);
if (po->result == NULL) {
PyRegion_RemoveLocalRef(po);
Py_DECREF(po);
return NULL;
}
Expand All @@ -324,10 +346,14 @@ pairwise_dealloc(PyObject *op)
pairwiseobject *po = pairwiseobject_CAST(op);
PyTypeObject *tp = Py_TYPE(po);
PyObject_GC_UnTrack(po);
PyRegion_RemoveRef(po, po->it);
PyRegion_RemoveRef(po, po->old);
PyRegion_RemoveRef(po, po->result);
Py_XDECREF(po->it);
Py_XDECREF(po->old);
Py_XDECREF(po->result);
tp->tp_free(po);
PyRegion_RemoveLocalRef(tp);
Py_DECREF(tp);
}

Expand All @@ -348,57 +374,106 @@ pairwise_next(PyObject *op)
pairwiseobject *po = pairwiseobject_CAST(op);
PyObject *it = po->it;
PyObject *old = po->old;
PyObject *new, *result;
PyObject *new;
PyObject *result = po->result;

if (it == NULL) {
return NULL;
}
if (old == NULL) {
old = (*Py_TYPE(it)->tp_iternext)(it);
Py_XSETREF(po->old, old);
if(PyRegion_XSETREF(po, po->old, old)) {
return NULL;
}
// Py_XSETREF(po->old, old);
if (old == NULL) {
Py_CLEAR(po->it);
PyRegion_CLEAR(po, po->it);
return NULL;
}
it = po->it;
if (it == NULL) {
Py_CLEAR(po->old);
PyRegion_CLEAR(po, po->old);
return NULL;
}
}
PyRegion_AddLocalRef(old);
Py_INCREF(old);
new = (*Py_TYPE(it)->tp_iternext)(it);
if (new == NULL) {
Py_CLEAR(po->it);
Py_CLEAR(po->old);
PyRegion_CLEAR(po, po->it);
PyRegion_CLEAR(po, po->old);
PyRegion_RemoveLocalRef(old);
Py_DECREF(old);
return NULL;
}

result = po->result;
if (Py_REFCNT(result) == 1) {
Py_INCREF(result);
PyObject *last_old = PyTuple_GET_ITEM(result, 0);
PyObject *last_new = PyTuple_GET_ITEM(result, 1);
PyTuple_SET_ITEM(result, 0, Py_NewRef(old));
PyTuple_SET_ITEM(result, 1, Py_NewRef(new));
Py_DECREF(last_old);
Py_DECREF(last_new);
// bpo-42536: The GC may have untracked this result tuple. Since we're
// recycling it, make sure it's tracked again:
_PyTuple_Recycle(result);
if(result != NULL) {
if (Py_REFCNT(result) == 1 && PyRegion_IsLocal(result)) {
if(PyRegion_AddLocalRef(result)) {
PyRegion_RemoveLocalRef(old);
PyRegion_RemoveLocalRef(new);
Py_DECREF(old);
Py_DECREF(new);
return NULL;
}
Py_INCREF(result);
PyObject *last_old = PyTuple_GET_ITEM(result, 0);
PyObject *last_new = PyTuple_GET_ITEM(result, 1);
PyObject *old_region = PyRegion_NewRef(old);
PyObject *new_region = PyRegion_NewRef(new);
if(PyRegion_TakeRefs(result, old_region, new_region)) {
PyRegion_RemoveLocalRef(old_region);
PyRegion_RemoveLocalRef(new_region);
Py_DECREF(old_region);
Py_DECREF(new_region);
PyRegion_RemoveLocalRef(result);
Py_DECREF(result);
return NULL;
}
PyTuple_SET_ITEM(result, 0, old_region);
PyTuple_SET_ITEM(result, 1, new_region);
PyRegion_RemoveLocalRef(last_old);
Py_DECREF(last_old);
PyRegion_RemoveLocalRef(last_new);
Py_DECREF(last_new);
// bpo-42536: The GC may have untracked this result tuple. Since we're
// recycling it, make sure it's tracked again:
_PyTuple_Recycle(result);
goto end;
}
else {
PyRegion_CLEAR(po, po->result);
}
}
else {
result = PyTuple_New(2);
if (result != NULL) {
PyTuple_SET_ITEM(result, 0, Py_NewRef(old));
PyTuple_SET_ITEM(result, 1, Py_NewRef(new));

result = PyTuple_New(2);
if (result != NULL) {
PyObject *old_region = PyRegion_NewRef(old);
PyObject *new_region = PyRegion_NewRef(new);
if(PyRegion_TakeRefs(result, old_region, new_region)) {
PyRegion_RemoveLocalRef(old_region);
PyRegion_RemoveLocalRef(new_region);
Py_DECREF(old_region);
Py_DECREF(new_region);
PyRegion_RemoveLocalRef(result);
Py_DECREF(result);
return NULL;
}
PyTuple_SET_ITEM(result, 0, old_region);
PyTuple_SET_ITEM(result, 1, new_region);
goto end;
}

Py_XSETREF(po->old, new);
Py_DECREF(old);
return result;
end:
if(PyRegion_XSETREF(po, po->old, new)) {
PyRegion_RemoveLocalRef(new);
Py_DECREF(new);
return NULL;
}
// Py_XSETREF(po->old, new);
PyRegion_RemoveLocalRef(old);
Py_DECREF(old);
return result;
}

static PyType_Slot pairwise_slots[] = {
Expand Down Expand Up @@ -4004,6 +4079,28 @@ static int
itertoolsmodule_clear(PyObject *mod)
{
itertools_state *state = get_module_state(mod);
PyRegion_RemoveLocalRef(state->accumulate_type);
PyRegion_RemoveLocalRef(state->batched_type);
PyRegion_RemoveLocalRef(state->chain_type);
PyRegion_RemoveLocalRef(state->combinations_type);
PyRegion_RemoveLocalRef(state->compress_type);
PyRegion_RemoveLocalRef(state->count_type);
PyRegion_RemoveLocalRef(state->cwr_type);
PyRegion_RemoveLocalRef(state->cycle_type);
PyRegion_RemoveLocalRef(state->dropwhile_type);
PyRegion_RemoveLocalRef(state->filterfalse_type);
PyRegion_RemoveLocalRef(state->groupby_type);
PyRegion_RemoveLocalRef(state->_grouper_type);
PyRegion_RemoveLocalRef(state->islice_type);
PyRegion_RemoveLocalRef(state->pairwise_type);
PyRegion_RemoveLocalRef(state->permutations_type);
PyRegion_RemoveLocalRef(state->product_type);
PyRegion_RemoveLocalRef(state->repeat_type);
PyRegion_RemoveLocalRef(state->starmap_type);
PyRegion_RemoveLocalRef(state->takewhile_type);
PyRegion_RemoveLocalRef(state->tee_type);
PyRegion_RemoveLocalRef(state->teedataobject_type);
PyRegion_RemoveLocalRef(state->ziplongest_type);
Py_CLEAR(state->accumulate_type);
Py_CLEAR(state->batched_type);
Py_CLEAR(state->chain_type);
Expand Down
15 changes: 14 additions & 1 deletion Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,7 @@ PyNumber_Add(PyObject *v, PyObject *w)
if (result != Py_NotImplemented) {
return result;
}
assert(PyRegion_IsLocal(result));
Py_DECREF(result);

PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence;
Expand Down Expand Up @@ -1466,7 +1467,14 @@ _PyNumber_Index(PyObject *item)
}

if (PyLong_Check(item)) {
return Py_NewRef(item);
// PyRegion_AddLocalRef(item); // Can Fail
/*
if (PyRegion_AddLocalRef(item)) {
return NULL;
}
return Py_NewRef(item);
*/
return PyRegion_NewRef(item);
}
if (!_PyIndex_Check(item)) {
PyErr_Format(PyExc_TypeError,
Expand Down Expand Up @@ -1508,6 +1516,7 @@ PyObject *
PyNumber_Index(PyObject *item)
{
PyObject *result = _PyNumber_Index(item);
// For subclass handling
if (result != NULL && !PyLong_CheckExact(result)) {
Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));
}
Expand Down Expand Up @@ -1562,6 +1571,7 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err)
}

finish:
PyRegion_RemoveLocalRef(value);
Py_DECREF(value);
return result;
}
Expand Down Expand Up @@ -2257,6 +2267,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
}

cmp = PyObject_RichCompareBool(item, obj, Py_EQ);
PyRegion_RemoveLocalRef(item);
Py_DECREF(item);
if (cmp < 0)
goto Fail;
Expand Down Expand Up @@ -2305,6 +2316,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
n = -1;
/* fall through */
Done:
PyRegion_RemoveLocalRef(it);
Py_DECREF(it);
return n;

Expand Down Expand Up @@ -2911,6 +2923,7 @@ PyObject_GetIter(PyObject *o)
PyErr_Format(PyExc_TypeError,
"%T.__iter__() must return an iterator, not %T",
o, res);
// ASK FRED: NO BARRIER NEEDED here, right?
Py_SETREF(res, NULL);
}
return res;
Expand Down
Loading