Skip to content

Commit 496e61e

Browse files
committed
Remove _step.EmptyStep logic
Non existing snapshots now raise InvalidSnapshotError akin to InvalidTimestepError. This is less surprising than returning a dummy object and allow for handling missing data using the error handling tools of Python.
1 parent 462fdc8 commit 496e61e

File tree

4 files changed

+41
-27
lines changed

4 files changed

+41
-27
lines changed

stagpy/_step.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -444,25 +444,11 @@ def isnap(self):
444444
# memory for what it's worth if search algo is efficient)
445445
while (istep is None or istep < self.istep) and isnap < 99999:
446446
isnap += 1
447-
istep = self.sdat.snaps[isnap].istep
447+
try:
448+
istep = self.sdat.snaps[isnap].istep
449+
except KeyError:
450+
pass
448451
# all intermediate istep could have their ._isnap to None
449452
if istep != self.istep:
450453
self._isnap = None
451454
return self._isnap
452-
453-
454-
class EmptyStep(Step):
455-
"""Dummy step object for nonexistent snaps.
456-
457-
This class inherits from :class:`Step`, but its :meth:`__getattribute__`
458-
method always return :obj:`None`. Its instances are falsy values.
459-
"""
460-
461-
def __init__(self):
462-
super().__init__(None, None)
463-
464-
def __getattribute__(self, name):
465-
return None
466-
467-
def __bool__(self):
468-
return False

stagpy/error.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,29 @@ def __init__(self, sdat, istep, msg):
9595
super().__init__(sdat, istep, msg)
9696

9797

98+
class InvalidSnapshotError(StagpyError, KeyError):
99+
"""Raised when invalid snapshot is requested.
100+
101+
Args:
102+
sdat (:class:`~stagpy.stagyydata.StagyyData`): the StagyyData
103+
instance for which the request was made.
104+
isnap (int): the invalid snapshot index.
105+
msg (str): the error message.
106+
107+
Attributes:
108+
sdat (:class:`~stagpy.stagyydata.StagyyData`): the StagyyData
109+
instance for which the request was made.
110+
isnap (int): the invalid snapshot index.
111+
msg (str): the error message.
112+
"""
113+
114+
def __init__(self, sdat, isnap, msg):
115+
self.sdat = sdat
116+
self.isnap = isnap
117+
self.msg = msg
118+
super().__init__(sdat, isnap, msg)
119+
120+
98121
class InvalidTimeFractionError(StagpyError):
99122
"""Raised when invalid fraction of series is requested.
100123

stagpy/stagyydata.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,12 @@ class _Steps:
192192
def __init__(self, sdat):
193193
self.sdat = sdat
194194
self._len = UNDETERMINED
195-
self._data = {None: _step.EmptyStep()} # for non existent snaps
195+
self._data = {}
196196

197197
def __repr__(self):
198198
return '{}.steps'.format(repr(self.sdat))
199199

200200
def __getitem__(self, istep):
201-
if istep is None:
202-
return self._data[None]
203201
keys = _as_view_item(istep)
204202
if keys is not None:
205203
return _StepsView(self, keys)
@@ -316,6 +314,9 @@ def __getitem__(self, isnap):
316314
self._bind(isnap, istep)
317315
else:
318316
self._isteps[isnap] = None
317+
if istep is None:
318+
raise error.InvalidSnapshotError(
319+
self.sdat, isnap, 'Invalid snapshot index')
319320
return self.sdat.steps[istep]
320321

321322
def __delitem__(self, isnap):
@@ -430,8 +431,12 @@ def __repr__(self):
430431
rep += '.filter({})'.format(', '.join(flts))
431432
return rep
432433

433-
def _pass(self, step):
434-
"""Check whether a :class:`~stagpy._step.Step` passes the filters."""
434+
def _pass(self, item):
435+
"""Check whether an item passes the filters."""
436+
try:
437+
step = self._col[item]
438+
except KeyError:
439+
return False
435440
okf = True
436441
okf = okf and (not self._flt['snap'] or step.isnap is not None)
437442
okf = okf and (not self._flt['rprof'] or step.rprof is not None)
@@ -475,8 +480,8 @@ def __iter__(self):
475480
if isinstance(item, slice):
476481
idx = item.indices(len(self._col))
477482
yield from (self._col[i] for i in range(*idx)
478-
if self._pass(self._col[i]))
479-
elif self._pass(self._col[item]):
483+
if self._pass(i))
484+
elif self._pass(item):
480485
yield self._col[item]
481486

482487
def __eq__(self, other):

tests/test_stagyydata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ def test_snaps_last(sdat):
7272

7373

7474
def test_snaps_empty(sdat):
75-
empty = sdat.snaps[len(sdat.snaps)]
76-
assert isinstance(empty, stagpy._step.EmptyStep)
75+
with pytest.raises(stagpy.error.InvalidSnapshotError):
76+
sdat.snaps[len(sdat.snaps)]
7777

7878

7979
def test_step_is_snap(sdat):

0 commit comments

Comments
 (0)