Пример #1
0
    def test_deserialization_with_yasoo_type_hints(self):
        @attrs(frozen=True)
        class Foo:
            a: int = attrib()

        l = [[Foo(i) for i in range(5)] for _ in range(5)]
        l2 = deserialize(serialize(l, type_key=None), obj_type=List_[List_[Foo]])
        self.assertIsInstance(l2, list)
        self.assertIsInstance(l2[0], list)
        self.assertIsInstance(l2[0][0], Foo)
        self.assertEqual(l, l2)

        l = [set(i) for i in l]
        l2 = deserialize(serialize(l, type_key=None), obj_type=List_[Set_[Foo]])
        self.assertIsInstance(l2, list)
        self.assertIsInstance(l2[0], list)
        self.assertIsInstance(l2[0][0], Foo)
        for i1, i2 in zip(l, l2):
            self.assertEqual(i1, set(i2))

        d = dict(enumerate(l))
        d2 = deserialize(serialize(d, type_key=None), obj_type=Dict_[int, Set_[Foo]])
        self.assertIsInstance(d2, dict)
        self.assertEqual(d.keys(), d2.keys())
        self.assertIsInstance(d2[0], list)
        self.assertIsInstance(d2[0][0], Foo)
        for k, v in d.items():
            self.assertEqual(v, set(d2[k]))
Пример #2
0
    def test_enum_deserialization_fallback_order(self):
        class Foo(Enum):
            A = 5
            B = 'a'
            C = 'A'
            D = 'x'

        # Default - by name
        obj = deserialize({ENUM_VALUE_KEY: 'A'},
                          obj_type=Foo,
                          globals=locals())
        self.assertEqual(obj, Foo.A)
        # Fallback 1 - by case-insensitive name
        obj = deserialize({ENUM_VALUE_KEY: 'a'},
                          obj_type=Foo,
                          globals=locals())
        self.assertEqual(obj, Foo.A)
        # Fallback 2 - by value
        obj = deserialize({ENUM_VALUE_KEY: 'x'},
                          obj_type=Foo,
                          globals=locals())
        self.assertEqual(obj, Foo.D)
        # Failure
        with self.assertRaises(ValueError):
            deserialize({ENUM_VALUE_KEY: 'y'}, obj_type=Foo, globals=locals())
Пример #3
0
    def test_deserialization_discovers_globals(self):
        data = {'child': {}}
        result = deserialize(dict(data), Child, globals=globals())
        self.assertIsInstance(result, Child)
        self.assertEqual('Parent', type(result.child).__name__)

        with self.assertRaises(TypeError) as e:
            deserialize(dict(data), Child)
        self.assertIn('Found type annotation Parent', e.exception.args[0])
    def test_attr_extraneous_fields(self):
        @attrs
        class Foo:
            pass

        try:
            deserialize({'a': 5}, Foo)
            self.fail('Deserialized with extraneous fields')
        except:
            pass
Пример #5
0
    def test_enum(self):
        class MyEnum(Enum):
            FIRST = 1
            Second = {'x': 1, 'y': 2}

        self.assertEqual(
            MyEnum.FIRST,
            deserialize(serialize(MyEnum.FIRST, type_key=None), MyEnum))
        self.assertEqual(
            MyEnum.Second,
            deserialize(serialize(MyEnum.Second, type_key=None), MyEnum))
Пример #6
0
    def test_remove_types(self):
        original = {'a': 1}
        type_key = '__type'
        data = serialize(original, type_key=type_key)
        restored = deserialize(data, obj_type=dict, type_key=None)
        self.assertIsInstance(restored, dict)
        self.assertNotEqual(original, restored)

        remove_type_data(data, type_key=type_key)
        restored = deserialize(data, obj_type=dict, type_key=None)
        self.assertIsInstance(restored, dict)
        self.assertEqual(original, restored)
Пример #7
0
    def test_deserializer_registration_can_defer_dereference(self):
        class Foo:
            pass

            @staticmethod
            @deserializer
            def func(_) -> 'Foo':
                return Foo()

        with self.assertRaises(Exception):
            f = deserialize({}, Foo, globals=globals())
        f = deserialize({}, Foo, globals=locals())
        self.assertEqual(Foo, type(f))
Пример #8
0
    def test_deserializer_temporary_unregister(self):
        class Foo:
            pass

        @deserializer_of(Foo)
        def func(_):
            return Foo()

        with self.assertRaises(TypeError) as e:
            with unregister_deserializers(Foo):
                deserialize({}, Foo, type_key=None)
        self.assertIn('attrs or dataclass classes', e.exception.args[0])
        self.assertIsInstance(deserialize({}, Foo, type_key=None), Foo)
Пример #9
0
    def test_deserialization_with_string_type_hint(self):
        class Foo:
            pass

        @deserializer_of(Foo)
        def deserialize_foo(_):
            return Foo()

        foo = deserialize({}, 'Foo', type_key=None, globals=locals())
        self.assertIsInstance(foo, Foo)

        with self.assertRaises(TypeError) as e:
            deserialize({}, 'Bar', type_key=None, globals=locals())
        self.assertIn('Bar', e.exception.args[0])
Пример #10
0
    def test_deserializer_registration_including_descendants(self):
        class Foo:
            pass

        class Bar(Foo):
            pass

        @deserializer_of(Foo, include_descendants=True)
        def foo(_, obj_type=Foo) -> Foo:
            return obj_type()

        self.assertIsInstance(deserialize({}, Foo, type_key=None), Foo)
        self.assertNotIsInstance(deserialize({}, Foo, type_key=None), Bar)
        self.assertIsInstance(deserialize({}, Bar, type_key=None), Bar)
    def test_attr_deserialization_with_type_hint_and_type_in_data(self):
        @attrs
        class Foo:
            a = attrib()

        @attrs
        class FakeFoo:
            a = attrib()

        @attrs
        class Bar:
            foo: FakeFoo = attrib()

        b = deserialize({
            '__type': 'Bar',
            'foo': {
                'a': 5,
                '__type': 'Foo'
            }
        },
                        type_key='__type',
                        globals=locals())
        self.assertEqual(type(b), Bar)
        self.assertEqual(type(b.foo), Foo)
        self.assertEqual(b.foo.a, 5)
Пример #12
0
    def _check_deserialization_of_inner_iterable_of_classes(
            self, iterable_type):
        class Foo:
            pass

        @deserializer
        def deserialize_foo(_) -> Foo:
            return Foo()

        it = [{_TYPE_KEY: 'Foo'} for _ in range(5)]
        deserialized = deserialize(
            {
                _TYPE_KEY: FooContainer.__name__,
                'foo': {
                    _TYPE_KEY: iterable_type.__name__,
                    ITERABLE_VALUE_KEY: it
                }
            },
            type_key=_TYPE_KEY,
            globals=dict(locals(), **globals()))
        self.assertIsInstance(deserialized, FooContainer)
        self.assertIsInstance(deserialized.foo, iterable_type)
        self.assertEqual(len(it), len(deserialized.foo))
        for f in deserialized.foo:
            self.assertIsInstance(f, Foo)
    def test_attr_missing_fields(self):
        @attrs
        class Foo:
            a = attrib()
            bar = attrib(default=None)

        try:
            deserialize({'a': 5}, Foo)
        except:
            self.fail('Failed to deserialize with non-mandatory field missing')

        try:
            deserialize({'bar': 5}, Foo)
            self.fail('Deserialized even though mandatory field is missing')
        except:
            pass
Пример #14
0
    def test_rename_types(self):
        original = {'a': 1}
        type_key = '__type'

        class Foo:
            @staticmethod
            @serializer
            def serialize(_: 'Foo'):
                return dict(original)

        data = serialize(Foo(), type_key=type_key, fully_qualified_types=False, globals=locals())
        with self.assertRaises(TypeError):
            deserialize(dict(data), globals=locals())
        rename_types(data, type_key, {'Foo': 'builtins.dict'})
        restored = deserialize(data, type_key=type_key)
        self.assertEqual(original, restored)
Пример #15
0
    def test_enum_deserialization(self):
        class Foo(Enum):
            A = 5
            B = 89

        obj = deserialize({ENUM_VALUE_KEY: 5}, obj_type=Foo, globals=locals())
        self.assertEqual(type(obj), Foo)
        self.assertEqual(obj, Foo.A)
    def test_attr_deserialization_with_string_type_hint(self):
        @attrs
        class Foo:
            foo: Optional['Foo'] = attrib(default=None)

        foo = deserialize({'foo': {}}, Foo, type_key=None, globals=locals())
        self.assertIsInstance(foo, Foo)
        self.assertIsInstance(foo.foo, Foo)
