Beispiel #1
0
    def _save_global(self, obj, name=None, pack=struct.pack):
        write = self.write
        memo = self.memo

        md = obj.__METADATA__
        
        if name is None:
            name = md.get('name')

        module = md.get('module')

        if self.proto >= 2:
            code = _extension_registry.get((module, name))
            if code:
                assert code > 0
                if code <= 0xff:
                    write(EXT1 + chr(code))
                elif code <= 0xffff:
                    write("%c%c%c" % (EXT2, code&0xff, code>>8))
                else:
                    write(EXT4 + pack("<i", code))
                return

        write(GLOBAL + module + '\n' + name + '\n')
        self.memoize(obj)
    def _save_global(self, obj, name=None, pack=struct.pack):
        write = self.write
        memo = self.memo

        md = obj.__METADATA__

        if name is None:
            name = md.get('name')

        module = md.get('module')

        if self.proto >= 2:
            code = _extension_registry.get((module, name))
            if code:
                assert code > 0
                if code <= 0xff:
                    write(EXT1 + chr(code))
                elif code <= 0xffff:
                    write("%c%c%c" % (EXT2, code & 0xff, code >> 8))
                else:
                    write(EXT4 + pack("<i", code))
                return

        write(GLOBAL + module + '\n' + name + '\n')
        self.memoize(obj)
Beispiel #3
0
    def save_global(self, obj, name=None):
        # unfortunately the pickler code is factored in a way that
        # forces us to copy/paste this function. The only change is marked
        # CHANGED below.
        write = self.write
        memo = self.memo

        # CHANGED: import module from module environment instead of __import__
        try:
            module_name, name = self.importer.get_name(obj, name)
        except (ObjNotFoundError, ObjMismatchError) as err:
            raise PicklingError(f"Can't pickle {obj}: {str(err)}") from None

        module = self.importer.import_module(module_name)
        _, parent = _getattribute(module, name)
        # END CHANGED

        if self.proto >= 2:
            code = _extension_registry.get((module_name, name))
            if code:
                assert code > 0
                if code <= 0xFF:
                    write(EXT1 + pack("<B", code))
                elif code <= 0xFFFF:
                    write(EXT2 + pack("<H", code))
                else:
                    write(EXT4 + pack("<i", code))
                return
        lastname = name.rpartition(".")[2]
        if parent is module:
            name = lastname
        # Non-ASCII identifiers are supported only with protocols >= 3.
        if self.proto >= 4:
            self.save(module_name)
            self.save(name)
            write(STACK_GLOBAL)
        elif parent is not module:
            self.save_reduce(getattr, (parent, lastname))
        elif self.proto >= 3:
            write(GLOBAL + bytes(module_name, "utf-8") + b"\n" +
                  bytes(name, "utf-8") + b"\n")
        else:
            if self.fix_imports:
                r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
                r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING
                if (module_name, name) in r_name_mapping:
                    module_name, name = r_name_mapping[(module_name, name)]
                elif module_name in r_import_mapping:
                    module_name = r_import_mapping[module_name]
            try:
                write(GLOBAL + bytes(module_name, "ascii") + b"\n" +
                      bytes(name, "ascii") + b"\n")
            except UnicodeEncodeError:
                raise PicklingError(
                    "can't pickle global identifier '%s.%s' using "
                    "pickle protocol %i" %
                    (module, name, self.proto)) from None

        self.memoize(obj)
Beispiel #4
0
def save_global_py2(obj, name=None, proto=2):

    if name is None:
        name = obj.__name__

    module = getattr(obj, "__module__", None)
    if module is None:
        module = whichmodule(obj, name)

    try:
        __import__(module)
        mod = sys.modules[module]
        klass = getattr(mod, name)
    except (ImportError, KeyError, AttributeError):
        raise PicklingError(
            "Can't pickle %r: it's not found as %s.%s" %
            (obj, module, name))
    else:
        if klass is not obj:
            raise PicklingError(
                "Can't pickle %r: it's not the same object as %s.%s" %
                (obj, module, name))

    if proto >= 2:
        code = _extension_registry.get((module, name))
        if code:
            # assert code > 0
            # if code <= 0xff:
            #     write(EXT1 + chr(code))
            # elif code <= 0xffff:
            #     write("%c%c%c" % (EXT2, code&0xff, code>>8))
            # else:
            #     write(EXT4 + pack("<i", code))
            # return
            raise H5itPicklingError(
                "h5it Can't pickle %r: extension codes "
                "are not supported yet." % obj)
    return GlobalTuple(module, name)
