提交 e4569421 编写于 作者: HansBug's avatar HansBug 😆

Merge branch 'main' into dev/repr

from collections import namedtuple
import pytest
from treevalue import FastTreeValue
from treevalue.tree import TreeValue, mapping, union, raw, subside, rise, delayed
......@@ -116,6 +119,24 @@ class TestTreeTreeStructural:
assert subside({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}, 'e': [3, 4, 5]}) == \
{'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}, 'e': [3, 4, 5]}
nt = namedtuple('nt', ['a', 'b', 'c'])
a = nt(
MyTreeValue({'x': 1, 'y': 2, 'z': {'v': 3}}),
MyTreeValue({'x': 4, 'y': 5, 'z': {'v': 6}}),
MyTreeValue({'x': 7, 'y': 8, 'z': {'v': 9}}),
)
t5 = subside(a)
assert t5 == MyTreeValue({
'x': nt(1, 4, 7),
'y': nt(2, 5, 8),
'z': {'v': nt(3, 6, 9), },
})
t6 = subside(a, return_type=FastTreeValue)
assert t6.a == FastTreeValue({'x': 1, 'y': 2, 'z': {'v': 3}})
assert t6.b == FastTreeValue({'x': 4, 'y': 5, 'z': {'v': 6}})
assert t6.c == FastTreeValue({'x': 7, 'y': 8, 'z': {'v': 9}})
def test_subside_delayed(self):
class MyTreeValue(TreeValue):
pass
......@@ -273,3 +294,15 @@ class TestTreeTreeStructural:
MyTreeValue({'v': {'x': 3, 'y': 8}}),
]
}
nt = namedtuple('nt', ['a', 'b', 'c'])
t11 = MyTreeValue({
'x': nt(1, 4, 7),
'y': nt(2, 5, 8),
'z': {'v': nt(3, 6, 9), },
})
assert rise(t11) == nt(
MyTreeValue({'x': 1, 'y': 2, 'z': {'v': 3}}),
MyTreeValue({'x': 4, 'y': 5, 'z': {'v': 6}}),
MyTreeValue({'x': 7, 'y': 8, 'z': {'v': 9}}),
)
......@@ -16,6 +16,15 @@ from ..func.modes cimport _c_load_mode
MISSING_NOT_ALLOW = SingletonMark("missing_not_allow")
cdef inline bool _c_is_namedtuple(object type_):
return issubclass(type_, tuple) and hasattr(type_, '_fields') and hasattr(type_, '_asdict')
cdef inline object _c_create_sequence_with_type(object type_, object iters):
if _c_is_namedtuple(type_):
return type_(*iters)
else:
return type_(iters)
cdef object _c_subside_process(tuple value, object it):
cdef type type_
cdef list items
......@@ -29,7 +38,7 @@ cdef object _c_subside_process(tuple value, object it):
_l_res = []
for v in items:
_l_res.append(_c_subside_process(v, it))
return type_(_l_res)
return _c_create_sequence_with_type(type_, _l_res)
elif issubclass(type_, dict):
_d_res = {}
for k, v in items:
......@@ -270,7 +279,7 @@ cdef object _c_rise_struct_builder(tuple p, object it):
for v in item:
_l_res.append(_c_rise_struct_builder(v, it))
return type_(_l_res)
return _c_create_sequence_with_type(type_, _l_res)
else:
return next(it)
......@@ -298,7 +307,10 @@ cdef tuple _c_rise_struct_process(list objs, object template):
raise ValueError(f"At least {repr(_l_temp - 2)} value expected due to template "
f"{repr(template)}, but length is {repr(_l_obj_0)}.")
_a_template = type(template)(chain(template[:-2], (template[-2],) * (_l_obj_0 - _l_temp + 2)))
_a_template = _c_create_sequence_with_type(
type(template),
chain(template[:-2], (template[-2],) * (_l_obj_0 - _l_temp + 2))
)
else:
_a_template = template
elif template is None:
......@@ -330,7 +342,7 @@ cdef tuple _c_rise_struct_process(list objs, object template):
if failed:
_a_template = object
else:
_a_template = _t_type(None for _ in range(length))
_a_template = _c_create_sequence_with_type(_t_type, (None for _ in range(length)))
else:
_a_template = object
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册