Commit 878ce389 authored by Benjamin Peterson's avatar Benjamin Peterson

add introspection to range objects (closes #9896)

Patch by Daniel Urban.
parent 03b08193
...@@ -1042,7 +1042,9 @@ are always available. They are listed here in alphabetical order. ...@@ -1042,7 +1042,9 @@ are always available. They are listed here in alphabetical order.
...]``. If *step* is positive, the last element is the largest ``start + i * ...]``. If *step* is positive, the last element is the largest ``start + i *
step`` less than *stop*; if *step* is negative, the last element is the step`` less than *stop*; if *step* is negative, the last element is the
smallest ``start + i * step`` greater than *stop*. *step* must not be zero smallest ``start + i * step`` greater than *stop*. *step* must not be zero
(or else :exc:`ValueError` is raised). Example: (or else :exc:`ValueError` is raised). Range objects have read-only data
attributes :attr:`start`, :attr:`stop` and :attr:`step` which return the
argument values (or their default). Example:
>>> list(range(10)) >>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
...@@ -1100,6 +1102,9 @@ are always available. They are listed here in alphabetical order. ...@@ -1100,6 +1102,9 @@ are always available. They are listed here in alphabetical order.
sequence of values they define (instead of comparing based on sequence of values they define (instead of comparing based on
object identity). object identity).
.. versionadded:: 3.3
The :attr:`start`, :attr:`stop` and :attr:`step` attributes.
.. function:: repr(object) .. function:: repr(object)
......
...@@ -560,6 +560,35 @@ class RangeTest(unittest.TestCase): ...@@ -560,6 +560,35 @@ class RangeTest(unittest.TestCase):
range(0) >= range(0) range(0) >= range(0)
def test_attributes(self):
# test the start, stop and step attributes of range objects
self.assert_attrs(range(0), 0, 0, 1)
self.assert_attrs(range(10), 0, 10, 1)
self.assert_attrs(range(-10), 0, -10, 1)
self.assert_attrs(range(0, 10, 1), 0, 10, 1)
self.assert_attrs(range(0, 10, 3), 0, 10, 3)
self.assert_attrs(range(10, 0, -1), 10, 0, -1)
self.assert_attrs(range(10, 0, -3), 10, 0, -3)
def assert_attrs(self, rangeobj, start, stop, step):
self.assertEqual(rangeobj.start, start)
self.assertEqual(rangeobj.stop, stop)
self.assertEqual(rangeobj.step, step)
with self.assertRaises(AttributeError):
rangeobj.start = 0
with self.assertRaises(AttributeError):
rangeobj.stop = 10
with self.assertRaises(AttributeError):
rangeobj.step = 1
with self.assertRaises(AttributeError):
del rangeobj.start
with self.assertRaises(AttributeError):
del rangeobj.stop
with self.assertRaises(AttributeError):
del rangeobj.step
def test_main(): def test_main():
test.support.run_unittest(RangeTest) test.support.run_unittest(RangeTest)
......
/* Range object implementation */ /* Range object implementation */
#include "Python.h" #include "Python.h"
#include "structmember.h"
/* Support objects whose length is > PY_SSIZE_T_MAX. /* Support objects whose length is > PY_SSIZE_T_MAX.
...@@ -880,6 +881,13 @@ static PyMethodDef range_methods[] = { ...@@ -880,6 +881,13 @@ static PyMethodDef range_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyMemberDef range_members[] = {
{"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY},
{"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY},
{"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY},
{0}
};
PyTypeObject PyRange_Type = { PyTypeObject PyRange_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0) PyVarObject_HEAD_INIT(&PyType_Type, 0)
"range", /* Name of this type */ "range", /* Name of this type */
...@@ -909,7 +917,7 @@ PyTypeObject PyRange_Type = { ...@@ -909,7 +917,7 @@ PyTypeObject PyRange_Type = {
range_iter, /* tp_iter */ range_iter, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
range_methods, /* tp_methods */ range_methods, /* tp_methods */
0, /* tp_members */ range_members, /* tp_members */
0, /* tp_getset */ 0, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment