未验证 提交 76a5e75a 编写于 作者: HansBug's avatar HansBug 😆 提交者: GitHub

Merge pull request #56 from opendilab/dev/update

dev(hansbug): add update method
......@@ -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
: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
.. _apidoc_tree_tree_delayed:
......
......@@ -4,6 +4,7 @@ import re
import pytest
from treevalue import raw, TreeValue, delayed
from treevalue.tree.common import create_storage
try:
_ = reversed({}.keys())
......@@ -360,6 +361,54 @@ class TestTreeTreeTree:
assert tv1.clear() is None
assert not tv1
# noinspection DuplicatedCode
def test_update(self):
tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
tv1.update({'a': 3, 'c': TreeValue({'x': 3, 'y': 4}), 'd': {'x': 200, 'y': 300}})
assert tv1 == TreeValue({
'a': 3, 'b': 2,
'c': {'x': 3, 'y': 4},
'd': raw({'x': 200, 'y': 300}),
})
tv2 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
tv2.update(a=3, c=TreeValue({'x': 3, 'y': 4}), d={'x': 200, 'y': 300})
assert tv2 == TreeValue({
'a': 3, 'b': 2,
'c': {'x': 3, 'y': 4},
'd': raw({'x': 200, 'y': 300}),
})
tv3 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
tv3.update(TreeValue({'a': 3, 'c': {'x': 3, 'y': 4}, 'd': raw({'x': 200, 'y': 300})}))
assert tv3 == TreeValue({
'a': 3, 'b': 2,
'c': {'x': 3, 'y': 4},
'd': raw({'x': 200, 'y': 300}),
})
tv4 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
tv4.update(create_storage({'a': 3, 'c': {'x': 3, 'y': 4}, 'd': raw({'x': 200, 'y': 300})}))
assert tv4 == TreeValue({
'a': 3, 'b': 2,
'c': {'x': 3, 'y': 4},
'd': raw({'x': 200, 'y': 300}),
})
tv5 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
with pytest.raises(TypeError):
tv5.update('sdklfj')
with pytest.raises(TypeError):
tv5.update(123)
tv6 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
tv6.update({'a': 3, 'c': TreeValue({'x': 3, 'y': 4}), 'd': {'x': 200, 'y': 300}}, a=50, f='dfkl')
assert tv6 == TreeValue({
'a': 50, 'b': 2, 'f': 'dfkl',
'c': {'x': 3, 'y': 4},
'd': raw({'x': 200, 'y': 300}),
})
def test_keys(self):
tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 3}, 'd': raw({'x': 2, 'y': 3})})
assert len(tv1.keys()) == 4
......
......@@ -20,14 +20,15 @@ cdef class TreeValue:
cpdef _getitem_extern(self, object key)
cpdef _setitem_extern(self, object key, object value)
cpdef _delitem_extern(self, object key)
cpdef get(self, str key, object default= *)
cpdef pop(self, str key, object default= *)
cpdef popitem(self)
cpdef void clear(self)
cpdef treevalue_keys keys(self)
cpdef treevalue_values values(self)
cpdef treevalue_items items(self)
cdef void _update(self, object d, dict kwargs) except *
cpdef public get(self, str key, object default= *)
cpdef public pop(self, str key, object default= *)
cpdef public popitem(self)
cpdef public void clear(self)
cpdef public treevalue_keys keys(self)
cpdef public treevalue_values values(self)
cpdef public treevalue_items items(self)
cdef str _prefix_fix(object text, object prefix)
cdef str _title_repr(TreeStorage st, object type_)
......
......@@ -2,7 +2,7 @@
# cython:language_level=3
import os
from collections.abc import Sized, Container, Reversible
from collections.abc import Sized, Container, Reversible, Mapping
from operator import itemgetter
import cython
......@@ -169,6 +169,72 @@ cdef class TreeValue:
"""
self._st.clear()
cdef void _update(self, object d, dict kwargs) except *:
cdef object dt
if d is None:
dt = {}
elif isinstance(d, Mapping):
dt = d
elif isinstance(d, TreeValue):
dt = d._detach().detach()
elif isinstance(d, TreeStorage):
dt = d.detach()
else:
raise TypeError(f'Invalid type of update dict - {type(d)!r}.')
cdef str key
cdef object value
for key, value in dt.items():
self._st.set(key, self._raw(value))
for key, value in kwargs.items():
self._st.set(key, self._raw(value))
@cython.binding(True)
def update(self, __update_dict=None, **kwargs):
"""
Overview:
Update items in current treevalue.
:param __update_dict: Dictionary object for updating.
:param kwargs: Arguments for updating.
.. note::
The method :meth:`update` is similar to \
`dict.update <https://docs.python.org/3/library/stdtypes.html#dict.update>`_.
Examples::
>>> from treevalue import TreeValue
>>>
>>> t = TreeValue({'a': 1, 'b': 3, 'c': '233'})
>>> t.update({'a': 10, 'f': 'sdkj'}) # with dict
>>> t
<TreeValue 0x7fa31f5ba048>
├── 'a' --> 10
├── 'b' --> 3
├── 'c' --> '233'
└── 'f' --> 'sdkj'
>>>
>>> t.update(a=100, ft='fffff') # with key-word arguments
>>> t
<TreeValue 0x7fa31f5ba048>
├── 'a' --> 100
├── 'b' --> 3
├── 'c' --> '233'
├── 'f' --> 'sdkj'
└── 'ft' --> 'fffff'
>>>
>>> t.update(TreeValue({'f': {'x': 1}, 'b': 40})) # with TreeValue
>>> t
<TreeValue 0x7fa31f5ba048>
├── 'a' --> 100
├── 'b' --> 40
├── 'c' --> '233'
├── 'f' --> <TreeValue 0x7fa31f5ba278>
│ └── 'x' --> 1
└── 'ft' --> 'fffff'
"""
self._update(__update_dict, kwargs)
@cython.binding(True)
cpdef _attr_extern(self, str key):
r"""
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册