Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Dec 24, 2025

Summary by CodeRabbit

  • Refactor

    • Consolidated iteration method handling for improved consistency and maintainability.
    • Streamlined iteration protocol implementation to better align with Python's standard behavior.
  • Bug Fixes

    • Enhanced error handling for iteration operations to ensure proper validation of method arguments.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

This pull request refactors iteration support in RustPython by moving __iter__ and __next__ implementations from trait methods to the slot wrapper mechanism. It introduces Iter and IterNext variants to the SlotFunc enum, adds a generic macro for unified slot wrapper insertion, and removes redundant trait method implementations.

Changes

Cohort / File(s) Summary
Slot wrapper extension for iteration
crates/vm/src/builtins/descriptor.rs
Added Iter(IterFunc) and IterNext(IterNextFunc) variants to SlotFunc enum. Updated Debug implementation with new variants. Extended SlotFunc::call method to handle iteration slots: validates no arguments are passed for __iter__ and __next__, invokes underlying functions, and converts IterNext results via to_pyresult(vm). Imported ToPyResult and type aliases for iteration function support.
Class slot wrapper insertion
crates/vm/src/class.rs
Introduced add_slot_wrapper macro to generically create and insert slot wrappers for __init__, __repr__, __iter__, and __next__. Retained special handling for __hash__ to set None when hash is not implemented. Consolidates slot wrapper insertion logic into uniform pattern aligned with CPython's behavior.
Trait implementation refactoring
crates/vm/src/types/slot.rs
Removed explicit __iter__ method from Iterable trait and __next__ method from IterNext trait. Removed default implementations delegating to slot_iter and slot_iternext. Added comments indicating these methods are now exposed via SlotFunc wrapper mechanism. Removed ToPyResult import, retaining only ToPyObject.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • __hash__ to slot_wrapper #6480: Modifies the same slot-wrapper infrastructure (SlotFunc enum and dispatch logic in descriptor.rs) with this PR extending it by adding Iter/IterNext variants to the existing mechanism.
  • Introduce slot wrapper to __init__  #4884: Earlier work on the slot-wrapper machinery introducing PySlotWrapper and method-wrapper pattern that this PR builds upon with the generic add_slot_wrapper macro.

Suggested reviewers

  • ShaharNaveh

Poem

🐰 Iteration flows through slots so neat,
No traits needed, macro's sweet!
iter wraps with next in tow,
Unified wrapper steals the show!
Hopping forward, code runs tight,

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main change: adding iteration slot support (iter and next) via slot-wrapper mechanism across descriptor.rs, class.rs, and types/slot.rs.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@youknowone youknowone marked this pull request as ready for review December 24, 2025 13:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2a7393 and 47fcdd9.

📒 Files selected for processing (3)
  • crates/vm/src/builtins/descriptor.rs
  • crates/vm/src/class.rs
  • crates/vm/src/types/slot.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust

Files:

  • crates/vm/src/builtins/descriptor.rs
  • crates/vm/src/types/slot.rs
  • crates/vm/src/class.rs
🧠 Learnings (3)
📓 Common learnings
Learnt from: jackoconnordev
Repo: RustPython/RustPython PR: 6086
File: benches/microbenchmarks/sort.py:1-3
Timestamp: 2025-08-09T22:56:24.527Z
Learning: In RustPython's microbenchmarks (benches/microbenchmarks/*.py), the variable `ITERATIONS` is intentionally used without being defined in the Python files. It is injected by the cargo bench harness at runtime. This pattern should be maintained for consistency across all microbenchmarks, and F821 lint warnings for undefined `ITERATIONS` are expected and acceptable in this context.
📚 Learning: 2025-08-09T22:56:24.527Z
Learnt from: jackoconnordev
Repo: RustPython/RustPython PR: 6086
File: benches/microbenchmarks/sort.py:1-3
Timestamp: 2025-08-09T22:56:24.527Z
Learning: In RustPython's microbenchmarks (benches/microbenchmarks/*.py), the variable `ITERATIONS` is intentionally used without being defined in the Python files. It is injected by the cargo bench harness at runtime. This pattern should be maintained for consistency across all microbenchmarks, and F821 lint warnings for undefined `ITERATIONS` are expected and acceptable in this context.

Applied to files:

  • crates/vm/src/builtins/descriptor.rs
