Skip to content

Callable iterator can SystemError if call exhausts the iterator #101892

Description

@ionite34

Bug report

If the callable of a callable iterator (with sentinel) exhausts the iterator itself during the call, a SystemError occurs.

Example discovered by @chilaxan

def bug():
    if bug.clear:
        return 1
    else:
        bug.clear = True
        list(bug.iterator)
        return 0

bug.iterator = iter(bug, 1)
bug.clear = False
next(bug.iterator)
SystemError: Objects\object.c:722: bad argument to internal function

Likely cause

iterobject.calliter_iternext does not check whether it->it_sentinel is NULL after the _PyObject_CallNoArgs call
https://github.com/python/cpython/blob/main/Objects/iterobject.c#L207-L237

static PyObject *
calliter_iternext(calliterobject *it)
{
    PyObject *result;

    if (it->it_callable == NULL) {
        return NULL;
    }

+   result = _PyObject_CallNoArgs(it->it_callable);
    if (result != NULL) {
        int ok;

+       ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
        if (ok == 0) {
            return result; /* Common case, fast path */
        }
(...)

Your environment

Appears to affect 3.7-3.12

Linked PRs

Activity

  1. added a commit that references this issue on Mar 4, 2023
  2. added 2 commits that reference this issue on Mar 4, 2023
  3. added a commit that references this issue on Mar 4, 2023
  4. added a commit that references this issue on Mar 4, 2023
  5. added a commit that references this issue on Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions