Skip to content

Commit

Permalink
implemented path support in list.pop()
Browse files Browse the repository at this point in the history
fixes #7.
  • Loading branch information
wbolster committed Jul 2, 2017
1 parent 864bd84 commit 1271c81
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
25 changes: 18 additions & 7 deletions src/sanest/sanest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,22 +1078,33 @@ def __mul__(self, n):

__rmul__ = __mul__

def pop(self, index=-1, *, type=None):
def pop(self, path_like=-1, *, type=None):
"""
Remove and return an item; like ``list.pop()``.
:param index: position to look up
:param path_like: position to look up
:param type: expected type
"""
if not self._data:
if type is not None:
validate_type(type)
if typeof(path_like) is int: # fast path
l = self._data
index = path_like
path = [index]
else:
index, path = parse_path_like(path_like)
if typeof(path[-1]) is not int:
raise InvalidPathError("path must lead to list index")
l, index = resolve_path(self._data, path, partial=True)
if not l:
raise IndexError("pop from empty list")
try:
value = self._data[index]
value = l[index]
except IndexError:
raise IndexError(index) from None
raise IndexError(path) from None
if type is not None:
check_type(value, type=type, path=[index])
del self._data[index]
check_type(value, type=type, path=path)
del l[index]
if typeof(value) in CONTAINER_TYPES:
value = wrap(value, check=False)
return value
Expand Down
23 changes: 22 additions & 1 deletion test_sanest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ def test_list_pop():
assert l.pop(0, type=str) == 'a'
with pytest.raises(IndexError) as excinfo:
l.pop(123)
assert str(excinfo.value) == "123"
assert str(excinfo.value) == "[123]"
assert excinfo.value.__cause__ is None
assert excinfo.value.__suppress_context__
value = l.pop(type=list)
Expand All @@ -1512,6 +1512,27 @@ def test_list_pop():
assert str(excinfo.value) == "pop from empty list"


def test_list_pop_with_path():
l = sanest.list([
{'items': ['a', 'b', 'c']},
])
assert l.pop([0, 'items', 0]) == 'a'
assert l[0, 'items'] == ['b', 'c']
with pytest.raises(sanest.InvalidValueError) as excinfo:
l.pop([0, 'items', 1], type=int)
assert str(excinfo.value) == (
"expected int, got str at path [0, 'items', 1]: 'c'")
assert l.pop([0, 'items', 1], type=str) == 'c'
assert l.pop([0, 'items', 0]) == 'b'
assert l[0, 'items'] == []
with pytest.raises(IndexError) as excinfo:
l.pop([0, 'items', 0])
assert str(excinfo.value) == "pop from empty list"
with pytest.raises(sanest.InvalidPathError) as excinfo:
l.pop([0, 'x'])
assert str(excinfo.value) == "path must lead to list index"


def test_list_remove():
l = sanest.list(['a', 'a', 'b', 'a', {}])
l.remove('a')
Expand Down

0 comments on commit 1271c81

Please sign in to comment.