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))
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)
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
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))
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'])
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]))