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