Skip to content

Commit

Permalink
Merge pull request #59 from opendilab/dev/iter
Browse files Browse the repository at this point in the history
dev(hansbug): update __iter__ and __reversed__
  • Loading branch information
HansBug committed Jul 7, 2022
2 parents fcc3548 + fdeca27 commit 92bbe31
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
2 changes: 1 addition & 1 deletion docs/source/api_doc/tree/tree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ TreeValue
---------------

.. autoclass:: TreeValue
:members: __init__, __getattribute__, __setattr__, __delattr__, __contains__, __repr__, __iter__, __hash__, __eq__, _attr_extern, __len__, __bool__, __str__, __getstate__, __setstate__, get, pop, keys, values, items, __getitem__, __setitem__, __delitem__, _getitem_extern, _setitem_extern, _delitem_extern, popitem, clear, update, setdefault
:members: __init__, __getattribute__, __setattr__, __delattr__, __contains__, __repr__, __iter__, __hash__, __eq__, _attr_extern, __len__, __bool__, __str__, __getstate__, __setstate__, get, pop, keys, values, items, __getitem__, __setitem__, __delitem__, _getitem_extern, _setitem_extern, _delitem_extern, popitem, clear, update, setdefault, __reversed__


.. _apidoc_tree_tree_delayed:
Expand Down
19 changes: 13 additions & 6 deletions test/tree/tree/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,19 @@ def test_tree_value_repr(self):
def test_tree_value_iter(self):
# Attention: dict(tv1) is not supported in python 3.7+
tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}})
assert sorted(list(tv1)) == [
('a', 1),
('b', 2),
('c', TreeValue({'x': 2, 'y': 3}))
]
assert sorted(list(tv1.c)) == [('x', 2), ('y', 3)]
assert sorted(list(tv1)) == ['a', 'b', 'c']
assert sorted(list(tv1.c)) == ['x', 'y']

def test_tree_value_reversed(self):
tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}})
if _reversible:
assert list(reversed(tv1)) == list(iter(tv1))[::-1]
assert list(reversed(tv1.c)) == list(iter(tv1.c))[::-1]
else:
with pytest.raises(TypeError):
reversed(tv1)
with pytest.raises(TypeError):
reversed(tv1.c)

def test_tree_value_len(self):
tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}})
Expand Down
2 changes: 1 addition & 1 deletion treevalue/tree/tree/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def _node_tag(current, parent, current_path, parent_path, is_node):
graph_title=title or "<untitled>",
graph_cfg=cfg or {},
repr_gen=repr_gen or (lambda x: nohtml(repr(x))),
iter_gen=lambda n: iter(n) if isinstance(n, TreeValue) else None,
iter_gen=lambda n: iter(n.items()) if isinstance(n, TreeValue) else None,
node_cfg_gen=_dict_call_merge(lambda n, p, np, pp, is_node, is_root, root: {
'fillcolor': _shape_color(root[2]),
'color': _border_color(root[2], is_node),
Expand Down
65 changes: 45 additions & 20 deletions treevalue/tree/tree/tree.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ from ...utils import format_tree
cdef class _CObject:
pass

try:
reversed({'a': 1}.keys())
except TypeError:
_reversible = False
else:
_reversible = True

cdef inline object _item_unwrap(object v):
if isinstance(v, list) and len(v) == 1:
return v[0]
Expand Down Expand Up @@ -529,24 +536,49 @@ cdef class TreeValue:
Overview:
Get iterator of this tree value.
Returns:
- iter (:obj:`iter`): Iterator for keys and values.
:return: An iterator for the keys.
Example:
Examples:
>>> from treevalue import TreeValue
>>>
>>> t = TreeValue({'a': 1, 'b': 2, 'x': 3})
>>> for key, value in t:
>>> print(key, value)
>>> for key in t:
... print(key)
a
b
x
The output will be:
.. note::
The method :meth:`__iter__`'s bahaviour should be similar to \
`dict.__iter__ <https://docs.python.org/3/library/stdtypes.html#dict.update>`_.
"""
yield from self._st.iter_keys()

>>> a 1
>>> b 2
>>> x 3
@cython.binding(True)
def __reversed__(self):
"""
cdef str k
cdef object v
for k, v in self._st.iter_items():
yield k, self._unraw(v)
Overview:
Get the reversed iterator of tree value.
:return: A reversed iterator for the keys.
Examples:
>>> from treevalue import TreeValue
>>>
>>> t = TreeValue({'a': 1, 'b': 2, 'x': 3})
>>> for key in reversed(t):
... print(key)
x
b
a
.. note::
Only available in python 3.8 or higher version.
"""
if _reversible:
return self._st.iter_rev_keys()
else:
raise TypeError(f'{self._type.__name__!r} object is not reversible')

@cython.binding(True)
def __len__(self):
Expand Down Expand Up @@ -810,13 +842,6 @@ cdef object _build_tree(TreeStorage st, object type_, str prefix, dict id_pool,
self_repr = _prefix_fix(self_repr, prefix)
return self_repr, children

try:
reversed({'a': 1}.keys())
except TypeError:
_reversible = False
else:
_reversible = True

# noinspection PyPep8Naming
cdef class treevalue_keys(_CObject, Sized, Container, Reversible):
def __cinit__(self, TreeStorage storage, type _type):
Expand Down

0 comments on commit 92bbe31

Please sign in to comment.