Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Lib/test/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,17 @@ def check(start, stop, step=None):
check(0, -1)
check(-1, -3, -1)

for test in (range(5), range(0), range(1, 10, 2), range(10, 0, -1), range(-1, 200, 1)):
with self.subTest(test=test):
self.assertIs(test, test[:])
self.assertIs(test, test[:len(test):])
self.assertIs(test, test[0:len(test):1])

if len(test) > 1:
self.assertIsNot(test, test[1:len(test):2])
self.assertIsNot(test, test[1:])
self.assertIsNot(test, test[:-1])

def test_contains(self):
r = range(10)
self.assertIn(0, r)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:func:`range` slicing with ``[:]`` and ``[:len(r):]`` no longer creates a copy,
it now returns the same object, consistent with :func:`copy.copy`.
7 changes: 7 additions & 0 deletions Objects/rangeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,13 @@ compute_slice(rangeobject *r, PyObject *_slice)
if (error == -1)
return NULL;

if (start == _PyLong_GetZero()
&& step == _PyLong_GetOne()
&& (slice->stop == Py_None || PyObject_RichCompareBool(stop, r->length, Py_EQ) == 1))
{
return Py_NewRef(r);
}
Comment on lines +416 to +421
Copy link
Member

@picnixz picnixz Oct 5, 2025

Choose a reason for hiding this comment

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

PyObject_RichCompareBool can raise an error. Handling it would then make the code more complex. So I'm rather against that change as it's not so trivial.

Also, start == _PyLong_GetZero() is not correct because it's not guaranteed that 0 will always be immortal (though it should in general and I see that there is code that is doing this for 1). I actually thought that we had the indices as C integers and not Python ones, but it appears that it's not the case.


substep = PyNumber_Multiply(r->step, step);
if (substep == NULL) goto fail;
Py_CLEAR(step);
Expand Down
Loading