diff --git a/tests/snippets/builtin_range.py b/tests/snippets/builtin_range.py index 667e776a2..755a5e227 100644 --- a/tests/snippets/builtin_range.py +++ b/tests/snippets/builtin_range.py @@ -61,3 +61,4 @@ assert 'foo' not in range(10) # __reversed__ assert list(reversed(range(5))) == [4, 3, 2, 1, 0] assert list(reversed(range(5, 0, -1))) == [1, 2, 3, 4, 5] +assert list(reversed(range(1,10,5))) == [6, 1] diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index 221e98da5..abc6e84ab 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -95,14 +95,23 @@ impl RangeType { #[inline] pub fn reversed(&self) -> Self { + // compute the last element that is actually contained within the range + // this is the new start + let remainder = ((&self.end - &self.start) % &self.step).abs(); + let start = if remainder.is_zero() { + &self.end - &self.step + } else { + &self.end - &remainder + }; + match self.step.sign() { Sign::Plus => RangeType { - start: &self.end - 1, + start, end: &self.start - 1, step: -&self.step, }, Sign::Minus => RangeType { - start: &self.end + 1, + start, end: &self.start + 1, step: -&self.step, },