Avoid callable iterator deadlock during sentinel comparison (#8011)#8040
Avoid callable iterator deadlock during sentinel comparison (#8011)#8040doma17 wants to merge 2 commits into
Conversation
Constraint: Python-level sentinel equality can re-enter the same callable iterator while internal iterator state is protected by a non-reentrant lock. Rejected: Holding the callable iterator status lock across sentinel equality | user-defined __eq__ can call next() on the same iterator and deadlock. Confidence: high Scope-risk: moderate Tested: pre-commit run --all-files; cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher; cargo build --release --features sqlite; pytest -v in extra_tests; cargo run --quiet -- extra_tests/snippets/protocol_iternext.py; cargo check -p rustpython-vm; cargo clippy -p rustpython-vm --all-targets -- -D warnings; git diff --check Not-tested: push/PR creation Assisted-by: Codex:gpt-5.5
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR fixes a deadlock in ChangesIterator Deadlock Fix and Test Updates
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
iter(callable, sentinel)when__eq__re-enters the same iterator #8011Summary
Fixes a deadlock in
iter(callable, sentinel)when sentinel equality re-entersthe same iterator. The comparison now runs outside the iterator status lock, and
a regression test covers the re-entrant case.
Problem
iter(callable, sentinel)could deadlock when sentinel comparison ran Pythoncode. The outer
next()held the callable iterator status lock while comparingthe callable result with the sentinel. If
__eq__callednext()on the sameiterator, the inner call waited on that same lock forever.
Fixes
re-enter and exhaust the iterator.
iterator needs to be marked exhausted.
Testing
iter(callable, sentinel)when__eq__re-enters the same iterator #8011 no longer hangs and now raisesStopIteration, matching CPython.protocol_iternextregression on both CPython andRustPython.
384 passed.Summary by CodeRabbit
Improvements
Tests