Skip to content

BUG: RangeIndex can be created without args #13803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ Bug Fixes
- Bug in ``DatetimeIndex`` with nanosecond frequency does not include timestamp specified with ``end`` (:issue:`13672`)

- Bug in ``Index`` raises ``OutOfBoundsDatetime`` if ``datetime`` exceeds ``datetime64[ns]`` bounds, rather than coercing to ``object`` dtype (:issue:`13663`)
- Bug in ``RangeIndex`` can be created without no arguments rather than raises ``TypeError`` (:issue:`13793`)
- Bug in ``.value_counts`` raises ``OutOfBoundsDatetime`` if data exceeds ``datetime64[ns]`` bounds (:issue:`13663`)
- Bug in ``DatetimeIndex`` may raise ``OutOfBoundsDatetime`` if input ``np.datetime64`` has other unit than ``ns`` (:issue:`9114`)

Expand Down
10 changes: 9 additions & 1 deletion pandas/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ def _ensure_int(value, field):

return new_value

if start is None:
if start is None and stop is None and step is None:
msg = "RangeIndex(...) must be called with integers"
raise TypeError(msg)
elif start is None:
start = 0
else:
start = _ensure_int(start, 'start')
Expand Down Expand Up @@ -122,8 +125,13 @@ def _simple_new(cls, start, stop=None, step=None, name=None,
result = object.__new__(cls)

# handle passed None, non-integers
if start is None and stop is None:
# empty
start, stop, step = 0, 0, 1

if start is None or not is_integer(start):
try:

return RangeIndex(start, stop, step, name=name, **kwargs)
except TypeError:
return Index(start, stop, step, name=name, **kwargs)
Expand Down
45 changes: 28 additions & 17 deletions pandas/tests/indexes/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,28 @@ def test_constructor(self):
self.assertEqual(index._step, 2)
tm.assert_index_equal(Index(expected), index)

index = RangeIndex()
expected = np.empty(0, dtype=np.int64)
self.assertIsInstance(index, RangeIndex)
self.assertEqual(index._start, 0)
self.assertEqual(index._stop, 0)
self.assertEqual(index._step, 1)
tm.assert_index_equal(Index(expected), index)

index = RangeIndex(name='Foo')
self.assertIsInstance(index, RangeIndex)
self.assertEqual(index.name, 'Foo')
msg = "RangeIndex\\(\\.\\.\\.\\) must be called with integers"
with tm.assertRaisesRegexp(TypeError, msg):
RangeIndex()

for index in [RangeIndex(0), RangeIndex(start=0), RangeIndex(stop=0),
RangeIndex(0, 0)]:
expected = np.empty(0, dtype=np.int64)
self.assertIsInstance(index, RangeIndex)
self.assertEqual(index._start, 0)
self.assertEqual(index._stop, 0)
self.assertEqual(index._step, 1)
tm.assert_index_equal(Index(expected), index)

with tm.assertRaisesRegexp(TypeError, msg):
RangeIndex(name='Foo')

for index in [RangeIndex(0, name='Foo'),
RangeIndex(start=0, name='Foo'),
RangeIndex(stop=0, name='Foo'),
RangeIndex(0, 0, name='Foo')]:
self.assertIsInstance(index, RangeIndex)
self.assertEqual(index.name, 'Foo')

# we don't allow on a bare Index
self.assertRaises(TypeError, lambda: Index(0, 1000))
Expand Down Expand Up @@ -210,10 +221,10 @@ def test_numeric_compat2(self):
RangeIndex(0, 1000, 1)._int64index // 2),
(RangeIndex(0, 100, 1), 2.0,
RangeIndex(0, 100, 1)._int64index // 2.0),
(RangeIndex(), 50, RangeIndex()),
(RangeIndex(0), 50, RangeIndex(0)),
(RangeIndex(2, 4, 2), 3, RangeIndex(0, 1, 1)),
(RangeIndex(-5, -10, -6), 4, RangeIndex(-2, -1, 1)),
(RangeIndex(-100, -200, 3), 2, RangeIndex())]
(RangeIndex(-100, -200, 3), 2, RangeIndex(0))]
for idx, div, expected in cases_exact:
tm.assert_index_equal(idx // div, expected, exact=True)

Expand Down Expand Up @@ -288,7 +299,7 @@ def test_delete(self):
def test_view(self):
super(TestRangeIndex, self).test_view()

i = RangeIndex(name='Foo')
i = RangeIndex(0, name='Foo')
i_view = i.view()
self.assertEqual(i_view.name, 'Foo')

Expand Down Expand Up @@ -612,16 +623,16 @@ def test_union(self):
(RI(0, 100, 5), RI(0, 100, 20), RI(0, 100, 5)),
(RI(0, -100, -5), RI(5, -100, -20), RI(-95, 10, 5)),
(RI(0, -11, -1), RI(1, -12, -4), RI(-11, 2, 1)),
(RI(), RI(), RI()),
(RI(0, -10, -2), RI(), RI(0, -10, -2)),
(RI(0), RI(0), RI(0)),
(RI(0, -10, -2), RI(0), RI(0, -10, -2)),
(RI(0, 100, 2), RI(100, 150, 200), RI(0, 102, 2)),
(RI(0, -100, -2), RI(-100, 50, 102), RI(-100, 4, 2)),
(RI(0, -100, -1), RI(0, -50, -3), RI(-99, 1, 1)),
(RI(0, 1, 1), RI(5, 6, 10), RI(0, 6, 5)),
(RI(0, 10, 5), RI(-5, -6, -20), RI(-5, 10, 5)),
(RI(0, 3, 1), RI(4, 5, 1), I64([0, 1, 2, 4])),
(RI(0, 10, 1), I64([]), RI(0, 10, 1)),
(RI(), I64([1, 5, 6]), I64([1, 5, 6]))]
(RI(0), I64([1, 5, 6]), I64([1, 5, 6]))]
for idx1, idx2, expected in cases:
res1 = idx1.union(idx2)
res2 = idx2.union(idx1)
Expand Down