diff -r 5b253226cd36 Doc/library/functions.rst --- a/Doc/library/functions.rst Tue Apr 19 11:15:11 2011 -0700 +++ b/Doc/library/functions.rst Tue Apr 19 23:04:10 2011 +0200 @@ -1012,7 +1012,9 @@ ...]``. 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 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)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -1058,6 +1060,9 @@ Test integers for membership in constant time instead of iterating through all items. + .. versionadded:: 3.3 + The :attr:`start`, :attr:`stop` and :attr:`step` attributes. + .. function:: repr(object) diff -r 5b253226cd36 Lib/test/test_range.py --- a/Lib/test/test_range.py Tue Apr 19 11:15:11 2011 -0700 +++ b/Lib/test/test_range.py Tue Apr 19 23:04:10 2011 +0200 @@ -508,6 +508,35 @@ r[i:j:k] + 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(): test.support.run_unittest(RangeTest) diff -r 5b253226cd36 Objects/rangeobject.c --- a/Objects/rangeobject.c Tue Apr 19 11:15:11 2011 -0700 +++ b/Objects/rangeobject.c Tue Apr 19 23:04:10 2011 +0200 @@ -1,6 +1,7 @@ /* Range object implementation */ #include "Python.h" +#include "structmember.h" /* Support objects whose length is > PY_SSIZE_T_MAX. @@ -749,6 +750,13 @@ {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 = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "range", /* Name of this type */ @@ -778,7 +786,7 @@ range_iter, /* tp_iter */ 0, /* tp_iternext */ range_methods, /* tp_methods */ - 0, /* tp_members */ + range_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */