Repository navigation
Fix RedisDeque.rotate() when abs(n) > len(d) - #857
Merged
brainix merged 1 commit intoOct 10, 2026
Merged
Conversation
Reduce n to the shorter equivalent rotation so rotating past the length wraps like collections.deque.rotate(), instead of slicing with the un-reduced n.
Contributor
Author
|
Hi @brainix - the CI run is sitting at "Action required" (fork PR approval). Could you approve the workflow run so the checks can complete? The change is small: |
Owner
|
Thank you for the contribution! |
Owner
|
By the way, this is the most brilliant pull request I've seen. The only thing that rivals your ability to write code is your ability to explain your reasoning. |
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.
Fixes #849
Problem
RedisDeque.rotate(n) produced a wrong ordering (and, for negative n, even dropped elements) whenever abs(n) exceeded the deque length. collections.deque - which the class documents itself as compatible with - reduces n modulo the length, so rotation wraps; RedisDeque instead sliced and trimmed with the un-reduced n.
Reproduced locally with fakeredis before the fix:
Fix
Reduce n to an equivalent rotation before the existing slice/trim logic, rotating the shorter way to minimize the number of elements pushed (the original code already pushed min(n, len) elements in the base case, so this keeps that):
I did not use the bare n %= len(self) suggested in the issue, because it would turn a small negative rotation into a large positive one - e.g. rotate(-2) on a 10-element deque becomes -2 % 10 == 8, pushing 8 elements instead of 2. The shorter-way normalization keeps the push count at min(n, length), matching the original behavior and avoiding a performance regression. A whole number of turns (n == 0 after reduction) is now an explicit no-op instead of a push+trim round trip.
Tests
Added test_rotate_more_than_length covering abs(n) > len(d) in both directions plus the exact-wrap cases, which the issue notes were not covered. Re-ran the existing rotate tests (invalid steps, zero, empty, right, left) against fakeredis - all pass.
Verified locally: flake8 / isort clean on both touched files; mypy shows no new errors versus master; behavior checked against collections.deque.rotate for n in {1, -1, 3, -3, 4, -4, 6, -6, 7, -7, 10, -10} plus the empty-deque no-op.