Example #1
0
    def __new_filet(self,
                    direntry=None,
                    entry=None,
                    handle=-1,
                    localpath=None,
                    name=None,
                    timestamp=None):
        newf = self.libmtp.LIBMTP_new_file_t
        newf.restype = POINTER(LIBMTP_file_struct)
        pfile = newf()
        if timestamp is None:
            pfile[0].modificationdate = c_long(long(time.time()))
        else:
            pfile[0].modificationdate = c_long(long(timestamp))
        if name is None and not entry is None:
            name = entry.get_name()

        if entry is not None:
            pfile[0].storage_id = entry.get_storage_id()
        elif direntry is not None:
            pfile[0].storage_id = direntry.get_storage_id()
        else:
            raise ValueError("Either direntry or entry must be set")

        pfile[0].item_id = 0
        pfile[0].filetype = MTPType.LIBMTP_FILETYPE_UNKNOWN
        if not entry is None:
            pfile[0].item_id = entry.get_id()
            pfile[0].filetype = MTPType.filetype(name)
            if direntry is None:
                pfile[0].parent_id = entry.get_folder_id()
        elif not localpath is None:
            if name is None:
                pfile[0].filetype = MTPType.filetype(
                    os.path.split(localpath)[1])
            else:
                pfile[0].filetype = MTPType.filetype(name)
        if not name is None:
            bname = bytes(name, 'utf8')
            pfile[0].name = cast(create_string_buffer(bname), c_char_p)

        if not direntry is None:
            pfile[0].parent_id = direntry.get_id()
        filelen = -1
        if handle >= 0:
            try:
                filelen = os.lseek(handle, 0, os.SEEK_END)
            except:
                traceback.print_exc(file=sys.stdout)
                self.log.exception("")
                filelen = -1
            finally:
                try:
                    os.lseek(handle, 0, os.SEEK_SET)
                except:
                    traceback.print_exc(file=sys.stdout)
                    self.log.exception("")
        elif not localpath is None:
            filelen = os.path.getsize(localpath)
        else:
            if not entry is None:
                filelen = entry.get_length()
            else:
                filelen = 0
        pfile[0].filesize = 0 if filelen < 0 else filelen
        return pfile
Example #2
0
        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)
