Skip to content
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

Make indexing and slicing consistent with Python. #1183

Merged
merged 1 commit into from
Feb 7, 2017
Merged
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
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Release History

**Changed**

- Integer indexing of Nengo objects out of range raises an ``IndexError``
now to be consistent with standard Python behaviour.
(`#1176 <https://github.com/nengo/nengo/issues/1176>`_,
`#1183 <https://github.com/nengo/nengo/pull/1183>`_)
- Documentation that applies to all Nengo projects has been moved to
https://nengo.github.io/.
(`#1251 <https://github.com/nengo/nengo/pull/1251>`_)
Expand Down
27 changes: 14 additions & 13 deletions nengo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,29 @@ class ObjView(object):

def __init__(self, obj, key=slice(None)):
self.obj = obj
if is_integer(key):
# single slices of the form [i] should be cast into
# slice objects for convenience
if key == -1:
# special case because slice(-1, 0) gives the empty list
key = slice(key, None)
else:
key = slice(key, key+1)
self.slice = key

# Node.size_in != size_out, so one of these can be invalid
try:
self.size_in = np.arange(self.obj.size_in)[self.slice].size
self.size_in = np.arange(self.obj.size_in)[key].size
except IndexError:
self.size_in = None
try:
self.size_out = np.arange(self.obj.size_out)[self.slice].size
self.size_out = np.arange(self.obj.size_out)[key].size
except IndexError:
self.size_out = None
if self.size_in is None and self.size_out is None:
raise ValidationError("Invalid slice '%s' of %s"
% (self.slice, self.obj), attr='key')
raise IndexError("Invalid slice '%s' of %s" % (key, self.obj))

if is_integer(key):
# single slices of the form [i] should be cast into
# slice objects for convenience
if key == -1:
# special case because slice(-1, 0) gives the empty list
self.slice = slice(key, None)
else:
self.slice = slice(key, key+1)
else:
self.slice = key

def copy(self):
return copy(self)
Expand Down
15 changes: 15 additions & 0 deletions nengo/tests/test_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,28 @@ def test_len():
assert len(ens1) == 1
assert len(ens5) == 5
assert len(ens1[0]) == 1
assert len(ens1[-1]) == 1
assert len(ens5[:3]) == 3
assert len(ens5[:100]) == 5

# Neurons.__len__
assert len(ens1.neurons) == 10
assert len(ens5.neurons) == 100
assert len(ens1.neurons[0]) == 1
assert len(ens5.neurons[90:]) == 10
assert len(ens5.neurons[90:150]) == 10


def test_invalid_indices():
with nengo.Network():
ens = nengo.Ensemble(10, dimensions=2)

with pytest.raises(IndexError):
assert ens[5]
with pytest.raises(IndexError):
assert ens[-5]
with pytest.raises(IndexError):
assert ens.neurons[20]


def test_invalid_rates(Simulator):
Expand Down