Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-101892: Fix SystemError when a callable iterator call exhausts the iterator #101896

Merged
merged 19 commits into from
Mar 4, 2023

Conversation

workingpayload
Copy link
Contributor

@workingpayload workingpayload commented Feb 14, 2023

Updated Cython/objects/iterobject.c Line 217

Updated Cython/objects/iterobject.c Line 217
@arhadthedev arhadthedev added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Feb 14, 2023
@Eclips4
Copy link
Member

Eclips4 commented Feb 14, 2023

It's good to coverage this case in tests.

@arhadthedev
Copy link
Member

Added a test copied from the issue with readability changes.

@@ -214,7 +214,7 @@ calliter_iternext(calliterobject *it)
}

result = _PyObject_CallNoArgs(it->it_callable);
if (result != NULL) {
if (result != NULL && it->it_callable != NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but this won't fix it. Notice the first if statement in the function. If it->it_callable == NULL is true, NULL is returned. So it->it_callable != NULL is already guaranteed at this point.

Copy link
Contributor Author

@workingpayload workingpayload Feb 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we check it->it_sentinel != NULL ?

Copy link
Contributor

@OTheDev OTheDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like NULL is being passed to PyObject_RichCompareBool() through it->it_sentinel when it expects an object?

If we add the check

if (result != NULL && it->it_sentinel != NULL) {

and get rid of that Py_DECREF(result) and place a new

Py_XDECREF(result);

just before return NULL;

Then the code in the issue will raise a StopIteration (no longer SystemError) and tests pass.

I'm not entirely sure if this is correct, TBH, but this is my guess.

return NO_MORE
spam.need_reentrance = True
spam.iterator = iter(spam, NO_MORE)
next(spam.iterator)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the expected behaviour here? StopIteration?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for noticing the oversight! Fixed.

@OTheDev
Copy link
Contributor

OTheDev commented Feb 15, 2023

@workingpayload What do you think? Worth a try?

@workingpayload
Copy link
Contributor Author

@workingpayload What do you think? Worth a try?

Yeah! Why not?

def spam():
if spam.need_reentrance:
spam.need_reentrance = False
list(spam.iterator) # Implicitly call ourselves
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This evening (after getting access to my dev machine) I'll check whether the inner list() is required to throw StopIteration to trigger the bug. If no, I will simplify the test:

Suggested change
list(spam.iterator) # Implicitly call ourselves
try:
list(spam.iterator) # Implicitly call ourselves.
except StopIteration:
pass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it wrong. list() cannot throw an exception because it returns a ready-to-use list (possibly empty) processing StopIteration by itself.

@furkanonder
Copy link
Contributor

LGTM. By the way PR title can be more meaningful. Ex: Fix SystemError when a callable iterator call exhausts the iterator.

Lib/test/test_iter.py Outdated Show resolved Hide resolved
Lib/test/test_iter.py Outdated Show resolved Hide resolved
@arhadthedev
Copy link
Member

@kumaraditya303 Thank you, addressed.

@kumaraditya303 kumaraditya303 added needs backport to 3.10 only security fixes needs backport to 3.11 only security fixes labels Mar 4, 2023
@kumaraditya303 kumaraditya303 merged commit 705487c into python:main Mar 4, 2023
@miss-islington
Copy link
Contributor

Thanks @workingpayload for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.10, 3.11.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Sorry, @workingpayload and @kumaraditya303, I could not cleanly backport this to 3.10 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 705487c6557c3d8866622b4d32528bf7fc2e4204 3.10

@bedevere-bot
Copy link

GH-102418 is a backport of this pull request to the 3.11 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label Mar 4, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 4, 2023
…usts the iterator (pythonGH-101896)

(cherry picked from commit 705487c)

Co-authored-by: Raj <[email protected]>
Co-authored-by: Oleg Iarygin <[email protected]>
miss-islington added a commit that referenced this pull request Mar 4, 2023
…he iterator (GH-101896)

(cherry picked from commit 705487c)

Co-authored-by: Raj <[email protected]>
Co-authored-by: Oleg Iarygin <[email protected]>
arhadthedev pushed a commit to arhadthedev/cpython that referenced this pull request Mar 4, 2023
…usts the iterator (python#101896)

Co-authored-by: Oleg Iarygin <[email protected]>
(cherry picked from commit 705487c)
@bedevere-bot
Copy link

GH-102422 is a backport of this pull request to the 3.10 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.10 only security fixes label Mar 4, 2023
kumaraditya303 pushed a commit that referenced this pull request Mar 4, 2023
…austs the iterator (GH-101896) (#102422)

gh-101892: Fix `SystemError` when a callable iterator call exhausts the iterator (#101896)

Co-authored-by: Oleg Iarygin <[email protected]>
(cherry picked from commit 705487c)

Co-authored-by: Raj <[email protected]>
@OTheDev
Copy link
Contributor

OTheDev commented Mar 4, 2023

@arhadthedev Thanks for the continued work on this!

@workingpayload workingpayload deleted the workingpayload/issue101892 branch March 5, 2023 07:42
hugovk pushed a commit to hugovk/cpython that referenced this pull request Mar 6, 2023
carljm added a commit to carljm/cpython that referenced this pull request Mar 6, 2023
* main: (21 commits)
  pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives in sub interpreters module (python#102472)
  pythongh-95672: Fix versionadded indentation of get_pagesize in test.rst (pythongh-102455)
  pythongh-102416: Do not memoize incorrectly loop rules in the parser (python#102467)
  pythonGH-101362: Optimise PurePath(PurePath(...)) (pythonGH-101667)
  pythonGH-101362: Check pathlib.Path flavour compatibility at import time (pythonGH-101664)
  pythonGH-101362: Call join() only when >1 argument supplied to pathlib.PurePath() (python#101665)
  pythongh-102444: Fix minor bugs in `test_typing` highlighted by pyflakes (python#102445)
  pythonGH-102341: Improve the test function for pow (python#102342)
  Fix unused classes in a typing test (pythonGH-102437)
  pythongh-101979: argparse: fix a bug where parentheses in metavar argument of add_argument() were dropped (python#102318)
  pythongh-102356: Add thrashcan macros to filter object dealloc (python#102426)
  Move around example in to_bytes() to avoid confusion (python#101595)
  pythonGH-97546: fix flaky asyncio `test_wait_for_race_condition` test (python#102421)
  pythongh-96821: Add config option `--with-strict-overflow` (python#96823)
  pythongh-101992: update pstlib module documentation (python#102133)
  pythongh-63301: Set exit code when tabnanny CLI exits on error (python#7699)
  pythongh-101863: Fix wrong comments in EUC-KR codec (pythongh-102417)
  pythongh-102302 Micro-optimize `inspect.Parameter.__hash__` (python#102303)
  pythongh-102179: Fix `os.dup2` error reporting for negative fds (python#102180)
  pythongh-101892: Fix `SystemError` when a callable iterator call exhausts the iterator (python#101896)
  ...
carljm added a commit to carljm/cpython that referenced this pull request Mar 7, 2023
* main: (37 commits)
  pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives in sub interpreters module (python#102472)
  pythongh-95672: Fix versionadded indentation of get_pagesize in test.rst (pythongh-102455)
  pythongh-102416: Do not memoize incorrectly loop rules in the parser (python#102467)
  pythonGH-101362: Optimise PurePath(PurePath(...)) (pythonGH-101667)
  pythonGH-101362: Check pathlib.Path flavour compatibility at import time (pythonGH-101664)
  pythonGH-101362: Call join() only when >1 argument supplied to pathlib.PurePath() (python#101665)
  pythongh-102444: Fix minor bugs in `test_typing` highlighted by pyflakes (python#102445)
  pythonGH-102341: Improve the test function for pow (python#102342)
  Fix unused classes in a typing test (pythonGH-102437)
  pythongh-101979: argparse: fix a bug where parentheses in metavar argument of add_argument() were dropped (python#102318)
  pythongh-102356: Add thrashcan macros to filter object dealloc (python#102426)
  Move around example in to_bytes() to avoid confusion (python#101595)
  pythonGH-97546: fix flaky asyncio `test_wait_for_race_condition` test (python#102421)
  pythongh-96821: Add config option `--with-strict-overflow` (python#96823)
  pythongh-101992: update pstlib module documentation (python#102133)
  pythongh-63301: Set exit code when tabnanny CLI exits on error (python#7699)
  pythongh-101863: Fix wrong comments in EUC-KR codec (pythongh-102417)
  pythongh-102302 Micro-optimize `inspect.Parameter.__hash__` (python#102303)
  pythongh-102179: Fix `os.dup2` error reporting for negative fds (python#102180)
  pythongh-101892: Fix `SystemError` when a callable iterator call exhausts the iterator (python#101896)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants