Example #1
0
    def test_get_cls_from_str(self):
        self.assertEqual(str, get_cls_from_str('str', {}, None))
        self.assertEqual(int, get_cls_from_str('int', {}, None))
        self.assertEqual(list, get_cls_from_str('list', {}, None))

        class C:
            pass

        jsons.announce_class(C, 'NonExisting')

        self.assertEqual(C, get_cls_from_str('NonExisting', {}, StateHolder))
Example #2
0
    def test_load_object_without_type_hints_verbose(self):
        class A:
            def __init__(self, x):
                self.x = x

        class B:
            def __init__(self, a: A):
                self.a = a

        class C:
            def __init__(self, b: B):
                self.b = b

        dumped1 = {
            'b': {
                'a': {
                    'x': 42
                }
            },
            '-meta': {
                'classes': {
                    '/': 'jsons.C',
                    '/b': 'jsons.B',
                    '/b/a': 'jsons.A'
                }
            }
        }

        # Place the classes where they can be found.
        jsons.A = A
        jsons.B = B
        jsons.C = C
        loaded = jsons.load(dumped1)
        # Clean it up again...
        del jsons.A
        del jsons.B
        del jsons.C
        self.assertEqual(42, loaded.b.a.x)

        # Now let's test what happens when we try to load an unknown class.
        dumped2 = {'x': 100, '-meta': {'classes': {'/': 'custom_class'}}}

        with self.assertRaises(UnknownClassError):
            jsons.load(dumped2)

        try:
            jsons.load(dumped2)
        except UnknownClassError as err:
            self.assertEqual('custom_class', err.target_name)

        # Now announce the class and try again; it should work now.
        jsons.announce_class(A, 'custom_class')
        loaded2 = jsons.load(dumped2)
        self.assertEqual(100, loaded2.x)
Example #3
0
def _do_serialize(
        obj: object,
        cls: type,
        attributes: Dict[str, Optional[type]],
        kwargs: dict,
        key_transformer: Optional[Callable[[str], str]] = None,
        strip_nulls: bool = False,
        strip_privates: bool = False,
        strip_properties: bool = False,
        strip_class_variables: bool = False,
        strip_attr: Union[str, MutableSequence[str], Tuple[str]] = None,
        strict: bool = False,
        fork_inst: Optional[type] = StateHolder) -> Dict[str, object]:
    result = dict()
    is_attrs_cls = getattr(cls, '__attrs_attrs__', None) is not None
    make_attributes_public = is_attrs_cls and not strip_privates
    for attr_name, cls_ in attributes.items():
        attr = getattr(obj, attr_name)
        attr_type = cls_ or type(attr)
        announce_class(attr_type, fork_inst=fork_inst)
        serializer = get_serializer(attr_type, fork_inst)
        try:
            dumped_elem = serializer(
                attr,
                cls=cls_,
                key_transformer=key_transformer,
                strip_nulls=strip_nulls,
                strip_privates=strip_privates,
                strip_properties=strip_properties,
                strip_class_variables=strip_class_variables,
                strip_attr=strip_attr,
                **kwargs)
            _store_cls_info(dumped_elem, attr, kwargs)
        except Exception as err:
            if strict:
                raise SerializationError(message=err.args[0]) from err
            else:
                fork_inst._warn(
                    'Failed to dump attribute "{}" of object of '
                    'type "{}". Reason: {}. Ignoring the '
                    'attribute.'.format(attr, get_class_name(cls),
                                        err.args[0]),
                    'attribute-not-serialized')
                break

        if make_attributes_public:
            attr_name = attr_name.lstrip('_')
        _add_dumped_elem(result, attr_name, dumped_elem, strip_nulls,
                         key_transformer)
    return result
Example #4
0
    def test_load_object_verbose(self):
        class BarBase:
            pass

        class BarA(BarBase):
            def __init__(self, a: int):
                self.a = a

        class BarB(BarBase):
            def __init__(self, b: int):
                self.b = b

        class Foo(BarBase):
            def __init__(self, bar: BarBase):
                self.bar = bar

        jsons.announce_class(Foo)
        jsons.announce_class(BarA)
        jsons.announce_class(BarB)
        jsons.announce_class(BarBase)

        foo = Foo(bar=BarA(a=5))
        dumped = jsons.dump(foo, verbose=True)
        loaded = jsons.load(dumped)

        self.assertTrue(isinstance(loaded, Foo))
        self.assertTrue(isinstance(loaded.bar, BarA))
Example #5
0
    def test_dump_object_verbose(self):
        class A:
            def __init__(self, x):
                self.x = x

        class B:
            def __init__(self, a: A):
                self.a = a

        class C:
            def __init__(self, b: B):
                self.b = b

        c = C(B(A(42)))
        dumped = jsons.dump(c, verbose=jsons.Verbosity.WITH_CLASS_INFO)
        expectation = {
            'classes': {
                '/': 'tests.test_object.C',
                '/b': 'tests.test_object.B',
                '/b/a': 'tests.test_object.A'
            }
        }

        self.assertDictEqual(expectation, dumped['-meta'])

        # Now customize the name of the B class.
        jsons.announce_class(B, 'custom_name')
        expectation2 = {
            'classes': {
                '/': 'tests.test_object.C',
                '/b': 'custom_name',
                '/b/a': 'tests.test_object.A'
            }
        }

        dumped2 = jsons.dump(c, verbose=jsons.Verbosity.WITH_CLASS_INFO)
        self.assertDictEqual(expectation2, dumped2['-meta'])

        dumped3 = jsons.dump(c, verbose=jsons.Verbosity.WITH_NOTHING)
        self.assertDictEqual({'b': {'a': {'x': 42}}}, dumped3)

        dumped4 = jsons.dump(c, verbose=jsons.Verbosity.WITH_DUMP_TIME)
        self.assertTrue('dump_time' in dumped4['-meta'])
        self.assertTrue('classes' not in dumped4['-meta'])

        dumped5 = jsons.dump(c, verbose=jsons.Verbosity.WITH_EVERYTHING)
        self.assertTrue('dump_time' in dumped5['-meta'])
        self.assertTrue('classes' in dumped5['-meta'])
Example #6
0
    def test_dump_load_list_verbose(self):
        class Parent:
            pass

        class Child(Parent):
            pass

        class Store:
            def __init__(self, c2s: List[Parent]):
                self.c2s = c2s

        jsons.announce_class(Parent)
        jsons.announce_class(Child)
        jsons.announce_class(Store)

        s = Store([Child()])
        dumped = jsons.dump(s, verbose=True)
        loaded = jsons.load(dumped)
        self.assertEqual(Child, type(loaded.c2s[0]))