Example #3
0
    def symmetry_table(self, capabilities):
        valdesc = [(Capabilities.int_values, Capabilities.int_keys,
                    [int, long], [0, -42, 42]),
                   (Capabilities.long_values, Capabilities.long_keys,
                    [int, long], [long(0)]),
                   (Capabilities.long_values, Capabilities.long_keys,
                    long, [-2 ** 66, 2 ** 66]),
                   (Capabilities.float_values, Capabilities.float_keys,
                    float, [0.0, 3.14159, -3.14159, 1.23145e23, 1.23145e-23]),
                   (Capabilities.bytes_values, Capabilities.str_keys,
                    str, ["", "spam"]),
                   # May not be valid for keys
                   (Capabilities.bytes_values, None,
                    str, ["\x00", "\n", "\xFF"]),
                   (Capabilities.unicode_values, Capabilities.unicode_keys,
                    unicode, [u"", u"hétérogénéité", u"\x00\xFF\n"]),
                   (Capabilities.bool_values, Capabilities.bool_keys,
                    bool, [True, False]),
                   (Capabilities.none_values, Capabilities.none_keys,
                    type(None), [None])]

        type_values = []
        if Capabilities.meta_types in capabilities:
            type_values.append(TestTypeSerializationDummyWithMeta)
            type_values.append(SerializableDummy)
        if Capabilities.new_style_types in capabilities:
            type_values.append(int)
            from datetime import datetime
            type_values.append(datetime)
            type_values.append(TestTypeSerializationDummy)

        if type_values:
            valdesc.append((Capabilities.type_values, Capabilities.type_keys,
                            type, type_values))
            valdesc.append((Capabilities.type_values, Capabilities.type_keys,
                            InterfaceClass, [DummyInterface]))

        def iter_values(desc):
            for cap, _, value_type, values in valdesc:
                if cap in capabilities:
                    for value in values:
                        yield value_type, value, False

        def iter_keys(desc):
            for _, cap, value_type, values in valdesc:
                if cap in capabilities:
                    for value in values:
                        yield value_type, value, False

        def cleanup_dummy_instance(o):
            if Capabilities.int_values not in capabilities:
                del o.int
            if Capabilities.long_values not in capabilities:
                del o.long
            if Capabilities.float_values not in capabilities:
                del o.float
            if Capabilities.bytes_values not in capabilities:
                del o.str
            if Capabilities.unicode_values not in capabilities:
                del o.unicode
            if Capabilities.bool_values not in capabilities:
                del o.bool
            if Capabilities.none_values not in capabilities:
                del o.none
            if Capabilities.tuple_values not in capabilities:
                del o.tuple
            if Capabilities.list_values not in capabilities:
                del o.list
            if (Capabilities.set_values not in capabilities
                    or Capabilities.int_keys not in capabilities):
                del o.set
            if (Capabilities.dict_values not in capabilities
                    or Capabilities.int_keys not in capabilities):
                del o.dict
            return o

        def iter_instances(desc):
            # Default instance
            o = SerializableDummy()
            yield SerializableDummy, cleanup_dummy_instance(o), True
            # Modified instance
            o = SerializableDummy()

            del o.int
            del o.none

            o.str = "spam"
            o.unicode = "fúúúú"
            o.long = 2 ** 44
            o.float = 2.7182818284
            o.bool = False
            o.list = ['a', 'b', 'c']
            o.tuple = ('d', 'e', 'f')
            o.set = set(['g', 'h', 'i'])
            o.dict = {'j': 1, 'k': 2, 'l': 3}

            yield SerializableDummy, cleanup_dummy_instance(o), True

            yield NotReferenceableDummy, NotReferenceableDummy(), True

        def iter_externals(desc):
            yield SerializableDummy, self.ext_val, False

        def iter_all_values(desc, stop=False, immutable=False):
            values = [v for _, v, _ in iter_values(desc)]
            if not immutable:
                if Capabilities.instance_values in capabilities:
                    values += [v for _, v, _ in iter_instances(desc)]
                if Capabilities.enum_values in capabilities:
                    values += [v for _, v, _ in iter_enums(desc)]
            if not stop:
                if Capabilities.tuple_values in capabilities:
                    values += [v for _, v, _ in
                               iter_tuples(desc, True, immutable)]
                if not immutable:
                    if Capabilities.list_values in capabilities:
                        values += [v for _, v, _ in iter_lists(desc, True)]
                    if Capabilities.set_values in capabilities:
                        values += [v for _, v, _ in iter_sets(desc, True)]
                    if Capabilities.dict_values in capabilities:
                        values += [v for _, v, _ in iter_dicts(desc, True)]
            return values

        def iter_all_keys(desc, stop=False):
            values = [v for _, v, _ in iter_keys(desc)]
            if Capabilities.enum_keys in capabilities:
                values += [v for _, v, _ in iter_enums(desc)]
            if not stop:
                if Capabilities.tuple_keys in capabilities:
                    values += [v for _, v, _ in iter_tuples(desc, True, True)]
            return values

        def iter_enums(desc):
            # Because enums cannot be compared with anything else
            # we can't put it in the description table
            yield DummyEnum, DummyEnum.a, False
            yield DummyEnum, DummyEnum.c, False

        def iter_tuples(desc, stop=False, immutable=False):
            yield tuple, (), False  # Exception for empty tuple singleton
            # A tuple for each possible values
            for v in iter_all_values(desc, stop, immutable):
                yield tuple, tuple([v]), True
            # One big tuple with everything supported in it
            yield tuple, tuple(iter_all_values(desc, stop, immutable)), True

        def iter_lists(desc, stop=False):
            yield list, [], True
            # A list for each possible values
            for v in iter_all_values(desc, stop):
                yield list, [v], True
            # One big list with everything supported in it
            yield list, iter_all_values(desc, stop), True

        def iter_sets(desc, stop=False):
            yield set, set([]), True
            # A set for each possible values
            for v in iter_all_keys(desc, stop):
                yield set, set([v]), True
            # Enums cannot be mixed with other values
            yield (set, set([v for v in iter_all_keys(desc, stop)
                             if isinstance(v, enum.Enum)]), True)
            # One big set with everything supported in it
            yield (set, set([v for v in iter_all_keys(desc, stop)
                             if not isinstance(v, enum.Enum)]), True)

        def iter_dicts(desc, stop=False):
            yield dict, {}, True
            # Enums cannot be mixed with other values
            d = {}
            for k in iter_all_keys(desc, stop):
                if isinstance(k, enum.Enum):
                    d[k] = None
            yield dict, d, True
            # Big dicts for every supported values and keys
            values = iter(iter_all_values(desc, stop))
            done = False
            while not done:
                d = {}
                for k in iter_all_keys(desc, stop):
                    if not isinstance(k, enum.Enum):
                        try:
                            v = next(values)
                        except StopIteration:
                            # Loop back to the first value
                            values = iter(iter_all_values(desc, stop))
                            v = next(values)  # At least there is one value
                            done = True
                        d[k] = v
                yield dict, d, True

        def iter_all(desc):
            iterators = [iter_values(desc)]
            if Capabilities.enum_values in capabilities:
                iterators.append(iter_enums(desc))
            if Capabilities.instance_values in capabilities:
                iterators.append(iter_instances(desc))
            if Capabilities.tuple_values in capabilities:
                iterators.append(iter_tuples(desc))
            if Capabilities.list_values in capabilities:
                iterators.append(iter_lists(desc))
            if Capabilities.set_values in capabilities:
                iterators.append(iter_sets(desc))
            if Capabilities.dict_values in capabilities:
                iterators.append(iter_dicts(desc))
            if Capabilities.external_values in capabilities:
                iterators.append(iter_externals(desc))
            return itertools.chain(*iterators)

        for record in iter_all(valdesc):
            value_type, value, should_mutate = record
            yield value_type, [value], should_mutate

        if Capabilities.circular_references in capabilities:
            # get supported values, keys and referencable
            values = iter_values(valdesc)
            _, X, _ = next(values)
            _, Y, _ = next(values)

            keys = iter_keys(valdesc)
            _, K, _ = next(keys)
            _, L, _ = next(keys)

            if Capabilities.list_values in capabilities:
                Z = [X, Y]
            elif Capabilities.tuple_values in capabilities:
                Z = (X, Y)
            elif Capabilities.set_values in capabilities:
                Z = set([X, Y])
            elif Capabilities.dict_values in capabilities:
                Z = dict([X, Y])
            else:
                self.fail("Converter support circular references but do not "
                          "supporte any referencable types")

            if Capabilities.list_values in capabilities:
                # Reference in list
                yield list, [[Z, Z]], True
                yield list, [[Z, [Z, [Z], Z], Z]], True

                # List self-references
                a = []
                a.append(a)
                yield list, [a], True

                a = []
                b = [a]
                a.append(b)
                yield list, [b], True

            if Capabilities.tuple_values in capabilities:
                # Reference in tuple
                yield tuple, [(Z, Z)], True
                yield tuple, [(Z, (Z, (Z, ), Z), Z)], True

            if Capabilities.dict_values in capabilities:
                # Reference in dictionary value
                yield dict, [{K: Z, L: Z}], True
                yield dict, [{K: Z, L: {L: Z, K: {K: Z}}}], True

                # Dictionary self-references
                a = {}
                a[K] = a
                yield dict, [a], True

                a = {}
                b = {K: a}
                a[K] = b
                yield dict, [a], True

                if (Capabilities.tuple_keys in capabilities
                        and Capabilities.list_values in capabilities):
                    a = (K, L)

                    # Dereference in dictionary keys.
                    yield list, [[a, {a: X}]], True

                    # Reference in dictionary keys.
                    yield list, [[{a: Y}, a]], True

                    # Multiple reference in dictionary keys
                    a = (K, L)
                    yield dict, [{(K, a): X, (L, a): Y}], True

            if (Capabilities.set_values in capabilities
                    and Capabilities.tuple_keys in capabilities
                    and Capabilities.list_values in capabilities):

                a = (K, L)
                # Dereference in set.
                yield list, [[a, set([a])]], True

                # Reference in set.
                yield list, [[set([a]), a]], True

                # Multiple reference in set
                b = set([(K, a), (L, a)])
                yield set, [b], True

            if (Capabilities.tuple_values in capabilities
                    and Capabilities.list_values in capabilities
                    and Capabilities.dict_values in capabilities
                    and Capabilities.tuple_keys in capabilities
                    and Capabilities.list_values in capabilities):

                # Complex structure
                a = (K, L)
                b = (a, )
                b2 = set(b)
                c = (a, b)
                c2 = {a: b2, b: c}
                d = (a, b, c)
                d2 = [a, b2, c2]
                e = (b, c, d)
                e2 = [b2, c2, e]
                c2[e] = e2  # Make a cycle
                yield dict, [{b: b2, c: c2, d: d2, e: e2}], True

            if Capabilities.instance_values in capabilities:
                # complex references in instances
                o1 = SerializableDummy()
                o2 = SerializableDummy()
                o3 = SerializableDummy()

                # remove unsupported attributes
                o1 = cleanup_dummy_instance(o1)
                o2 = cleanup_dummy_instance(o2)
                o3 = cleanup_dummy_instance(o3)

                o1.dict = {K: X}
                o2.tuple = (X, )
                o3.list = [Y]

                o1.ref = o2
                o2.ref = o1
                o3.ref = o3
                o1.list = o3.list
                o2.dict = o1.dict
                o3.tuple = o2.tuple

                yield SerializableDummy, [o1], True
                yield SerializableDummy, [o2], True
                yield SerializableDummy, [o3], True

                if Capabilities.list_values in capabilities:
                    yield list, [[o1, o2]], True
                    yield list, [[o2, o1]], True
                    yield list, [[o1, o3]], True
                    yield list, [[o3, o1]], True
                    yield list, [[o2, o3]], True
                    yield list, [[o3, o2]], True
                    yield list, [[o1, o2, o3]], True
                    yield list, [[o3, o1, o2]], True