Beispiel #5
0
    def save_global(self, obj, name=None):
        # unfortunately the pickler code is factored in a way that
        # forces us to copy/paste this function. The only change is marked
        # CHANGED below.
        write = self.write
        memo = self.memo

        if name is None:
            name = getattr(obj, '__qualname__', None)
        if name is None:
            name = obj.__name__

        module_name = whichmodule(obj, name)
        try:
            # CHANGED: self.import_module rather than
            # __import__
            module = self.import_module(module_name)
            obj2, parent = _getattribute(module, name)
        except (ImportError, KeyError, AttributeError):
            raise PicklingError("Can't pickle %r: it's not found as %s.%s" %
                                (obj, module_name, name)) from None
        else:
            if obj2 is not obj:
                raise PicklingError(
                    "Can't pickle %r: it's not the same object as %s.%s" %
                    (obj, module_name, name))

        if self.proto >= 2:
            code = _extension_registry.get((module_name, name))
            if code:
                assert code > 0
                if code <= 0xff:
                    write(EXT1 + pack("<B", code))
                elif code <= 0xffff:
                    write(EXT2 + pack("<H", code))
                else:
                    write(EXT4 + pack("<i", code))
                return
        lastname = name.rpartition('.')[2]
        if parent is module:
            name = lastname
        # Non-ASCII identifiers are supported only with protocols >= 3.
        if self.proto >= 4:
            self.save(module_name)
            self.save(name)
            write(STACK_GLOBAL)
        elif parent is not module:
            self.save_reduce(getattr, (parent, lastname))
        elif self.proto >= 3:
            write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
                  bytes(name, "utf-8") + b'\n')
        else:
            if self.fix_imports:
                r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
                r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING
                if (module_name, name) in r_name_mapping:
                    module_name, name = r_name_mapping[(module_name, name)]
                elif module_name in r_import_mapping:
                    module_name = r_import_mapping[module_name]
            try:
                write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
                      bytes(name, "ascii") + b'\n')
            except UnicodeEncodeError:
                raise PicklingError(
                    "can't pickle global identifier '%s.%s' using "
                    "pickle protocol %i" %
                    (module, name, self.proto)) from None

        self.memoize(obj)
Beispiel #6
0
    async def save_global(self, obj, name=None):
        write = self.write
        memo = self.memo

        if name is None:
            name = getattr(obj, '__qualname__', None)
        if name is None:
            name = obj.__name__

        module_name = whichmodule(obj, name)
        try:
            __import__(module_name, level=0)
            module = sys.modules[module_name]
            obj2, parent = _getattribute(module, name)
        except (ImportError, KeyError, AttributeError):
            raise PicklingError(
                "Can't pickle %r: it's not found as %s.%s" %
                (obj, module_name, name)) from None
        else:
            if obj2 is not obj:
                raise PicklingError(
                    "Can't pickle %r: it's not the same object as %s.%s" %
                    (obj, module_name, name))

        if self.proto >= 2:
            code = _extension_registry.get((module_name, name))
            if code:
                assert code > 0
                if code <= 0xff:
                    await write(EXT1 + pack("<B", code))
                elif code <= 0xffff:
                    await write(EXT2 + pack("<H", code))
                else:
                    await write(EXT4 + pack("<i", code))
                return
        lastname = name.rpartition('.')[2]
        if parent is module:
            name = lastname
        # Non-ASCII identifiers are supported only with protocols >= 3.
        if self.proto >= 4:
            await self.save(module_name)
            await self.save(name)
            await write(STACK_GLOBAL)
        elif parent is not module:
            await self.save_reduce(getattr, (parent, lastname))
        elif self.proto >= 3:
            await write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
                        bytes(name, "utf-8") + b'\n')
        else:
            if self.fix_imports:
                r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
                r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING
                if (module_name, name) in r_name_mapping:
                    module_name, name = r_name_mapping[(module_name, name)]
                elif module_name in r_import_mapping:
                    module_name = r_import_mapping[module_name]
            try:
                await write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
                            bytes(name, "ascii") + b'\n')
            except UnicodeEncodeError:
                raise PicklingError(
                    "can't pickle global identifier '%s.%s' using "
                    "pickle protocol %i" % (module, name, self.proto)) from None

        await self.memoize(obj)