Пример #17
0
    def test_attrs_with_only_primitives_no_type_hints(self):
        @attrs
        class Foo:
            i = attrib()
            f = attrib()
            s = attrib()
            b = attrib()
            n = attrib()

        f = Foo(i=1, f=.5, s='b', b=True, n=None)
        f2 = deserialize(serialize(f, fully_qualified_types=False), globals=locals())
        self.assertIsInstance(f2, Foo)
        self.assertEqual(f2, f)

        f2 = deserialize(serialize(f, type_key=None), obj_type=Foo)
        self.assertIsInstance(f2, Foo)
        self.assertEqual(f2, f)
    def test_attr_deserialization_with_allow_extra_fields(self):
        @attrs
        class Foo:
            pass

        foo = deserialize({'a': 5}, Foo, allow_extra_fields=True)
        self.assertIsInstance(foo, Foo)
        self.assertFalse(hasattr(foo, 'a'))
    def test_attr_deserialization(self):
        @attrs
        class Foo:
            a = attrib()

        f = deserialize({'a': 5}, Foo)
        self.assertEqual(type(f), Foo)
        self.assertEqual(f.a, 5)
Пример #20
0
        def test_dataclass_deserialization(self):
            @dataclass
            class Foo:
                a: Any

            f = deserialize({'a': 5}, Foo)
            self.assertEqual(type(f), Foo)
            self.assertEqual(f.a, 5)
Пример #21
0
        def test_dataclass_missing_fields(self):
            @dataclass
            class Foo:
                a: Any
                bar: Any = field(default=None)

            try:
                deserialize({'a': 5}, Foo, None)
            except:
                self.fail(
                    'Failed to deserialize with non-mandatory field missing')

            try:
                deserialize({'bar': 5}, Foo, None)
                self.fail(
                    'Deserialized even though mandatory field is missing')
            except:
                pass
Пример #22
0
    def test_deserializer_registration_datetime_overrides_default(self):
        _datetime = datetime.now()

        @deserializer_of(datetime)
        def foo(_) -> datetime:
            return _datetime

        self.assertEqual(_datetime,
                         deserialize({'time': 0}, datetime, type_key=None))
Пример #23
0
    def test_deserializer_registration(self):
        class Foo:
            pass

        @deserializer_of(Foo)
        def func(_):
            return Foo()

        f = deserialize({}, Foo)
        self.assertEqual(Foo, type(f))
Пример #24
0
    def test_deserializer_registration_user_defined_generic(self):
        class Foo(Generic[T]):
            pass

        @deserializer
        def func(_) -> Foo:
            return Foo()

        f = deserialize({}, Foo[int])
        self.assertIsInstance(f, Foo)
Пример #25
0
    def test_stringified_dict_key_types(self):
        original = {'a': 1, 2: 'b', True: 3}
        serialized = serialize(original, stringify_dict_keys=True)

        self.assertIsInstance(serialized, dict)
        for k in serialized.keys():
            self.assertIsInstance(k, str)

        restored = deserialize(serialized)
        self.assertEqual(original, restored)
Пример #26
0
    def test_attrs_with_list_of_primitives_without_type_hint(self):
        @attrs
        class Foo:
            l = attrib()

        f = Foo([1, 'a', True, None])
        f2 = deserialize(serialize(f, fully_qualified_types=False), globals=locals())
        self.assertIsInstance(f2, Foo)
        self.assertIsInstance(f2.l, list)
        self.assertEqual(f.l, f2.l)
Пример #27
0
    def test_enum_deserialization_case_insensitive(self):
        class Foo(Enum):
            AbC = 5
            B = 89

        obj = deserialize({ENUM_VALUE_KEY: Foo.AbC.name.lower()},
                          obj_type=Foo,
                          globals=locals())
        self.assertEqual(type(obj), Foo)
        self.assertEqual(obj, Foo.AbC)
    def test_attr_deserialization_with_non_init_field(self):
        @attrs
        class Foo:
            a: int = attrib()
            b: str = attrib(init=False)

        f = deserialize({'a': 5, 'b': 'x'}, Foo, globals=locals())
        self.assertIsInstance(f, Foo)
        self.assertEqual(5, f.a)
        self.assertEqual('x', f.b)
Пример #29
0
    def test_attrs_with_mixed_tuple_of_primitives_and_type_hints(self):
        @attrs
        class Foo:
            a: Tuple[int, str] = attrib()

        f = Foo((8, 'dfkjh'))
        f2 = deserialize(serialize(f, type_key=None, fully_qualified_types=False), Foo, globals=locals())
        self.assertIsInstance(f2, Foo)
        self.assertIsInstance(f2.a, Iterable)
        self.assertEqual(list(f.a), list(f2.a))
Пример #30
0
    def test_deserializer_registration_type_hint(self):
        class Foo:
            pass

        @deserializer
        def func(_) -> Foo:
            return Foo()

        f = deserialize({}, Foo)
        self.assertEqual(Foo, type(f))