Rebase range iterator __reduce__ to match CPython - #8424
Draft
devyubin wants to merge 1 commit into
Draft
Conversation
range_iterator.__reduce__ (and longrange_iterator) returned the original range plus the current index as pickle state; CPython returns the range rebased to the current position with a None state. Rebase start by index * step (clamped to the length) and emit None. __setstate__ is kept so pickles carrying an integer state still load. Assisted-by: Claude Code:claude-opus-4-8
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
range_iterator.__reduce__(andlongrange_iterator.__reduce__) returned the original range plus the current index as the pickle state, whereas CPython returns the remaining range rebased to the current position with aNonestate. The round-trip result was already correct on both (RustPython restored the index via__setstate__), so this is a representational / cross-compatibility divergence, not data loss.Cause
range_iter_reduceembedded the full original range and passedindexas the third tuple element. BothPyRangeIterator::__reduce__andPyLongRangeIterator::__reduce__go through it.Fix
Rebase the range start by
index * stepand emitNonefor the state. The index is clamped to the length first, because RustPython's iterator increments the index unconditionally, so it can run past the length after exhaustion (unlike CPython, which stops at the length).__setstate__is left intact, so pickles that carry an integer state still load.Test
Verified against CPython 3.14.6 —
__reduce__output now matches for mid-iteration, fresh,reversed, exhausted (range(2, 2)), step > 1, empty, single-element, negative-step,longrange, and__setstate__-advanced iterators.pickle.loads(pickle.dumps(it))round-trips correctly in all cases.test_range: SUCCESS (29 run, 2 skipped — the two skips are a separate, pre-existing__setstate__crash, unrelated to this change).cargo build/cargo clippy -p rustpython-vm/cargo fmt --check: clean.No
@expectedFailuremarker flips here: CPython's owntest_rangehas no test asserting the__reduce__shape, so this is a representational fix, covered for regressions by the existing pickle round-trip tests.