Example #4
0
def get_long():
    from past.types import long

    return long("1")
        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)
Example #6
0
        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)
Example #8
0
    def symmetry_table(self, capabilities):
        valdesc = [
            (Capabilities.int_values, Capabilities.int_keys, [int, long],
             [0, -42, 42]),
            (Capabilities.long_values, Capabilities.long_keys, [int, long],
             [long(0)]),
            (Capabilities.long_values, Capabilities.long_keys, long,
             [-2**66, 2**66]),
            (Capabilities.float_values, Capabilities.float_keys, float,
             [0.0, 3.14159, -3.14159, 1.23145e23, 1.23145e-23]),
            (Capabilities.bytes_values, Capabilities.str_keys, str,
             ["", "spam"]),
            # May not be valid for keys
            (Capabilities.bytes_values, None, str, ["\x00", "\n", "\xFF"]),
            (Capabilities.unicode_values, Capabilities.unicode_keys, unicode,
             [u"", u"hétérogénéité", u"\x00\xFF\n"]),
            (Capabilities.bool_values, Capabilities.bool_keys, bool,
             [True, False]),
            (Capabilities.none_values, Capabilities.none_keys, type(None),
             [None])
        ]

        type_values = []
        if Capabilities.meta_types in capabilities:
            type_values.append(TestTypeSerializationDummyWithMeta)
            type_values.append(SerializableDummy)
        if Capabilities.new_style_types in capabilities:
            type_values.append(int)
            from datetime import datetime
            type_values.append(datetime)
            type_values.append(TestTypeSerializationDummy)

        if type_values:
            valdesc.append((Capabilities.type_values, Capabilities.type_keys,
                            type, type_values))
            valdesc.append((Capabilities.type_values, Capabilities.type_keys,
                            InterfaceClass, [DummyInterface]))

        def iter_values(desc):
            for cap, _, value_type, values in valdesc:
                if cap in capabilities:
                    for value in values:
                        yield value_type, value, False

        def iter_keys(desc):
            for _, cap, value_type, values in valdesc:
                if cap in capabilities:
                    for value in values:
                        yield value_type, value, False

        def cleanup_dummy_instance(o):
            if Capabilities.int_values not in capabilities:
                del o.int
            if Capabilities.long_values not in capabilities:
                del o.long
            if Capabilities.float_values not in capabilities:
                del o.float
            if Capabilities.bytes_values not in capabilities:
                del o.str
            if Capabilities.unicode_values not in capabilities:
                del o.unicode
            if Capabilities.bool_values not in capabilities:
                del o.bool
            if Capabilities.none_values not in capabilities:
                del o.none
            if Capabilities.tuple_values not in capabilities:
                del o.tuple
            if Capabilities.list_values not in capabilities:
                del o.list
            if (Capabilities.set_values not in capabilities
                    or Capabilities.int_keys not in capabilities):
                del o.set
            if (Capabilities.dict_values not in capabilities
                    or Capabilities.int_keys not in capabilities):
                del o.dict
            return o

        def iter_instances(desc):
            # Default instance
            o = SerializableDummy()
            yield SerializableDummy, cleanup_dummy_instance(o), True
            # Modified instance
            o = SerializableDummy()

            del o.int
            del o.none

            o.str = "spam"
            o.unicode = "fúúúú"
            o.long = 2**44
            o.float = 2.7182818284
            o.bool = False
            o.list = ['a', 'b', 'c']
            o.tuple = ('d', 'e', 'f')
            o.set = set(['g', 'h', 'i'])
            o.dict = {'j': 1, 'k': 2, 'l': 3}

            yield SerializableDummy, cleanup_dummy_instance(o), True

            yield NotReferenceableDummy, NotReferenceableDummy(), True

        def iter_externals(desc):
            yield SerializableDummy, self.ext_val, False

        def iter_all_values(desc, stop=False, immutable=False):
            values = [v for _, v, _ in iter_values(desc)]
            if not immutable:
                if Capabilities.instance_values in capabilities:
                    values += [v for _, v, _ in iter_instances(desc)]
                if Capabilities.enum_values in capabilities:
                    values += [v for _, v, _ in iter_enums(desc)]
            if not stop:
                if Capabilities.tuple_values in capabilities:
                    values += [
                        v for _, v, _ in iter_tuples(desc, True, immutable)
                    ]
                if not immutable:
                    if Capabilities.list_values in capabilities:
                        values += [v for _, v, _ in iter_lists(desc, True)]
                    if Capabilities.set_values in capabilities:
                        values += [v for _, v, _ in iter_sets(desc, True)]
                    if Capabilities.dict_values in capabilities:
                        values += [v for _, v, _ in iter_dicts(desc, True)]
            return values

        def iter_all_keys(desc, stop=False):
            values = [v for _, v, _ in iter_keys(desc)]
            if Capabilities.enum_keys in capabilities:
                values += [v for _, v, _ in iter_enums(desc)]
            if not stop:
                if Capabilities.tuple_keys in capabilities:
                    values += [v for _, v, _ in iter_tuples(desc, True, True)]
            return values

        def iter_enums(desc):
            # Because enums cannot be compared with anything else
            # we can't put it in the description table
            yield DummyEnum, DummyEnum.a, False
            yield DummyEnum, DummyEnum.c, False

        def iter_tuples(desc, stop=False, immutable=False):
            yield tuple, (), False  # Exception for empty tuple singleton
            # A tuple for each possible values
            for v in iter_all_values(desc, stop, immutable):
                yield tuple, tuple([v]), True
            # One big tuple with everything supported in it
            yield tuple, tuple(iter_all_values(desc, stop, immutable)), True

        def iter_lists(desc, stop=False):
            yield list, [], True
            # A list for each possible values
            for v in iter_all_values(desc, stop):
                yield list, [v], True
            # One big list with everything supported in it
            yield list, iter_all_values(desc, stop), True

        def iter_sets(desc, stop=False):
            yield set, set([]), True
            # A set for each possible values
            for v in iter_all_keys(desc, stop):
                yield set, set([v]), True
            # Enums cannot be mixed with other values
            yield (set,
                   set([
                       v for v in iter_all_keys(desc, stop)
                       if isinstance(v, enum.Enum)
                   ]), True)
            # One big set with everything supported in it
            yield (set,
                   set([
                       v for v in iter_all_keys(desc, stop)
                       if not isinstance(v, enum.Enum)
                   ]), True)

        def iter_dicts(desc, stop=False):
            yield dict, {}, True
            # Enums cannot be mixed with other values
            d = {}
            for k in iter_all_keys(desc, stop):
                if isinstance(k, enum.Enum):
                    d[k] = None
            yield dict, d, True
            # Big dicts for every supported values and keys
            values = iter(iter_all_values(desc, stop))
            done = False
            while not done:
                d = {}
                for k in iter_all_keys(desc, stop):
                    if not isinstance(k, enum.Enum):
                        try:
                            v = next(values)
                        except StopIteration:
                            # Loop back to the first value
                            values = iter(iter_all_values(desc, stop))
                            v = next(values)  # At least there is one value
                            done = True
                        d[k] = v
                yield dict, d, True

        def iter_all(desc):
            iterators = [iter_values(desc)]
            if Capabilities.enum_values in capabilities:
                iterators.append(iter_enums(desc))
            if Capabilities.instance_values in capabilities:
                iterators.append(iter_instances(desc))
            if Capabilities.tuple_values in capabilities:
                iterators.append(iter_tuples(desc))
            if Capabilities.list_values in capabilities:
                iterators.append(iter_lists(desc))
            if Capabilities.set_values in capabilities:
                iterators.append(iter_sets(desc))
            if Capabilities.dict_values in capabilities:
                iterators.append(iter_dicts(desc))
            if Capabilities.external_values in capabilities:
                iterators.append(iter_externals(desc))
            return itertools.chain(*iterators)

        for record in iter_all(valdesc):
            value_type, value, should_mutate = record
            yield value_type, [value], should_mutate

        if Capabilities.circular_references in capabilities:
            # get supported values, keys and referencable
            values = iter_values(valdesc)
            _, X, _ = next(values)
            _, Y, _ = next(values)

            keys = iter_keys(valdesc)
            _, K, _ = next(keys)
            _, L, _ = next(keys)

            if Capabilities.list_values in capabilities:
                Z = [X, Y]
            elif Capabilities.tuple_values in capabilities:
                Z = (X, Y)
            elif Capabilities.set_values in capabilities:
                Z = set([X, Y])
            elif Capabilities.dict_values in capabilities:
                Z = dict([X, Y])
            else:
                self.fail("Converter support circular references but do not "
                          "supporte any referencable types")

            if Capabilities.list_values in capabilities:
                # Reference in list
                yield list, [[Z, Z]], True
                yield list, [[Z, [Z, [Z], Z], Z]], True

                # List self-references
                a = []
                a.append(a)
                yield list, [a], True

                a = []
                b = [a]
                a.append(b)
                yield list, [b], True

            if Capabilities.tuple_values in capabilities:
                # Reference in tuple
                yield tuple, [(Z, Z)], True
                yield tuple, [(Z, (Z, (Z, ), Z), Z)], True

            if Capabilities.dict_values in capabilities:
                # Reference in dictionary value
                yield dict, [{K: Z, L: Z}], True
                yield dict, [{K: Z, L: {L: Z, K: {K: Z}}}], True

                # Dictionary self-references
                a = {}
                a[K] = a
                yield dict, [a], True

                a = {}
                b = {K: a}
                a[K] = b
                yield dict, [a], True

                if (Capabilities.tuple_keys in capabilities
                        and Capabilities.list_values in capabilities):
                    a = (K, L)

                    # Dereference in dictionary keys.
                    yield list, [[a, {a: X}]], True

                    # Reference in dictionary keys.
                    yield list, [[{a: Y}, a]], True

                    # Multiple reference in dictionary keys
                    a = (K, L)
                    yield dict, [{(K, a): X, (L, a): Y}], True

            if (Capabilities.set_values in capabilities
                    and Capabilities.tuple_keys in capabilities
                    and Capabilities.list_values in capabilities):

                a = (K, L)
                # Dereference in set.
                yield list, [[a, set([a])]], True

                # Reference in set.
                yield list, [[set([a]), a]], True

                # Multiple reference in set
                b = set([(K, a), (L, a)])
                yield set, [b], True

            if (Capabilities.tuple_values in capabilities
                    and Capabilities.list_values in capabilities
                    and Capabilities.dict_values in capabilities
                    and Capabilities.tuple_keys in capabilities
                    and Capabilities.list_values in capabilities):

                # Complex structure
                a = (K, L)
                b = (a, )
                b2 = set(b)
                c = (a, b)
                c2 = {a: b2, b: c}
                d = (a, b, c)
                d2 = [a, b2, c2]
                e = (b, c, d)
                e2 = [b2, c2, e]
                c2[e] = e2  # Make a cycle
                yield dict, [{b: b2, c: c2, d: d2, e: e2}], True

            if Capabilities.instance_values in capabilities:
                # complex references in instances
                o1 = SerializableDummy()
                o2 = SerializableDummy()
                o3 = SerializableDummy()

                # remove unsupported attributes
                o1 = cleanup_dummy_instance(o1)
                o2 = cleanup_dummy_instance(o2)
                o3 = cleanup_dummy_instance(o3)

                o1.dict = {K: X}
                o2.tuple = (X, )
                o3.list = [Y]

                o1.ref = o2
                o2.ref = o1
                o3.ref = o3
                o1.list = o3.list
                o2.dict = o1.dict
                o3.tuple = o2.tuple

                yield SerializableDummy, [o1], True
                yield SerializableDummy, [o2], True
                yield SerializableDummy, [o3], True

                if Capabilities.list_values in capabilities:
                    yield list, [[o1, o2]], True
                    yield list, [[o2, o1]], True
                    yield list, [[o1, o3]], True
                    yield list, [[o3, o1]], True
                    yield list, [[o2, o3]], True
                    yield list, [[o3, o2]], True
                    yield list, [[o1, o2, o3]], True
                    yield list, [[o3, o1, o2]], True
        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)