Repository navigation
Check enumerate() arguments before calling __iter__ - #9241
Conversation
EnumerateArgs bound the iterable as PyIter, so argument binding called __iter__ before start was converted and before surplus positional arguments were rejected. An exception from __iter__ then replaced the TypeError CPython raises for a bad start or a third argument. Bind the iterable as an object and call get_iter() in py_new, after start is converted, which is the order of CPython's enum_new_impl. Assisted-by: Claude Code:claude-opus-5-5
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bae548e432
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Bound as an object so the other arguments are checked before `iter()` runs, as in CPython. | ||
| #[pyarg(any)] | ||
| iterable: PyIter, | ||
| iterable: PyObjectRef, |
There was a problem hiding this comment.
Defer start conversion until binding validates the call
After only iterable is made raw, a malformed call such as enumerate(BadIter(), RaisingIndex(), extra) reaches ArgIndex::try_from_object for start before FuncArgs::bind_for notices the extra positional argument. It therefore runs and may propagate RaisingIndex.__index__ instead of raising the argument-count TypeError; CPython rejects this call before invoking either __index__ or __iter__. Binding start as an object too, then converting it in py_new immediately before get_iter, preserves the intended valid-call order without this side effect.
Useful? React with 👍 / 👎.
Summary
EnumerateArgsbinds the iterable asPyIter, so argument binding calls__iter__beforestartis converted and before surplus or unknown arguments are rejected. An exception from__iter__then replaces theTypeErrorCPython raises. CPython'senum_new_impl()convertsstartwithPyNumber_Indexbefore it callsPyObject_GetIter.AS-IS
TO-BE
(matching CPython's exception types; the wording of the second message is the shared argument-count message and still differs from CPython's enumerate-specific
enumerate() takes at most 2 arguments (3 given))Changes
iterableasPyObjectRefand callget_iter()inpy_new, afterstartis converted, asitertools.batchedalready does for its iterable.extra_tests/snippets/builtin_enumerate.pywith a badstartby position and by keyword, a third argument, an unknown keyword, and a valid call that still raises from__iter__.Test plan
Built and run on macOS aarch64 against upstream/main 398dd70, using the CI feature set
--no-default-features --features stdlib,importlib,stdio,encodings,sqlite,ssl-rustls-aws-lc,host_env,doc,ucd_3_2_0, plusthreading, compared with CPython 3.14.4.startvalues (by position and keyword), missing, surplus and unknown arguments,__index__,bool,2**70and__reduce__differs from CPython in 7 cases on an unpatched build of that commit and matches in all of them with the patch. It also checks that a rejected call no longer runs__iter__.rustpython -m test test_enumerate test_builtin test_itertools test_iter test_list: 524 run, 56 skipped, all pass.pytest -k "rustpython and builtin"inextra_tests: 71 pass. The extended snippet fails on the unpatched build and passes under CPython 3.14.4.cargo fmt --checkclean,cargo clippy -p rustpython-vm --all-targetsreports nothing, andpre-commit run --filespasses on both changed files.I used Claude Code (claude-opus-5-5) to draft the analysis, the patch and this description; I reviewed the change and ran every command above myself.
Summary by CodeRabbit
enumerateargument validation so invalid argument counts, keywords, and starting values are reported before iteration begins.