diff --git a/nirum/deserialize.py b/nirum/deserialize.py index 2887d96..a9afa39 100644 --- a/nirum/deserialize.py +++ b/nirum/deserialize.py @@ -21,6 +21,10 @@ def deserialize_meta(cls, data): def deserialize_boxed_type(cls, value): + deserializer = getattr(cls.__nirum_boxed_type__, + '__nirum_deserialize__', None) + if deserializer: + value = deserializer(value) return cls(value=value) diff --git a/nirum/validate.py b/nirum/validate.py index e04fdca..1ccb692 100644 --- a/nirum/validate.py +++ b/nirum/validate.py @@ -6,18 +6,7 @@ def validate_boxed_type(boxed, type_hint) -> bool: - actual_boxed_val_type = type(boxed) - while True: - try: - actual_boxed_val_type = actual_boxed_val_type.__nirum_boxed_type__ - except AttributeError: - break - while True: - try: - type_hint = type_hint.__nirum_boxed_type__ - except AttributeError: - break - if actual_boxed_val_type != type_hint: + if not isinstance(boxed, type_hint): raise TypeError('{0} expected, found: {1}'.format(type_hint, type(boxed))) return boxed diff --git a/tests/conftest.py b/tests/conftest.py index 755f7ae..5cd0a1a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -262,7 +262,7 @@ def __repr__(self) -> str: class C: - __nirum_boxed_type__ = A + __nirum_boxed_type__ = B def __init__(self, value: B) -> None: validate_boxed_type(value, B) diff --git a/tests/deserialize_test.py b/tests/deserialize_test.py index 8292ea4..155103b 100644 --- a/tests/deserialize_test.py +++ b/tests/deserialize_test.py @@ -85,3 +85,11 @@ def test_deserialize_meta_boxed(fx_boxed_type, fx_record_type, fx_point): meta = deserialize_meta(fx_boxed_type, v) boxed = fx_boxed_type(v) assert meta == boxed + + +def test_deserialize_multiple_boxed_type(fx_layered_boxed_types): + A, B, C = fx_layered_boxed_types + assert B.__nirum_deserialize__('lorem') == B(A('lorem')) + assert C.__nirum_deserialize__('x') == C(B(A('x'))) + with raises(TypeError): + B.__nirum_deserialize__(1) diff --git a/tests/serialize_test.py b/tests/serialize_test.py index a753f2a..6aa1d50 100644 --- a/tests/serialize_test.py +++ b/tests/serialize_test.py @@ -32,3 +32,9 @@ def test_serialize_union_type(fx_point, fx_offset, fx_circle_type, 'lower_right': serialize_record_type(fx_point), } assert serialize_union_type(rectangle) == s + + +def test_multiple_boxed_type(fx_layered_boxed_types): + A, B, _ = fx_layered_boxed_types + assert B(A('hello')).value.value == 'hello' + assert B(A('lorem')).__nirum_serialize__() == 'lorem' diff --git a/tests/validate_test.py b/tests/validate_test.py index 71f8190..9764ceb 100644 --- a/tests/validate_test.py +++ b/tests/validate_test.py @@ -31,4 +31,15 @@ def test_validate_union_type(fx_rectangle, fx_rectangle_type, fx_point): def test_validate_layered_boxed_types(fx_layered_boxed_types): - assert validate_boxed_type('test', fx_layered_boxed_types[1]) + A, B, C = fx_layered_boxed_types + assert validate_boxed_type('test', str) + assert validate_boxed_type(A('test'), A) + assert validate_boxed_type(B(A('test')), B) + with raises(TypeError): + assert validate_boxed_type('test', A) + + with raises(TypeError): + assert validate_boxed_type('test', B) + + with raises(TypeError): + assert validate_boxed_type(A('test'), B)