def test_instances_serialization(self, serializer): # Because dictionaries item order is not guaranteed we cannot # compare directly directlly the result obj = utils.SerializableDummy() name = reflect.canonical_name(utils.SerializableDummy) data = serializer.convert(obj) assert isinstance(data, list) assert data[0] == name assert isinstance(data[1], list) assert data[1][0] == "dictionary" dict_vals = data[1][1:] assert len(dict_vals) == 12 assert ['none', ['None']] in dict_vals assert ['set', ['set', 1, 2, 3]] in dict_vals assert ['str', 'dummy'] in dict_vals assert ['tuple', ['tuple', 1, 2, 3]] in dict_vals assert ['int', 42] in dict_vals assert ['float', 3.1415926] in dict_vals assert ['list', ['list', 1, 2, 3]] in dict_vals assert ['long', 2 ** 66] in dict_vals assert ['bool', ['boolean', 'true']] in dict_vals assert ['unicode', ['unicode', 'dummy']] in dict_vals assert ['dict', ['dictionary', [1, 2], [3, 4]]] in dict_vals assert ['ref', ['None']] in dict_vals obj = ListSerializableDummy([1, 2, 3]) name = reflect.canonical_name(ListSerializableDummy) assert serializer.convert(obj) == [name, ['list', 1, 2, 3]]
def test_method(self, builtin_module): assert ('tests.test_reflect.Dummy.spam' == reflect.canonical_name( Dummy.spam)) assert ('tests.test_reflect.Dummy.spam' == reflect.canonical_name( Dummy().spam)) assert (builtin_module + '.split' == reflect.canonical_name( 'test'.split))
def test_method(self, builtin_module): assert ( 'tests.test_reflect.Dummy.spam' == reflect.canonical_name(Dummy.spam)) assert ( 'tests.test_reflect.Dummy.spam' == reflect.canonical_name(Dummy().spam)) assert ( builtin_module + '.split' == reflect.canonical_name('test'.split))
def _lookup_restorator(self, type_name): # Lookup the registry for a IRestorator restorator = self._registry.lookup(type_name) if restorator is None: raise TypeError("Type %s not supported by unserializer %s" % (type_name, reflect.canonical_name(self))) return restorator
def flatten_unknown_value(self, value, caps, freezing): # Flatten enums if isinstance(value, enum.Enum): return self.flatten_enum_value(value, caps, freezing) # Flatten types and interfaces if isinstance(value, (type, InterfaceClass)): return self.flatten_type_value(value, caps, freezing) if self._externalizer is not None: extid = self._externalizer.identify(value) if extid is not None: return self.flatten_external(extid, caps, freezing) # Checks if value support the current required protocol # Could be ISnapshotable or ISerializable if freezing: try: snapshotable = ISnapshotable(value) except TypeError: raise_( TypeError, "Freezing of type %s values " "not supported by %s. Value = %r." % (type(value).__name__, reflect.canonical_name(self), value), sys.exc_info()[2] ) return self.flatten_instance(snapshotable, caps, freezing) else: try: serializable = ISerializable(value) except TypeError: raise_( TypeError, "Serialization of type %s values " "not supported by %s. Value = %r." % (reflect.canonical_name(value), reflect.canonical_name(self), value), sys.exc_info()[2] ) return self.flatten_instance(serializable, caps, freezing)
def flatten_unknown_value(self, value, caps, freezing): # Flatten enums if isinstance(value, enum.Enum): return self.flatten_enum_value(value, caps, freezing) # Flatten types and interfaces if isinstance(value, (type, InterfaceClass)): return self.flatten_type_value(value, caps, freezing) if self._externalizer is not None: extid = self._externalizer.identify(value) if extid is not None: return self.flatten_external(extid, caps, freezing) # Checks if value support the current required protocol # Could be ISnapshotable or ISerializable if freezing: try: snapshotable = ISnapshotable(value) except TypeError: raise_( TypeError, "Freezing of type %s values " "not supported by %s. Value = %r." % (type(value).__name__, reflect.canonical_name(self), value), sys.exc_info()[2]) return self.flatten_instance(snapshotable, caps, freezing) else: try: serializable = ISerializable(value) except TypeError: raise_( TypeError, "Serialization of type %s values " "not supported by %s. Value = %r." % (reflect.canonical_name(value), reflect.canonical_name(self), value), sys.exc_info()[2]) return self.flatten_instance(serializable, caps, freezing)
def flatten_key(self, key, caps, freezing): if not isinstance(key, bytes): if isinstance(key, unicode) and (self._force_unicode or PY3): return self.pack_unicode, key else: raise TypeError("Serializer %s is not capable of serializing " "non-string dictionary keys: %r" % (reflect.canonical_name(self), key)) # Flatten it as unicode by using the selected encoding return self.pack_unicode, key.decode(DEFAULT_ENCODING)
def test_not_referenceable(self, serializer): Klass = utils.NotReferenceableDummy Inst = pytree.Instance name = reflect.canonical_name(Klass) obj = Klass() data = serializer.convert([obj, obj]) assert data == [Inst(name, {"value": 42}), Inst(name, {"value": 42})] data = serializer.freeze([obj, obj]) assert data == [{"value": 42}, {"value": 42}]
def flatten_unknown_key(self, value, caps, freezing): # Flatten enums if isinstance(value, enum.Enum): return self.flatten_enum_key(value, caps, freezing) # Flatten types and interfaces if isinstance(value, (type, InterfaceClass)): return self.flatten_type_key(value, caps, freezing) # Instances are not supported in keys raise TypeError("Type %s keys not supported by serializer %s" % (type(value).__name__, reflect.canonical_name(self)))
def test_not_referenceable(self, serializer): Klass = utils.NotReferenceableDummy Inst = pytree.Instance name = reflect.canonical_name(Klass) obj = Klass() data = serializer.convert([obj, obj]) assert data == [ Inst(name, {"value": 42}), Inst(name, {"value": 42})] data = serializer.freeze([obj, obj]) assert data == [{"value": 42}, {"value": 42}]
def test_not_referenceable(self, serializer, helper): Klass = utils.NotReferenceableDummy name = reflect.canonical_name(Klass) obj = Klass() data = serializer.convert([obj, obj]) assert data == [ "list", [name, ["dictionary", ["value", 42]]], [name, ["dictionary", ["value", 42]]], ] data = serializer.freeze([obj, obj]) assert data == [ "list", ["dictionary", ["value", 42]], ["dictionary", ["value", 42]], ]
def _unpack_data(self, data, refid, refdata): # Just return pass-through types, # support sub-classed base types and metaclasses if set(type(data).__mro__) & self.pass_through_types: return data analysis = self.analyse_data(data) if analysis is not None: constructor, unpacker = analysis if constructor is None: # Immutable types return unpacker(self, data) if callable(constructor): # Unpack the mutable containers that provides constructor container = constructor() if container is not None: if refid is not None: self._references[refid] = (id(refdata), container) return self.delayed_unpacking(container, unpacker, self, container, data) else: # Instance type name prepared = self.prepare_instance(constructor) if prepared is None: # Immutable instance return unpacker(self, data, None, None, None) restorator, instance = prepared if refid is not None: self._references[refid] = (id(refdata), instance) return self.delayed_unpacking(instance, unpacker, self, data, refid, restorator, instance) raise TypeError("Type %s not supported by unserializer %s" % (type(data).__name__, reflect.canonical_name(self)))
def test_none(self): assert None == reflect.canonical_name(None)
def pack_enum(self, data): return [ENUM_ATOM, reflect.canonical_name(data) + "." + data.name]
def test_interface(self): assert ( 'tests.test_reflect.DummyInterface' == reflect.canonical_name(DummyInterface))
def pack_frozen_function(self, data): return reflect.canonical_name(data)
def test_function(self, builtin_module): assert 'tests.test_reflect.bacon' == reflect.canonical_name(bacon) assert builtin_module + '.getattr' == reflect.canonical_name(getattr)
def convertion_table(capabilities, freezing): # ## Basic immutable types ### yield bytes, [b"" ], str, ['[".enc", "UTF8", ""]', '[".bytes", ""]'], False yield bytes, [b"dummy"], str, [ '[".enc", "UTF8", "dummy"]', '[".bytes", "ZHVtbXk="]' ], False yield bytes, [b"\xFF"], str, ['[".bytes", "/w=="]'], False yield unicode, [u""], str, ['""'], False yield unicode, [u"dummy"], str, ['"dummy"'], False yield unicode, [u"áéí"], str, ['"\\u00e1\\u00e9\\u00ed"'], False yield [int, long], [0], str, ["0"], False yield [int, long], [42], str, ["42"], False yield [int, long], [-42], str, ["-42"], False yield [int, long], [long(0)], str, ["0"], False yield long, [2**72], str, ["4722366482869645213696"], False yield long, [-2**72], str, ["-4722366482869645213696"], False yield float, [0.0], str, ["0.0"], False yield float, [3.141], str, ["3.141"], False yield float, [-3.141], str, ["-3.141"], False yield float, [1e20], str, ["1e+20"], False yield float, [1e-22], str, ["1e-22"], False yield bool, [True], str, ["true"], False yield bool, [False], str, ["false"], False yield type(None), [None], str, ["null"], False # ## Types ### from datetime import datetime if PY3: yield type, [int], str, ['[".type", "builtins.int"]'], False else: yield type, [int], str, ['[".type", "__builtin__.int"]'], False yield (type, [datetime], str, ['[".type", "datetime.datetime"]'], False) yield (type, [utils.SerializableDummy], str, ['[".type", "tests.utils.' 'SerializableDummy"]'], False) yield (InterfaceClass, [DummyInterface], str, ['[".type", "tests.test_json.DummyInterface"]'], False) # ## Enums ### DummyEnum = utils.DummyEnum yield (DummyEnum, [DummyEnum.a], str, ['[".enum", "tests.utils.' 'DummyEnum.a"]'], False) yield (DummyEnum, [DummyEnum.c], str, ['[".enum", "tests.utils.' 'DummyEnum.c"]'], False) # ## External References ### # TODO: not working on PY3 if not PY3: if freezing: name = '[".enc", "UTF8", "%s"]' % helper.ext_val.type_name identifier = ('[".tuple", %s, %d]' % (name, id(helper.ext_val))) yield (type(helper.ext_val), [helper.ext_val], str, [identifier], False) yield (type(helper.ext_snap_val), [helper.ext_snap_val], str, [str(id(helper.ext_snap_val))], False) else: name = '[".enc", "UTF8", "%s"]' % helper.ext_val.type_name identifier = ('[".tuple", %s, %d]' % (name, id(helper.ext_val))) yield (utils.SerializableDummy, [helper.ext_val], str, ['[".ext", %s]' % identifier], False) # ## Freezing-Only Types ### if freezing: mod_name = "tests.test_json" fun_name = '"%s.dummy_function"' % mod_name meth_name = '"%s.DummyClass.dummy_method"' % mod_name yield (types.FunctionType, [dummy_function], str, [fun_name], True) yield (types.FunctionType, [DummyClass.dummy_method], str, [meth_name], True) o = DummyClass() yield (types.FunctionType, [o.dummy_method], str, [meth_name], True) # ### Basic mutable types plus tuples ### # Exception for empty tuple singleton yield tuple, [()], str, ['[".tuple"]'], False yield tuple, [(1, 2, 3)], str, ['[".tuple", 1, 2, 3]'], True yield list, [[]], str, ['[]'], True yield list, [[1, 2, 3]], str, ['[1, 2, 3]'], True yield set, [set([])], str, ['[".set"]'], True yield set, [set([1, 3])], str, ['[".set", 1, 3]'], True yield dict, [{}], str, ['{}'], True yield dict, [{"1": 2, "3": 4}], str, ['{"1": 2, "3": 4}'], True # Container with different types yield (tuple, [(0.11, b"a", u"z", False, None, (1, ), [2], set([3]), { "4": 5 })], str, [ '[".tuple", 0.11, [".enc", "UTF8", "a"], "z", false, ' 'null, [".tuple", 1], [2], [".set", 3], {"4": 5}]' ], True) yield (list, [[ 0.11, b"a", u"z", False, None, (1, ), [2], set([3]), { "4": 5 } ]], str, [ '[0.11, [".enc", "UTF8", "a"], "z", false, null, ' '[".tuple", 1], [2], [".set", 3], {"4": 5}]' ], True) # ## References and Dereferences ### # Simple reference in list a = [] b = [a, a] yield list, [b], str, ['[[".ref", 1, []], [".deref", 1]]'], True # Simple reference in tuple a = () b = (a, a) yield tuple, [b], str, [ '[".tuple", [".ref", 1, [".tuple"]], ' '[".deref", 1]]' ], True # Simple dereference in dict value. a = [] b = [a, {"1": a}] yield (list, [b], str, ['[[".ref", 1, []], {"1": [".deref", 1]}]'], True) # Simple reference in dict value. a = [] b = [{"1": a}, a] yield (list, [b], str, ['[{"1": [".ref", 1, []]}, [".deref", 1]]'], True) # Multiple reference in dictionary values, because dictionary order # is not predictable all possibilities have to be tested a = {} b = {"1": a, "2": a, "3": a} # generate all excepted resoults resoults = [] for p in permutations([1, 2, 3]): resoult_parts = [ tml % dec for dec, tml in zip(p, ('"%d": [".ref", 1, {}]', '"%d": [".deref", 1]', '"%d": [".deref", 1]')) ] resoults.extend([ '{%s}' % ', '.join(p) for p in permutations(resoult_parts) ]) yield (dict, [b], str, resoults, True) # Simple dereference in set. a = () b = [a, set([a])] yield list, [b], str, [ '[[".ref", 1, [".tuple"]], ' '[".set", [".deref", 1]]]' ], True # Simple reference in set. a = () b = [set([a]), a] yield list, [b], str, [ '[[".set", [".ref", 1, [".tuple"]]], ' '[".deref", 1]]' ], True # Multiple reference in set, because set values order # is not predictable all possibilities have to be tested a = () b = set([(1, a), (2, a)]) yield (set, [b], str, [ '[".set", [".tuple", 1, [".ref", 1, [".tuple"]]], ' '[".tuple", 2, [".deref", 1]]]', '[".set", [".tuple", 2, [".ref", 1, [".tuple"]]], ' '[".tuple", 1, [".deref", 1]]]' ], True) # List self-reference a = [] a.append(a) yield list, [a], str, ['[".ref", 1, [[".deref", 1]]]'], True # Dict self-reference a = {} a["1"] = a yield dict, [a], str, ['[".ref", 1, {"1": [".deref", 1]}]'], True # Multiple references a = [] b = [a] c = [a, b] d = [a, b, c] yield list, [d], str, [ '[[".ref", 1, []], ' '[".ref", 2, [[".deref", 1]]], ' '[[".deref", 1], [".deref", 2]]]' ], True # Default instance o = DummyClass() o.value = 42 if freezing: yield (DummyClass, [o], str, ['{"value": 42}'], True) else: name = reflect.canonical_name(o) yield (DummyClass, [o], str, [ '{".type": "%s", "value": 42}' % name, '{"value": 42, ".type": "%s"}' % name ], True) Klass = DummyClass name = reflect.canonical_name(Klass) a = Klass() b = Klass() c = Klass() a.ref = b b.ref = a c.ref = c if freezing: yield (Klass, [a], str, ['[".ref", 1, {"ref": {"ref": [".deref", 1]}}]'], True) yield (Klass, [b], str, ['[".ref", 1, {"ref": {"ref": [".deref", 1]}}]'], True) yield (Klass, [c], str, ['[".ref", 1, {"ref": [".deref", 1]}]'], True) else: yield (Klass, [a], str, [('[".ref", 1, {".type": "%s", "ref": {".type": "%s", ' '"ref": [".deref", 1]}}]') % (name, name)], True) yield (Klass, [b], str, [('[".ref", 1, {".type": "%s", "ref": {".type": "%s", ' '"ref": [".deref", 1]}}]') % (name, name)], True) yield (Klass, [c], str, [('[".ref", 1, {".type": "%s", "ref": ' '[".deref", 1]}]') % (name, )], True)
def convertion_table(capabilities, freezing): # ## Basic immutable types ### yield str, [""], str, [""], False yield str, ["dummy"], str, ["dummy"], False yield unicode, [u""], unicode, [u""], False yield unicode, [u"dummy"], unicode, [u"dummy"], False yield unicode, [u"áéí"], unicode, [u"áéí"], False yield int, [0], int, [0], False yield int, [42], int, [42], False yield int, [-42], int, [-42], False yield long, [long(0)], long, [long(0)], False yield long, [2 ** 66], long, [2 ** 66], False yield long, [-2 ** 66], long, [-2 ** 66], False yield float, [0.0], float, [0.0], False yield float, [3.1415926], float, [3.1415926], False yield float, [1e24], float, [1e24], False yield float, [1e-24], float, [1e-24], False yield bool, [True], bool, [True], False yield bool, [False], bool, [False], False yield type(None), [None], type(None), [None], False # ## Types ### from datetime import datetime yield type, [int], type, [int], False yield type, [datetime], type, [datetime], False yield (type, [utils.SerializableDummy], type, [utils.SerializableDummy], False) yield (InterfaceClass, [DummyInterface], InterfaceClass, [DummyInterface], False) # ## Enums ### DummyEnum = utils.DummyEnum yield DummyEnum, [DummyEnum.a], DummyEnum, [DummyEnum.a], False yield DummyEnum, [DummyEnum.c], DummyEnum, [DummyEnum.c], False # ## External References ### if freezing: identifier = (helper.ext_val.type_name, id(helper.ext_val)) yield (type(helper.ext_val), [helper.ext_val], tuple, [identifier], False) yield (type(helper.ext_snap_val), [helper.ext_snap_val], type(id(helper.ext_snap_val)), [id(helper.ext_snap_val)], False) else: identifier = (helper.ext_val.type_name, id(helper.ext_val)) yield (utils.SerializableDummy, [helper.ext_val], pytree.External, [pytree.External(identifier)], False) # ## Freezing-Only Types ### if freezing: mod_name = "tests.test_pytree" fun_name = mod_name + ".dummy_function" meth_name = mod_name + ".DummyClass.dummy_method" yield ( types.FunctionType, [dummy_function], str, [fun_name], True) yield (types.FunctionType, [DummyClass.dummy_method], str, [meth_name], True) o = DummyClass() yield ( types.FunctionType, [o.dummy_method], str, [meth_name], True) # ### Basic mutable types plus tuples ### # Exception for empty tuple singleton yield tuple, [()], tuple, [()], False yield tuple, [(1, 2, 3)], tuple, [(1, 2, 3)], True yield list, [[]], list, [[]], True yield list, [[1, 2, 3]], list, [[1, 2, 3]], True yield set, [set([])], set, [set([])], True yield set, [set([1, 3])], set, [set([1, 3])], True yield dict, [{}], dict, [{}], True yield dict, [{1: 2, 3: 4}], dict, [{1: 2, 3: 4}], True # Container with different types yield (tuple, [(0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5})], tuple, [(0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5})], True) yield (list, [[0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5}]], list, [[0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5}]], True) yield (set, [set([0.1, 2 ** 45, "a", u"z", False, None, (1)])], set, [set([0.1, 2 ** 45, "a", u"z", False, None, (1)])], True) yield (dict, [{0.2: 0.1, 2 ** 42: 2 ** 45, "x": "a", u"y": u"z", True: False, None: None, (-1, ): (1, ), 8: [2], 9: set([3]), 10: {4: 5}}], dict, [{0.2: 0.1, 2 ** 42: 2 ** 45, "x": "a", u"y": u"z", True: False, None: None, (-1, ): (1, ), 8: [2], 9: set([3]), 10: {4: 5}}], True) # ## References and Dereferences ### Ref = pytree.Reference Deref = pytree.Dereference # Simple reference in list a = [] b = [a, a] yield list, [b], list, [[Ref(1, []), Deref(1)]], True # Simple reference in tuple a = () b = (a, a) yield tuple, [b], tuple, [(Ref(1, ()), Deref(1))], True # Simple dereference in dict value. a = () b = [a, {1: a}] yield list, [b], list, [[Ref(1, ()), {1: Deref(1)}]], True # Simple reference in dict value. a = () b = [{1: a}, a] yield list, [b], list, [[{1: Ref(1, ())}, Deref(1)]], True # Simple dereference in dict keys. a = () b = [a, {a: 1}] yield list, [b], list, [[Ref(1, ()), {Deref(1): 1}]], True # Simple reference in dict keys. a = () b = [{a: 1}, a] yield list, [b], list, [[{Ref(1, ()): 1}, Deref(1)]], True # Multiple reference in dictionary values, because dictionary order # is not predictable all possibilities have to be tested a = {} b = {1: a, 2: a, 3: a} yield (dict, [b], dict, [{1: Ref(1, {}), 2: Deref(1), 3: Deref(1)}, {1: Deref(1), 2: Ref(1, {}), 3: Deref(1)}, {1: Deref(1), 2: Deref(1), 3: Ref(1, {})}], True) # Multiple reference in dictionary keys, because dictionary order # is not predictable all possibilities have to be tested a = (1, ) b = {(1, a): 1, (2, a): 2, (3, a): 3} yield (dict, [b], dict, [{(1, Ref(1, (1, ))): 1, (2, Deref(1)): 2, (3, Deref(1)): 3}, {(1, Deref(1)): 1, (2, Ref(1, (1, ))): 2, (3, Deref(1)): 3}, {(1, Deref(1)): 1, (2, Deref(1)): 2, (3, Ref(1, (1, ))): 3}], True) # Simple dereference in set. a = () b = [a, set([a])] yield list, [b], list, [[Ref(1, ()), set([Deref(1)])]], True # Simple reference in set. a = () b = [set([a]), a] yield list, [b], list, [[set([Ref(1, ())]), Deref(1)]], True # Multiple reference in set, because set values order # is not predictable all possibilities have to be tested a = (1, ) b = set([(1, a), (2, a), (3, a)]) yield (set, [b], set, [set([(1, Ref(1, (1, ))), (2, Deref(1)), (3, Deref(1))]), set([(1, Deref(1)), (2, Ref(1, (1, ))), (3, Deref(1))]), set([(1, Deref(1)), (2, Deref(1)), (3, Ref(1, (1, )))])], True) # List self-reference a = [] a.append(a) yield list, [a], Ref, [Ref(1, [Deref(1)])], True # Dict self-reference a = {} a[1] = a yield dict, [a], Ref, [Ref(1, {1: Deref(1)})], True # Multiple references a = [] b = [a] c = [a, b] d = [a, b, c] yield (list, [d], list, [[Ref(1, []), Ref(2, [Deref(1)]), [Deref(1), Deref(2)]]], True) # Complex structure without dict or set a = () b = (a, ) b2 = set(b) c = (a, b) c2 = [c] d = (a, b, c) d2 = [a, b2, c2] e = (b, c, d) e2 = [b2, c2, e] g = (b, b2, c, c2, d, d2, e, e2) yield (tuple, [g], tuple, [(Ref(2, (Ref(1, ()), )), Ref(4, set([Deref(1)])), Ref(3, (Deref(1), Deref(2))), Ref(5, [Deref(3)]), Ref(6, (Deref(1), Deref(2), Deref(3))), [Deref(1), Deref(4), Deref(5)], Ref(7, (Deref(2), Deref(3), Deref(6))), [Deref(4), Deref(5), Deref(7)])], True) Klass = utils.SerializableDummy name = reflect.canonical_name(Klass) if freezing: Inst = lambda v: v InstType = dict else: Inst = lambda v: pytree.Instance(name, v) InstType = pytree.Instance # Default instance o = Klass() yield (Klass, [o], InstType, [Inst({"str": "dummy", "unicode": u"dummy", "int": 42, "long": 2 ** 66, "float": 3.1415926, "bool": True, "none": None, "list": [1, 2, 3], "tuple": (1, 2, 3), "set": set([1, 2, 3]), "dict": {1: 2, 3: 4}, "ref": None})], True) Klass = DummyClass name = reflect.canonical_name(Klass) if freezing: Inst = lambda v: v InstType = dict else: Inst = lambda v: pytree.Instance(name, v) InstType = pytree.Instance a = Klass() b = Klass() c = Klass() a.ref = b b.ref = a c.ref = c yield (Klass, [a], Ref, [Ref(1, Inst({"ref": Inst({"ref": Deref(1)})}))], True) yield (Klass, [b], Ref, [Ref(1, Inst({"ref": Inst({"ref": Deref(1)})}))], True) yield (Klass, [c], Ref, [Ref(1, Inst({"ref": Deref(1)}))], True) yield (list, [[a, b]], list, [[Ref(1, Inst({"ref": Ref(2, Inst({"ref": Deref(1)}))})), Deref(2)]], True) yield (list, [[a, c]], list, [[Ref(1, Inst({"ref": Inst({"ref": Deref(1)})})), Ref(2, Inst({"ref": Deref(2)}))]], True) yield (list, [[a, [a, [a, [a]]]]], list, [[Ref(1, Inst({'ref': Inst({'ref': Deref(1)})})), [Deref(1), [Deref(1), [Deref(1)]]]]], True) yield (tuple, [(a, (a, (a, (a, ))))], tuple, [(Ref(1, Inst({'ref': Inst({'ref': Deref(1)})})), (Deref(1), (Deref(1), (Deref(1), ))))], True)
def pack_function(self, data): return [FUNCTION_ATOM, reflect.canonical_name(data)]
def pack_type(self, data): return [TYPE_ATOM, reflect.canonical_name(data)]
def check_capabilities(self, cap, value, caps, freezing): if cap not in caps: kind = "Freezer" if freezing else "Serializer" raise ValueError("%s %s do not support %s: %r" % (kind, reflect.canonical_name(self), cap.name, value))
def pack_type(self, value): return [CLASS_ATOM, reflect.canonical_name(value)]
def pack_enum(self, value): return [ENUM_ATOM, reflect.canonical_name(value), value.name]
def pack_frozen_function(self, value): return reflect.canonical_name(value)
def test_interface(self): assert ('tests.test_reflect.DummyInterface' == reflect.canonical_name( DummyInterface))
def test_class_with_meta(self): assert ('tests.test_reflect.MetaDummy' == reflect.canonical_name( MetaDummy))
def test_class_with_meta(self): assert ( 'tests.test_reflect.MetaDummy' == reflect.canonical_name(MetaDummy))
def convertion_table(capabilities, freezing): # ## Basic immutable types ### yield str, [""], str, [""], False yield str, ["dummy"], str, ["dummy"], False yield unicode, [u""], unicode, [u""], False yield unicode, [u"dummy"], unicode, [u"dummy"], False yield unicode, [u"áéí"], unicode, [u"áéí"], False yield int, [0], int, [0], False yield int, [42], int, [42], False yield int, [-42], int, [-42], False yield long, [long(0)], long, [long(0)], False yield long, [2**66], long, [2**66], False yield long, [-2**66], long, [-2**66], False yield float, [0.0], float, [0.0], False yield float, [3.1415926], float, [3.1415926], False yield float, [1e24], float, [1e24], False yield float, [1e-24], float, [1e-24], False yield bool, [True], bool, [True], False yield bool, [False], bool, [False], False yield type(None), [None], type(None), [None], False # ## Types ### from datetime import datetime yield type, [int], type, [int], False yield type, [datetime], type, [datetime], False yield (type, [utils.SerializableDummy], type, [utils.SerializableDummy], False) yield (InterfaceClass, [DummyInterface], InterfaceClass, [DummyInterface], False) # ## Enums ### DummyEnum = utils.DummyEnum yield DummyEnum, [DummyEnum.a], DummyEnum, [DummyEnum.a], False yield DummyEnum, [DummyEnum.c], DummyEnum, [DummyEnum.c], False # ## External References ### if freezing: identifier = (helper.ext_val.type_name, id(helper.ext_val)) yield (type(helper.ext_val), [helper.ext_val], tuple, [identifier], False) yield (type(helper.ext_snap_val), [helper.ext_snap_val], type(id(helper.ext_snap_val)), [id(helper.ext_snap_val)], False) else: identifier = (helper.ext_val.type_name, id(helper.ext_val)) yield (utils.SerializableDummy, [helper.ext_val], pytree.External, [pytree.External(identifier)], False) # ## Freezing-Only Types ### if freezing: mod_name = "tests.test_pytree" fun_name = mod_name + ".dummy_function" meth_name = mod_name + ".DummyClass.dummy_method" yield (types.FunctionType, [dummy_function], str, [fun_name], True) yield (types.FunctionType, [DummyClass.dummy_method], str, [meth_name], True) o = DummyClass() yield (types.FunctionType, [o.dummy_method], str, [meth_name], True) # ### Basic mutable types plus tuples ### # Exception for empty tuple singleton yield tuple, [()], tuple, [()], False yield tuple, [(1, 2, 3)], tuple, [(1, 2, 3)], True yield list, [[]], list, [[]], True yield list, [[1, 2, 3]], list, [[1, 2, 3]], True yield set, [set([])], set, [set([])], True yield set, [set([1, 3])], set, [set([1, 3])], True yield dict, [{}], dict, [{}], True yield dict, [{1: 2, 3: 4}], dict, [{1: 2, 3: 4}], True # Container with different types yield (tuple, [(0.1, 2**45, "a", u"z", False, None, (1, ), [2], set([3]), { 4: 5 })], tuple, [(0.1, 2**45, "a", u"z", False, None, (1, ), [2], set([3]), { 4: 5 })], True) yield (list, [[ 0.1, 2**45, "a", u"z", False, None, (1, ), [2], set([3]), { 4: 5 } ]], list, [[ 0.1, 2**45, "a", u"z", False, None, (1, ), [2], set([3]), { 4: 5 } ]], True) yield (set, [set([0.1, 2**45, "a", u"z", False, None, (1)])], set, [set([0.1, 2**45, "a", u"z", False, None, (1)])], True) yield (dict, [{ 0.2: 0.1, 2**42: 2**45, "x": "a", u"y": u"z", True: False, None: None, (-1, ): (1, ), 8: [2], 9: set([3]), 10: { 4: 5 } }], dict, [{ 0.2: 0.1, 2**42: 2**45, "x": "a", u"y": u"z", True: False, None: None, (-1, ): (1, ), 8: [2], 9: set([3]), 10: { 4: 5 } }], True) # ## References and Dereferences ### Ref = pytree.Reference Deref = pytree.Dereference # Simple reference in list a = [] b = [a, a] yield list, [b], list, [[Ref(1, []), Deref(1)]], True # Simple reference in tuple a = () b = (a, a) yield tuple, [b], tuple, [(Ref(1, ()), Deref(1))], True # Simple dereference in dict value. a = () b = [a, {1: a}] yield list, [b], list, [[Ref(1, ()), {1: Deref(1)}]], True # Simple reference in dict value. a = () b = [{1: a}, a] yield list, [b], list, [[{1: Ref(1, ())}, Deref(1)]], True # Simple dereference in dict keys. a = () b = [a, {a: 1}] yield list, [b], list, [[Ref(1, ()), {Deref(1): 1}]], True # Simple reference in dict keys. a = () b = [{a: 1}, a] yield list, [b], list, [[{Ref(1, ()): 1}, Deref(1)]], True # Multiple reference in dictionary values, because dictionary order # is not predictable all possibilities have to be tested a = {} b = {1: a, 2: a, 3: a} yield (dict, [b], dict, [{ 1: Ref(1, {}), 2: Deref(1), 3: Deref(1) }, { 1: Deref(1), 2: Ref(1, {}), 3: Deref(1) }, { 1: Deref(1), 2: Deref(1), 3: Ref(1, {}) }], True) # Multiple reference in dictionary keys, because dictionary order # is not predictable all possibilities have to be tested a = (1, ) b = {(1, a): 1, (2, a): 2, (3, a): 3} yield (dict, [b], dict, [{ (1, Ref(1, (1, ))): 1, (2, Deref(1)): 2, (3, Deref(1)): 3 }, { (1, Deref(1)): 1, (2, Ref(1, (1, ))): 2, (3, Deref(1)): 3 }, { (1, Deref(1)): 1, (2, Deref(1)): 2, (3, Ref(1, (1, ))): 3 }], True) # Simple dereference in set. a = () b = [a, set([a])] yield list, [b], list, [[Ref(1, ()), set([Deref(1)])]], True # Simple reference in set. a = () b = [set([a]), a] yield list, [b], list, [[set([Ref(1, ())]), Deref(1)]], True # Multiple reference in set, because set values order # is not predictable all possibilities have to be tested a = (1, ) b = set([(1, a), (2, a), (3, a)]) yield (set, [b], set, [ set([(1, Ref(1, (1, ))), (2, Deref(1)), (3, Deref(1))]), set([(1, Deref(1)), (2, Ref(1, (1, ))), (3, Deref(1))]), set([(1, Deref(1)), (2, Deref(1)), (3, Ref(1, (1, )))]) ], True) # List self-reference a = [] a.append(a) yield list, [a], Ref, [Ref(1, [Deref(1)])], True # Dict self-reference a = {} a[1] = a yield dict, [a], Ref, [Ref(1, {1: Deref(1)})], True # Multiple references a = [] b = [a] c = [a, b] d = [a, b, c] yield (list, [d], list, [[Ref(1, []), Ref(2, [Deref(1)]), [Deref(1), Deref(2)]]], True) # Complex structure without dict or set a = () b = (a, ) b2 = set(b) c = (a, b) c2 = [c] d = (a, b, c) d2 = [a, b2, c2] e = (b, c, d) e2 = [b2, c2, e] g = (b, b2, c, c2, d, d2, e, e2) yield (tuple, [g], tuple, [(Ref(2, (Ref(1, ()), )), Ref(4, set([Deref(1)])), Ref(3, (Deref(1), Deref(2))), Ref(5, [Deref(3)]), Ref(6, (Deref(1), Deref(2), Deref(3))), [Deref(1), Deref(4), Deref(5)], Ref(7, (Deref(2), Deref(3), Deref(6))), [Deref(4), Deref(5), Deref(7)])], True) Klass = utils.SerializableDummy name = reflect.canonical_name(Klass) if freezing: Inst = lambda v: v InstType = dict else: Inst = lambda v: pytree.Instance(name, v) InstType = pytree.Instance # Default instance o = Klass() yield (Klass, [o], InstType, [ Inst({ "str": "dummy", "unicode": u"dummy", "int": 42, "long": 2**66, "float": 3.1415926, "bool": True, "none": None, "list": [1, 2, 3], "tuple": (1, 2, 3), "set": set([1, 2, 3]), "dict": { 1: 2, 3: 4 }, "ref": None }) ], True) Klass = DummyClass name = reflect.canonical_name(Klass) if freezing: Inst = lambda v: v InstType = dict else: Inst = lambda v: pytree.Instance(name, v) InstType = pytree.Instance a = Klass() b = Klass() c = Klass() a.ref = b b.ref = a c.ref = c yield (Klass, [a], Ref, [Ref(1, Inst({"ref": Inst({"ref": Deref(1)})}))], True) yield (Klass, [b], Ref, [Ref(1, Inst({"ref": Inst({"ref": Deref(1)})}))], True) yield (Klass, [c], Ref, [Ref(1, Inst({"ref": Deref(1)}))], True) yield (list, [[a, b]], list, [[ Ref(1, Inst({"ref": Ref(2, Inst({"ref": Deref(1)}))})), Deref(2) ]], True) yield (list, [[a, c]], list, [[ Ref(1, Inst({"ref": Inst({"ref": Deref(1)})})), Ref(2, Inst({"ref": Deref(2)})) ]], True) yield (list, [[a, [a, [a, [a]]]]], list, [[ Ref(1, Inst({'ref': Inst({'ref': Deref(1)})})), [Deref(1), [Deref(1), [Deref(1)]]] ]], True) yield (tuple, [(a, (a, (a, (a, ))))], tuple, [(Ref(1, Inst({'ref': Inst({'ref': Deref(1)})})), (Deref(1), (Deref(1), (Deref(1), ))))], True)
def convertion_table(capabilities, freezing): ### Basic immutable types ### yield str, [""], str, [""], False yield str, ["dummy"], str, ["dummy"], False yield unicode, [u""], list, [["unicode", ""]], True yield unicode, [u"dummy"], list, [["unicode", "dummy"]], True yield (unicode, [u"áéí"], list, [["unicode", '\xc3\xa1\xc3\xa9\xc3\xad']], True) yield int, [0], int, [0], False yield int, [42], int, [42], False yield int, [-42], int, [-42], False yield long, [long(0)], long, [long(0)], False yield long, [2 ** 66], long, [2 ** 66], False yield long, [-2 ** 66], long, [-2 ** 66], False yield float, [0.0], float, [0.0], False yield float, [3.1415926], float, [3.1415926], False yield float, [1e24], float, [1e24], False yield float, [1e-24], float, [1e-24], False yield bool, [True], list, [["boolean", "true"]], True yield bool, [False], list, [["boolean", "false"]], True yield types.NoneType, [None], list, [["None"]], True ### Types ### from datetime import datetime yield type, [int], list, [["class", "__builtin__.int"]], False yield ( type, [datetime], list, [["class", "datetime.datetime"]], False) name = reflect.canonical_name( utils.SerializableDummy) yield (type, [utils.SerializableDummy], list, [["class", name]], False) name = reflect.canonical_name(DummyInterface) yield (InterfaceClass, [DummyInterface], list, [["class", name]], False) ### Enums ### DummyEnum = utils.DummyEnum name = reflect.canonical_name(DummyEnum) if Capabilities.enum_values in Capabilities: yield (DummyEnum, [DummyEnum.a], list, [["enum", name, DummyEnum.a.name]], False) yield (DummyEnum, [DummyEnum.c], list, [["enum", name, DummyEnum.c.name]], False) ### External References ### if freezing: identifier = [ "tuple", helper.ext_val.type_name, id(helper.ext_val)] yield (type(helper.ext_val), [helper.ext_val], list, [identifier], False) yield (type(helper.ext_snap_val), [helper.ext_snap_val], int, [id(helper.ext_snap_val)], False) else: identifier = [ "tuple", helper.ext_val.type_name, id(helper.ext_val)] yield (utils.SerializableDummy, [helper.ext_val], list, [["external", identifier]], False) ### Freezing-Only Types ### if freezing: mod_name = "tests.test_sexp" fun_name = mod_name + ".dummy_function" meth_name = mod_name + ".DummyClass.dummy_method" yield ( types.FunctionType, [dummy_function], str, [fun_name], True) yield (types.FunctionType, [DummyClass.dummy_method], str, [meth_name], True) o = DummyClass() yield ( types.FunctionType, [o.dummy_method], str, [meth_name], True) ### Basic containers ### # Exception for empty tuple yield tuple, [()], list, [["tuple"]], False yield tuple, [(1, 2, 3)], list, [["tuple", 1, 2, 3]], True yield list, [[]], list, [["list"]], True yield list, [[1, 2, 3]], list, [["list", 1, 2, 3]], True yield set, [set([])], list, [["set"]], True yield set, [set([1, 3])], list, [["set", 1, 3]], True yield dict, [{}], list, [["dictionary"]], True yield (dict, [{1: 2, 3: 4}], list, [["dictionary", [1, 2], [3, 4]]], True) # Tuple with various value type yield (tuple, [(0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5})], list, [["tuple", 0.1, 2 ** 45, "a", ["unicode", "z"], ["boolean", "false"], ["None"], ["tuple", 1], ["list", 2], ["set", 3], ["dictionary", [4, 5]]]], True) # List with various value type yield (list, [[0.1, 2 ** 45, "a", u"z", False, None, (1, ), [2], set([3]), {4: 5}]], list, [["list", 0.1, 2 ** 45, "a", ["unicode", "z"], ["boolean", "false"], ["None"], ["tuple", 1], ["list", 2], ["set", 3], ["dictionary", [4, 5]]]], True) # Set with various value type # Because set are not ordered every order is possible values = [0.1, 2 ** 45, "a", ["unicode", "z"], ["boolean", "false"], ["None"], ["tuple", 1]] expected = [["set"] + values] alternatives = [["set"] + list(perm) for perm in itertools.permutations(values)] yield (set, [set([0.1, 2 ** 45, "a", u"z", False, None, (1, )])], [], list, expected, alternatives, True) # Dictionary with various value type # Because dictionaries are not ordered every order is possible values = [[1, 0.1], [2, 2 ** 45], [3, "a"], [4, ["unicode", "z"]], [5, ["boolean", "false"]]] expected = [["dictionary"] + values] alternatives = [["dictionary"] + list(perm) for perm in itertools.permutations(values)] yield (dict, [{1: 0.1, 2: 2 ** 45, 3: "a", 4: u"z", 5: False}], [], list, expected, alternatives, True) values = [[6, ["None"]], [7, ["tuple", 1]], [8, ["list", 2]], [9, ["set", 3]], [0, ["dictionary", [4, 5]]]] expected = [["dictionary"] + values] alternatives = [["dictionary"] + list(perm) for perm in itertools.permutations(values)] yield (dict, [{6: None, 7: (1, ), 8: [2], 9: set([3]), 0: {4: 5}}], [], list, expected, alternatives, True) values = [[0.1, 1], [2 ** 45, 2], ["a", 3], [["unicode", "z"], 4], [["boolean", "false"], 5], [["None"], 6], [["tuple", 1], 7]] expected = [["dictionary"] + values] alternatives = [["dictionary"] + list(perm) for perm in itertools.permutations(values)] yield (dict, [{0.1: 1, 2 ** 45: 2, "a": 3, u"z": 4, False: 5, None: 6, (1, ): 7}], [], list, expected, alternatives, True) ### References and Dereferences ### Ref = lambda refid, value: ["reference", refid, value] Deref = lambda refid: ["dereference", refid] # Simple reference in list a = [] b = [a, a] yield list, [b], list, [["list", Ref(1, ["list"]), Deref(1)]], True # Simple reference in tuple a = () b = (a, a) yield ( tuple, [b], list, [["tuple", Ref(1, ["tuple"]), Deref(1)]], True) # Simple dereference in dict value. a = {} b = [a, {1: a}] yield (list, [b], list, [["list", Ref(1, ["dictionary"]), ["dictionary", [1, Deref(1)]]]], True) # Simple reference in dict value. a = set([]) b = [{1: a}, a] yield (list, [b], list, [["list", ["dictionary", [1, Ref(1, ["set"])]], Deref(1)]], True) # Simple dereference in dict keys. a = () b = [a, {a: 1}] yield (list, [b], list, [["list", Ref(1, ["tuple"]), ["dictionary", [Deref(1), 1]]]], True) # Simple reference in dict keys. a = (1, 2) b = [{a: 1}, a] yield (list, [b], list, [["list", ["dictionary", [Ref(1, ["tuple", 1, 2]), 1]], Deref(1)]], True) # Multiple reference in dictionary values, because dictionary order # is not predictable all possibilities have to be tested a = set() b = {1: a, 2: a, 3: a} values1 = [[1, Ref(1, ["set"])], [2, Deref(1)], [3, Deref(1)]] values2 = [[2, Ref(1, ["set"])], [3, Deref(1)], [1, Deref(1)]] values3 = [[3, Ref(1, ["set"])], [1, Deref(1)], [2, Deref(1)]] expected1 = [["dictionary"] + values1] expected2 = [["dictionary"] + values2] expected3 = [["dictionary"] + values3] alternatives1 = [["dictionary"] + list(perm) for perm in itertools.permutations(values1)] alternatives2 = [["dictionary"] + list(perm) for perm in itertools.permutations(values2)] alternatives3 = [["dictionary"] + list(perm) for perm in itertools.permutations(values3)] yield (dict, [b], [], list, expected1 + expected2 + expected3, alternatives1 + alternatives2 + alternatives3, True) # Multiple reference in dictionary keys, because dictionary order # is not predictable all possibilities have to be tested a = (1, ) b = {(1, a): 1, (2, a): 2, (3, a): 3} values1 = [ [["tuple", 1, Ref(1, ["tuple", 1])], 1], [["tuple", 2, Deref(1)], 2], [["tuple", 3, Deref(1)], 3]] values2 = [ [["tuple", 2, Ref(1, ["tuple", 1])], 2], [["tuple", 3, Deref(1)], 3], [["tuple", 1, Deref(1)], 1]] values3 = [ [["tuple", 3, Ref(1, ["tuple", 1])], 3], [["tuple", 1, Deref(1)], 1], [["tuple", 2, Deref(1)], 2]] expected1 = [["dictionary"] + values1] expected2 = [["dictionary"] + values2] expected3 = [["dictionary"] + values3] alternatives1 = [["dictionary"] + list(perm) for perm in itertools.permutations(values1)] alternatives2 = [["dictionary"] + list(perm) for perm in itertools.permutations(values2)] alternatives3 = [["dictionary"] + list(perm) for perm in itertools.permutations(values3)] yield (dict, [b], [], list, expected1 + expected2 + expected3, alternatives1 + alternatives2 + alternatives3, True) # Simple dereference in set. a = ("a", ) b = [a, set([a])] yield (list, [b], list, [["list", Ref(1, ["tuple", "a"]), ["set", Deref(1)]]], True) # Simple reference in set. a = ("b", ) b = [set([a]), a] yield (list, [b], list, [["list", ["set", Ref(1, ["tuple", "b"])], Deref(1)]], True) # Multiple reference in set, because set values order # is not predictable all possibilities have to be tested a = (1, ) b = set([(1, a), (2, a), (3, a)]) values1 = [["tuple", 1, Ref(1, ["tuple", 1])], ["tuple", 2, Deref(1)], ["tuple", 3, Deref(1)]] values2 = [["tuple", 2, Ref(1, ["tuple", 1])], ["tuple", 3, Deref(1)], ["tuple", 1, Deref(1)]] values3 = [["tuple", 3, Ref(1, ["tuple", 1])], ["tuple", 1, Deref(1)], ["tuple", 2, Deref(1)]] expected1 = [["set"] + values1] expected2 = [["set"] + values2] expected3 = [["set"] + values3] alternatives1 = [["set"] + list(perm) for perm in itertools.permutations(values1)] alternatives2 = [["set"] + list(perm) for perm in itertools.permutations(values2)] alternatives3 = [["set"] + list(perm) for perm in itertools.permutations(values3)] yield (set, [b], [], list, expected1 + expected2 + expected3, alternatives1 + alternatives2 + alternatives3, True) # List self-reference a = [] a.append(a) yield list, [a], list, [Ref(1, ["list", Deref(1)])], True # Dict self-reference a = {} a[1] = a yield ( dict, [a], list, [Ref(1, ["dictionary", [1, Deref(1)]])], True) # Multiple references a = [] b = [a] c = [a, b] d = [a, b, c] yield (list, [d], list, [["list", Ref(1, ["list"]), Ref(2, ["list", Deref(1)]), ["list", Deref(1), Deref(2)]]], True) # Complex structure without dict or set a = () b = (a, ) b2 = set(b) c = (a, b) c2 = [c] d = (a, b, c) d2 = [a, b2, c2] e = (b, c, d) e2 = [b2, c2, e] g = (b, b2, c, c2, d, d2, e, e2) yield (tuple, [g], list, [['tuple', Ref(2, ['tuple', Ref(1, ['tuple'])]), Ref(4, ['set', Deref(1)]), Ref(3, ['tuple', Deref(1), Deref(2)]), Ref(5, ['list', Deref(3)]), Ref(6, ['tuple', Deref(1), Deref(2), Deref(3)]), ['list', Deref(1), Deref(4), Deref(5)], Ref(7, ['tuple', Deref(2), Deref(3), Deref(6)]), ['list', Deref(4), Deref(5), Deref(7)]]], True) Klass = utils.SerializableDummy # Object instances o = Klass() # Update the instance to have only one attribute del o.set del o.dict del o.str del o.unicode del o.long del o.float del o.bool del o.none del o.list del o.tuple del o.ref o.int = 101 if freezing: yield (Klass, [o], list, [["dictionary", ["int", 101]]], True) else: yield (Klass, [o], list, [[reflect.canonical_name(Klass), ["dictionary", ["int", 101]]]], True) Klass = DummyClass name = reflect.canonical_name(Klass) if freezing: Inst = lambda v: v else: Inst = lambda v: [name, v] a = Klass() b = Klass() c = Klass() a.ref = b b.ref = a c.ref = c yield (Klass, [a], list, [Ref(1, Inst( ["dictionary", ["ref", Inst(["dictionary", ["ref", Deref(1)]])]]))], True) yield (Klass, [b], list, [Ref(1, Inst( ["dictionary", ["ref", Inst(["dictionary", ["ref", Deref(1)]])]]))], True) yield (Klass, [c], list, [Ref(1, Inst(["dictionary", ["ref", Deref(1)]]))], True) yield (list, [[a, b]], list, [["list", Ref(1, Inst( ["dictionary", ["ref", Ref(2, Inst(["dictionary", ["ref", Deref(1)]]))]])), Deref(2)]], True) yield (list, [[a, c]], list, [["list", Ref(1, Inst( ["dictionary", ["ref", Inst(["dictionary", ["ref", Deref(1)]])]])), Ref(2, Inst(["dictionary", ["ref", Deref(2)]]))]], True)
def test_class(self, builtin_module): assert 'tests.test_reflect.Dummy' == reflect.canonical_name(Dummy) assert 'tests.test_reflect.Dummy' == reflect.canonical_name(Dummy()) assert builtin_module + '.int' == reflect.canonical_name(int) assert builtin_module + '.str' == reflect.canonical_name('some string')
def check_capabilities(self, cap, value, caps, freezing): if cap not in caps: kind = "Freezer" if freezing else "Serializer" raise ValueError( "%s %s do not support %s: %r" % (kind, reflect.canonical_name(self), cap.name, value))
def convertion_table(capabilities, freezing): # ## Basic immutable types ### yield bytes, [b""], str, ['[".enc", "UTF8", ""]', '[".bytes", ""]'], False yield bytes, [b"dummy"], str, ['[".enc", "UTF8", "dummy"]', '[".bytes", "ZHVtbXk="]'], False yield bytes, [b"\xFF"], str, ['[".bytes", "/w=="]'], False yield unicode, [u""], str, ['""'], False yield unicode, [u"dummy"], str, ['"dummy"'], False yield unicode, [u"áéí"], str, ['"\\u00e1\\u00e9\\u00ed"'], False yield [int, long], [0], str, ["0"], False yield [int, long], [42], str, ["42"], False yield [int, long], [-42], str, ["-42"], False yield [int, long], [long(0)], str, ["0"], False yield long, [2 ** 72], str, ["4722366482869645213696"], False yield long, [-2 ** 72], str, ["-4722366482869645213696"], False yield float, [0.0], str, ["0.0"], False yield float, [3.141], str, ["3.141"], False yield float, [-3.141], str, ["-3.141"], False yield float, [1e20], str, ["1e+20"], False yield float, [1e-22], str, ["1e-22"], False yield bool, [True], str, ["true"], False yield bool, [False], str, ["false"], False yield type(None), [None], str, ["null"], False # ## Types ### from datetime import datetime if PY3: yield type, [int], str, ['[".type", "builtins.int"]'], False else: yield type, [int], str, ['[".type", "__builtin__.int"]'], False yield (type, [datetime], str, ['[".type", "datetime.datetime"]'], False) yield (type, [utils.SerializableDummy], str, ['[".type", "tests.utils.' 'SerializableDummy"]'], False) yield (InterfaceClass, [DummyInterface], str, ['[".type", "tests.test_json.DummyInterface"]'], False) # ## Enums ### DummyEnum = utils.DummyEnum yield (DummyEnum, [DummyEnum.a], str, ['[".enum", "tests.utils.' 'DummyEnum.a"]'], False) yield (DummyEnum, [DummyEnum.c], str, ['[".enum", "tests.utils.' 'DummyEnum.c"]'], False) # ## External References ### # TODO: not working on PY3 if not PY3: if freezing: name = '[".enc", "UTF8", "%s"]' % helper.ext_val.type_name identifier = ( '[".tuple", %s, %d]' % (name, id(helper.ext_val))) yield (type(helper.ext_val), [helper.ext_val], str, [identifier], False) yield (type(helper.ext_snap_val), [helper.ext_snap_val], str, [str(id(helper.ext_snap_val))], False) else: name = '[".enc", "UTF8", "%s"]' % helper.ext_val.type_name identifier = ( '[".tuple", %s, %d]' % (name, id(helper.ext_val))) yield (utils.SerializableDummy, [helper.ext_val], str, ['[".ext", %s]' % identifier], False) # ## Freezing-Only Types ### if freezing: mod_name = "tests.test_json" fun_name = '"%s.dummy_function"' % mod_name meth_name = '"%s.DummyClass.dummy_method"' % mod_name yield ( types.FunctionType, [dummy_function], str, [fun_name], True) yield (types.FunctionType, [DummyClass.dummy_method], str, [meth_name], True) o = DummyClass() yield ( types.FunctionType, [o.dummy_method], str, [meth_name], True) # ### Basic mutable types plus tuples ### # Exception for empty tuple singleton yield tuple, [()], str, ['[".tuple"]'], False yield tuple, [(1, 2, 3)], str, ['[".tuple", 1, 2, 3]'], True yield list, [[]], str, ['[]'], True yield list, [[1, 2, 3]], str, ['[1, 2, 3]'], True yield set, [set([])], str, ['[".set"]'], True yield set, [set([1, 3])], str, ['[".set", 1, 3]'], True yield dict, [{}], str, ['{}'], True yield dict, [{"1": 2, "3": 4}], str, ['{"1": 2, "3": 4}'], True # Container with different types yield (tuple, [(0.11, b"a", u"z", False, None, (1, ), [2], set([3]), {"4": 5})], str, ['[".tuple", 0.11, [".enc", "UTF8", "a"], "z", false, ' 'null, [".tuple", 1], [2], [".set", 3], {"4": 5}]'], True) yield (list, [[0.11, b"a", u"z", False, None, (1, ), [2], set([3]), {"4": 5}]], str, ['[0.11, [".enc", "UTF8", "a"], "z", false, null, ' '[".tuple", 1], [2], [".set", 3], {"4": 5}]'], True) # ## References and Dereferences ### # Simple reference in list a = [] b = [a, a] yield list, [b], str, ['[[".ref", 1, []], [".deref", 1]]'], True # Simple reference in tuple a = () b = (a, a) yield tuple, [b], str, ['[".tuple", [".ref", 1, [".tuple"]], ' '[".deref", 1]]'], True # Simple dereference in dict value. a = [] b = [a, {"1": a}] yield ( list, [b], str, ['[[".ref", 1, []], {"1": [".deref", 1]}]'], True) # Simple reference in dict value. a = [] b = [{"1": a}, a] yield ( list, [b], str, ['[{"1": [".ref", 1, []]}, [".deref", 1]]'], True) # Multiple reference in dictionary values, because dictionary order # is not predictable all possibilities have to be tested a = {} b = {"1": a, "2": a, "3": a} # generate all excepted resoults resoults = [] for p in permutations([1, 2, 3]): resoult_parts = [tml % dec for dec, tml in zip(p, ('"%d": [".ref", 1, {}]', '"%d": [".deref", 1]', '"%d": [".deref", 1]'))] resoults.extend( ['{%s}' % ', '.join(p) for p in permutations(resoult_parts)]) yield ( dict, [b], str, resoults, True) # Simple dereference in set. a = () b = [a, set([a])] yield list, [b], str, ['[[".ref", 1, [".tuple"]], ' '[".set", [".deref", 1]]]'], True # Simple reference in set. a = () b = [set([a]), a] yield list, [b], str, ['[[".set", [".ref", 1, [".tuple"]]], ' '[".deref", 1]]'], True # Multiple reference in set, because set values order # is not predictable all possibilities have to be tested a = () b = set([(1, a), (2, a)]) yield (set, [b], str, ['[".set", [".tuple", 1, [".ref", 1, [".tuple"]]], ' '[".tuple", 2, [".deref", 1]]]', '[".set", [".tuple", 2, [".ref", 1, [".tuple"]]], ' '[".tuple", 1, [".deref", 1]]]'], True) # List self-reference a = [] a.append(a) yield list, [a], str, ['[".ref", 1, [[".deref", 1]]]'], True # Dict self-reference a = {} a["1"] = a yield dict, [a], str, ['[".ref", 1, {"1": [".deref", 1]}]'], True # Multiple references a = [] b = [a] c = [a, b] d = [a, b, c] yield list, [d], str, ['[[".ref", 1, []], ' '[".ref", 2, [[".deref", 1]]], ' '[[".deref", 1], [".deref", 2]]]'], True # Default instance o = DummyClass() o.value = 42 if freezing: yield (DummyClass, [o], str, ['{"value": 42}'], True) else: name = reflect.canonical_name(o) yield (DummyClass, [o], str, ['{".type": "%s", "value": 42}' % name, '{"value": 42, ".type": "%s"}' % name], True) Klass = DummyClass name = reflect.canonical_name(Klass) a = Klass() b = Klass() c = Klass() a.ref = b b.ref = a c.ref = c if freezing: yield (Klass, [a], str, ['[".ref", 1, {"ref": {"ref": [".deref", 1]}}]'], True) yield (Klass, [b], str, ['[".ref", 1, {"ref": {"ref": [".deref", 1]}}]'], True) yield (Klass, [c], str, ['[".ref", 1, {"ref": [".deref", 1]}]'], True) else: yield (Klass, [a], str, [('[".ref", 1, {".type": "%s", "ref": {".type": "%s", ' '"ref": [".deref", 1]}}]') % (name, name)], True) yield (Klass, [b], str, [('[".ref", 1, {".type": "%s", "ref": {".type": "%s", ' '"ref": [".deref", 1]}}]') % (name, name)], True) yield (Klass, [c], str, [('[".ref", 1, {".type": "%s", "ref": ' '[".deref", 1]}]') % (name, )], True)