fix(python): match Python range semantics for empty and descending ranges - #9781
fix(python): match Python range semantics for empty and descending ranges#9781jackylee-ch wants to merge 2 commits into
Conversation
…nges `range_len` reports a range whose bounds coincide as `Some(0)`, which fell through to `Sequence`, and that encoding requires at least one element. Route every empty range to the primitive-array path instead. Inferring the dtype from the bounds alone chose `U64` for a descending range, so the negative step no longer fit. Move the inference next to `range_len` as `range_ptype` and require a positive step for the unsigned choice. Signed-off-by: jackylee-ch <qcsd2011@gmail.com>
|
Thank you @jackylee-ch! Do you mind adding a short python-side test here? |
Both shapes raised before this branch, so `test_from_range.py` had no case for either. Names follow the file's existing `<start>_<stop>_<step>` convention, and the descending case compares against Python's own `range`, which is the behaviour being matched. Signed-off-by: jackylee-ch <qcsd2011@gmail.com>
|
Added Left your inline suggestion alone since you'd already resolved it. |
Merging this PR will regress 2 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | random_i16[0.95] |
77.5 µs | 95.8 µs | -19.09% |
| ❌ | WallTime | mul_u32_nonnull_avx512 |
5.5 µs | 6.2 µs | -10.49% |
| ⚡ | WallTime | arrow_checked_add_u32_neon[16384] |
20.5 µs | 12.8 µs | +60.41% |
| ⚡ | Simulation | random_i8[0.8] |
99.2 µs | 69.8 µs | +42.12% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing jackylee-ch:fix/python-range-semantics (ec72623) with develop (dc1b355)
Footnotes
-
206 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
vx.array(range(3, 3))raisesSequenceArray length must be greater than zero, whilerange(10, 3)andrange(0, 10, -1)both return an empty array —test_from_range_invalidalready asserts those two.
range_lenreports coinciding bounds asSome(0)and only theother two shapes as
None, so the third empty shape reachedSequence, which holds at leastone element.
vx.array(range(5, 1, -1))raisesStep, -1, does not fit in requested dtype: u64: theinference read the bounds but not the step. An explicitly requested unsigned dtype still
errors, which
test_sequence_array_from_lenasserts.Tests
cargo test --release -p vortex-python --lib: 31 passed, 21 ondevelop. Restoring the oldempty-range branch fails the three
bounds_coincidecases; droppingstep > 0from theinference fails two more. Tests are Rust-side because
test_from_range.pyis open in #9546.AI assistance
Written with agentic AI assistance; I checked each empty shape against
range_lenby hand.