Skip to content

Commit

Permalink
Address code review
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 committed Feb 8, 2024
1 parent 61362aa commit a93faf6
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 71 deletions.
27 changes: 15 additions & 12 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1727,19 +1727,22 @@ def _check_tracemalloc():


def check_free_after_iterating(test, iter, cls, args=()):
class A(cls):
def __del__(self):
nonlocal done
done = True
try:
next(it)
except StopIteration:
pass

done = False
it = iter(A(*args))
# Issue 26494: Shouldn't crash
test.assertRaises(StopIteration, next, it)
def wrapper():
class A(cls):
def __del__(self):
nonlocal done
done = True
try:
next(it)
except StopIteration:
pass

it = iter(A(*args))
# Issue 26494: Shouldn't crash
test.assertRaises(StopIteration, next, it)

wrapper()
# The sequence should be deallocated just after the end of iterating
gc_collect()
test.assertTrue(done)
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def __eq__(self, other):
# listiter_reduce_general
self.assertEqual(
run("reversed", orig["reversed"](list(range(8)))),
(iter, ([],))
(reversed, ([],))
)

for case in types:
Expand Down
83 changes: 33 additions & 50 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3392,34 +3392,29 @@ static PyObject *
listiter_next(PyObject *self)
{
_PyListIterObject *it = (_PyListIterObject *)self;
PyListObject *seq;
PyObject *item;

assert(it != NULL);
seq = it->it_seq;
if (seq == NULL)
Py_ssize_t index = LOAD_SSIZE(it->it_index);
if (index < 0) {
return NULL;
assert(PyList_Check(seq));

if (it->it_index < PyList_GET_SIZE(seq)) {
item = PyList_GET_ITEM(seq, it->it_index);
++it->it_index;
return Py_NewRef(item);
}

it->it_seq = NULL;
Py_DECREF(seq);
return NULL;
PyObject *item = list_get_item_ref(it->it_seq, index);
if (item == NULL) {
// out-of-bounds
STORE_SSIZE(it->it_index, -1);
return NULL;
}
STORE_SSIZE(it->it_index, index + 1);
return item;
}

static PyObject *
listiter_len(PyObject *self, PyObject *Py_UNUSED(ignored))
{
assert(self != NULL);
_PyListIterObject *it = (_PyListIterObject *)self;
Py_ssize_t len;
Py_ssize_t index = LOAD_SSIZE(it->it_index);
if (it->it_seq) {
len = PyList_GET_SIZE(it->it_seq) - index;
if (index >= 0) {
Py_ssize_t len = PyList_GET_SIZE(it->it_seq) - index;
if (len >= 0)
return PyLong_FromSsize_t(len);
}
Expand All @@ -3440,8 +3435,8 @@ listiter_setstate(PyObject *self, PyObject *state)
if (index == -1 && PyErr_Occurred())
return NULL;
if (it->it_seq != NULL) {
if (index < 0)
index = 0;
if (index < -1)
index = -1;
else if (index > PyList_GET_SIZE(it->it_seq))
index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */
it->it_index = index;
Expand Down Expand Up @@ -3546,35 +3541,30 @@ static PyObject *
listreviter_next(PyObject *self)
{
listreviterobject *it = (listreviterobject *)self;
PyObject *item;
Py_ssize_t index;
PyListObject *seq;

assert(it != NULL);
seq = it->it_seq;
if (seq == NULL) {
return NULL;
}
PyListObject *seq = it->it_seq;
assert(PyList_Check(seq));

index = LOAD_SSIZE(it->it_index);
Py_ssize_t index = LOAD_SSIZE(it->it_index);
if (index>=0 && index < PyList_GET_SIZE(seq)) {
item = PyList_GET_ITEM(seq, index);
it->it_index--;
return Py_NewRef(item);
PyObject *item = list_get_item_ref(seq, index);
if (item != NULL) {
STORE_SSIZE(it->it_index, index - 1);
return item;
}
}
STORE_SSIZE(it->it_index, -1);
it->it_seq = NULL;
Py_DECREF(seq);
return NULL;
}

static PyObject *
listreviter_len(PyObject *self, PyObject *Py_UNUSED(ignored))
{
listreviterobject *it = (listreviterobject *)self;
Py_ssize_t len = it->it_index + 1;
if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)
Py_ssize_t index = LOAD_SSIZE(it->it_index);
Py_ssize_t len;
STORE_SSIZE(len, index + 1);
if (PyList_GET_SIZE(it->it_seq) < len)
len = 0;
return PyLong_FromSsize_t(len);
}
Expand Down Expand Up @@ -3608,36 +3598,29 @@ static PyObject *
listiter_reduce_general(void *_it, int forward)
{
PyObject *list;
PyObject *iter;

/* _PyEval_GetBuiltin can invoke arbitrary code,
* call must be before access of iterator pointers.
* see issue #101765 */

/* the objects are not the same, index is of different types! */
if (forward) {
PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
if (!iter) {
return NULL;
}
iter = _PyEval_GetBuiltin(&_Py_ID(iter));
_PyListIterObject *it = (_PyListIterObject *)_it;
if (it->it_seq) {
if (it->it_index >= 0) {
return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
}
Py_DECREF(iter);
} else {
PyObject *reversed = _PyEval_GetBuiltin(&_Py_ID(reversed));
if (!reversed) {
return NULL;
}
iter = _PyEval_GetBuiltin(&_Py_ID(reversed));
listreviterobject *it = (listreviterobject *)_it;
if (it->it_seq) {
return Py_BuildValue("N(O)n", reversed, it->it_seq, it->it_index);
if (it->it_index >= 0) {
return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
}
Py_DECREF(reversed);
}
/* empty iterator, create an empty list */
list = PyList_New(0);
if (list == NULL)
return NULL;
return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
return Py_BuildValue("N(N)", iter, list);
}
5 changes: 1 addition & 4 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2615,10 +2615,7 @@ dummy_func(
STAT_INC(FOR_ITER, hit);
PyListObject *seq = it->it_seq;
if (seq == NULL || it->it_index >= PyList_GET_SIZE(seq)) {
if (seq != NULL) {
it->it_seq = NULL;
Py_DECREF(seq);
}
it->it_index = -1;
Py_DECREF(iter);
STACK_SHRINK(1);
/* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
Expand Down
5 changes: 1 addition & 4 deletions Python/generated_cases.c.h

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

0 comments on commit a93faf6

Please sign in to comment.