Beispiel #7
0
def save_global_py3(obj, name=None, proto=2, fix_imports=True):

    if name is None and proto >= 4:
        name = getattr(obj, '__qualname__', None)
    if name is None:
        name = obj.__name__

    module_name = whichmodule(obj, name, allow_qualname=proto >= 4)
    try:
        __import__(module_name, level=0)
        module = sys.modules[module_name]
        obj2 = _getattribute(module, name, allow_qualname=proto >= 4)
    except (ImportError, KeyError, AttributeError):
        raise PicklingError(
            "Can't pickle %r: it's not found as %s.%s" %
            (obj, module_name, name))
    else:
        if obj2 is not obj:
            raise PicklingError(
                "Can't pickle %r: it's not the same object as %s.%s" %
                (obj, module_name, name))

    if proto >= 2:
        code = _extension_registry.get((module_name, name))
        if code:
            # assert code > 0
            # if code <= 0xff:
            #     write(EXT1 + pack("<B", code))
            # elif code <= 0xffff:
            #     write(EXT2 + pack("<H", code))
            # else:
            #     write(EXT4 + pack("<i", code))
            # return
            raise H5itPicklingError("h5it Can't pickle %r: extension codes are not"
                            " supported yet." % obj)
    # Non-ASCII identifiers are supported only with protocols >= 3.
    if proto >= 4:
        # self.save(module_name)
        # self.save(name)
        # write(STACK_GLOBAL)
        raise H5itPicklingError("h5it Can't pickle %r: protocol %i is not "
                        "supported yet." % (obj, proto))
    elif proto >= 3:
        # write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
        #       bytes(name, "utf-8") + b'\n')
        raise H5itPicklingError("h5it Can't pickle %r: protocol %i is not "
                        "supported yet." % (obj, proto))
    else:
        if fix_imports:
            r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
            r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING
            if (module_name, name) in r_name_mapping:
                module_name, name = r_name_mapping[(module_name, name)]
            if module_name in r_import_mapping:
                module_name = r_import_mapping[module_name]
        try:
            return GlobalTuple(bytes(module_name, "ascii"),
                               bytes(name, "ascii"))
        except UnicodeEncodeError:
            raise PicklingError(
                "can't pickle global identifier '%s.%s' using "
                "pickle protocol %i" % (module, name, proto))
Beispiel #8
0
    def save_global(self, obj, name=None):
        # unfortunately the pickler code is factored in a way that
        # forces us to copy/paste this function. The only change is marked
        # CHANGED below.
        write = self.write
        memo = self.memo

        if name is None:
            name = getattr(obj, '__qualname__', None)
        if name is None:
            name = obj.__name__

        orig_module_name = whichmodule(obj, name)
        # CHANGED: demangle the module name before importing. If this obj came
        # out of a PackageImporter, `__module__` will be mangled. See
        # mangling.md for details.
        module_name = demangle(orig_module_name)
        try:
            # CHANGED: self.import_module rather than
            # __import__
            module = self.import_module(module_name)
            obj2, parent = _getattribute(module, name)
        except (ImportError, KeyError, AttributeError):
            raise PicklingError("Can't pickle %r: it's not found as %s.%s" %
                                (obj, module_name, name)) from None
        else:
            if obj2 is not obj:
                # CHANGED: More specific error message in the case of mangling.
                obj_module_name = getattr(obj, "__module__", orig_module_name)
                obj2_module_name = getattr(obj2, "__module__",
                                           orig_module_name)

                msg = f"Can't pickle {obj}: it's not the same object as {obj2_module_name}.{name}."

                is_obj_mangled = is_mangled(obj_module_name)
                is_obj2_mangled = is_mangled(obj2_module_name)

                if is_obj_mangled or is_obj2_mangled:
                    obj_location = (get_mangle_prefix(obj_module_name)
                                    if is_obj_mangled else
                                    "the current Python environment")
                    obj2_location = (get_mangle_prefix(obj2_module_name)
                                     if is_obj2_mangled else
                                     "the current Python environment")

                    obj_importer_name = (
                        f"the importer for {get_mangle_prefix(obj_module_name)}"
                        if is_obj_mangled else "'importlib.import_module'")
                    obj2_importer_name = (
                        f"the importer for {get_mangle_prefix(obj2_module_name)}"
                        if is_obj2_mangled else "'importlib.import_module'")

                    msg += (
                        f"\n\nThe object being pickled is from '{orig_module_name}', "
                        f"which is coming from {obj_location}."
                        f"\nHowever, when we import '{orig_module_name}', it's coming from {obj2_location}."
                        "\nTo fix this, make sure 'PackageExporter.importers' lists "
                        f"{obj_importer_name} before {obj2_importer_name}")
                raise PicklingError(msg)

        if self.proto >= 2:
            code = _extension_registry.get((module_name, name))
            if code:
                assert code > 0
                if code <= 0xff:
                    write(EXT1 + pack("<B", code))
                elif code <= 0xffff:
                    write(EXT2 + pack("<H", code))
                else:
                    write(EXT4 + pack("<i", code))
                return
        lastname = name.rpartition('.')[2]
        if parent is module:
            name = lastname
        # Non-ASCII identifiers are supported only with protocols >= 3.
        if self.proto >= 4:
            self.save(module_name)
            self.save(name)
            write(STACK_GLOBAL)
        elif parent is not module:
            self.save_reduce(getattr, (parent, lastname))
        elif self.proto >= 3:
            write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
                  bytes(name, "utf-8") + b'\n')
        else:
            if self.fix_imports:
                r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
                r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING
                if (module_name, name) in r_name_mapping:
                    module_name, name = r_name_mapping[(module_name, name)]
                elif module_name in r_import_mapping:
                    module_name = r_import_mapping[module_name]
            try:
                write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
                      bytes(name, "ascii") + b'\n')
            except UnicodeEncodeError:
                raise PicklingError(
                    "can't pickle global identifier '%s.%s' using "
                    "pickle protocol %i" %
                    (module, name, self.proto)) from None

        self.memoize(obj)