📚 Learning: 2025-11-29T12:17:28.606Z
Learnt from: CR
Repo: RustPython/RustPython PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T12:17:28.606Z
Learning: Applies to **/*.rs : Use the macro system (`pyclass`, `pymodule`, `pyfunction`, etc.) when implementing Python functionality in Rust

Applied to files:

  • crates/vm/src/builtins/descriptor.rs
🧬 Code graph analysis (2)
crates/vm/src/builtins/descriptor.rs (2)
crates/vm/src/types/slot.rs (1)
  • obj (1335-1336)
crates/vm/src/builtins/type.rs (3)
  • obj (221-221)
  • obj (639-639)
  • obj (1089-1089)
crates/vm/src/class.rs (1)
crates/vm/src/vm/context.rs (1)
  • intern_str (353-355)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
🔇 Additional comments (10)
crates/vm/src/class.rs (2)

142-159: Macro consolidation looks good.

The add_slot_wrapper! macro effectively consolidates repetitive slot wrapper logic, mirroring CPython's add_operators() pattern. The logic correctly checks for slot existence and prevents overwriting existing attributes.


171-187: Special handling for __hash__ is correct.

The code properly distinguishes between hash_not_implemented (which sets __hash__ = None) and regular hash functions (which get wrapped). This matches Python semantics for unhashable types.

crates/vm/src/builtins/descriptor.rs (4)

7-7: LGTM!

The ToPyResult import is correctly added for use in line 459's to_pyresult(vm) call.


10-11: LGTM!

The IterFunc and IterNextFunc imports are necessary for the new SlotFunc::Iter and SlotFunc::IterNext variants.


403-404: LGTM!

The new Iter and IterNext variants correctly extend the SlotFunc enum with appropriate function pointer types, following the established pattern.


445-460: LGTM!

The call handling for Iter and IterNext is correctly implemented:

  • Both validate that no arguments are passed (beyond self)
  • Iter returns PyResult directly from the underlying function
  • IterNext properly converts PyIterReturn to PyResult using to_pyresult(vm) to handle StopIteration

The error messages match CPython's format.

crates/vm/src/types/slot.rs (4)

9-9: LGTM!

The ToPyResult import has been appropriately moved to descriptor.rs where it's actually used, keeping imports minimal in this file.


1438-1438: LGTM!

The comment correctly documents that __iter__ is now exposed through the slot wrapper mechanism rather than as a trait method.


1458-1458: LGTM!

The comment correctly documents that __next__ is now exposed through the slot wrapper mechanism rather than as a trait method.


1473-1473: LGTM!

The comment correctly documents that __iter__ is now exposed through the slot wrapper mechanism for the SelfIter implementation.

Comment on lines +161 to +169
add_slot_wrapper!(
init,
__init__,
Init,
"Initialize self. See help(type(self)) for accurate signature."
);
add_slot_wrapper!(repr, __repr__, Repr, "Return repr(self).");
add_slot_wrapper!(iter, __iter__, Iter, "Implement iter(self).");
add_slot_wrapper!(iternext, __next__, IterNext, "Implement next(self).");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for trait method implementations of __iter__ and __next__
# that might not have been migrated to the slot wrapper system

echo "=== Searching for #[pymethod] __iter__ implementations ==="
rg -n '#\[pymethod\]' -A 1 | grep -A 1 'fn __iter__'

echo ""
echo "=== Searching for #[pymethod] __next__ implementations ==="
rg -n '#\[pymethod\]' -A 1 | grep -A 1 'fn __next__'

echo ""
echo "=== Checking for trait Iterable implementations ==="
rg -n 'impl.*Iterable for' -A 5

echo ""
echo "=== Checking for trait IterNext implementations ==="
rg -n 'impl.*IterNext for' -A 5

Repository: RustPython/RustPython

Length of output: 38232


🏁 Script executed:

# Also search for SlotFunc enum to verify Iter and IterNext variants exist
echo "=== Searching for SlotFunc enum definition ==="
rg -n 'enum SlotFunc' -A 30

Repository: RustPython/RustPython

Length of output: 2468


🏁 Script executed:

# Check for any __iter__ or __next__ in the entire codebase to get full picture
echo "=== All __iter__ references ==="
rg -n '__iter__' crates/vm/src/

echo ""
echo "=== All __next__ references ==="
rg -n '__next__' crates/vm/src/

Repository: RustPython/RustPython

Length of output: 2088


Address the #[pymethod] __iter__ implementation in contextvars.rs that uses a separate approach.

The slot wrappers are correctly added for __iter__ and __next__ in the class machinery. However, a #[pymethod] fn __iter__ exists at crates/stdlib/src/contextvars.rs:211. Consider whether this should also be migrated to the slot wrapper system to maintain consistency with the new approach, or if keeping the trait-based method is intentional.

@youknowone youknowone merged commit cbde5ce into RustPython:main Dec 24, 2025
13 checks passed
@youknowone youknowone deleted the slot-iter branch December 24, 2025 14:35
@coderabbitai coderabbitai bot mentioned this pull request Dec 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant