def load_module(self, fullname): """load_module(fullname) -> module. Load the module specified by 'fullname'. 'fullname' must be the fully qualified (dotted) module name. It returns the imported module, or raises ZipImportError if it could not be imported. Deprecated since Python 3.10. Use exec_module() instead. """ msg = ( "zipimport.zipimporter.load_module() is deprecated and slated for " "removal in Python 3.12; use exec_module() instead") _warnings.warn(msg, DeprecationWarning) code, ispackage, modpath = _get_module_code(self, fullname) mod = sys.modules.get(fullname) if mod is None or not isinstance(mod, _module_type): mod = _module_type(fullname) sys.modules[fullname] = mod mod.__loader__ = self try: if ispackage: # add __path__ to the module *before* the code gets # executed path = _get_module_path(self, fullname) fullpath = _bootstrap_external._path_join(self.archive, path) mod.__path__ = [fullpath] if not hasattr(mod, '__builtins__'): mod.__builtins__ = __builtins__ _bootstrap_external._fix_up_module(mod.__dict__, fullname, modpath) exec(code, mod.__dict__) except: del sys.modules[fullname] raise try: mod = sys.modules[fullname] except KeyError: raise ImportError( f'Loaded module {fullname!r} not found in sys.modules') _bootstrap._verbose_message('import {} # loaded from Zip {}', fullname, modpath) return mod
def __init__(self, path): if not isinstance(path, str): import os path = os.fsdecode(path) if not path: raise ZipImportError('archive path is empty', path=path) if alt_path_sep: path = path.replace(alt_path_sep, path_sep) prefix = [] while True: try: st = _bootstrap_external._path_stat(path) except (OSError, ValueError): # On Windows a ValueError is raised for too long paths. # Back up one path element. dirname, basename = _bootstrap_external._path_split(path) if dirname == path: raise ZipImportError('not a Zip file', path=path) path = dirname prefix.append(basename) else: # it exists if (st.st_mode & 0o170000) != 0o100000: # stat.S_ISREG # it's a not file raise ZipImportError('not a Zip file', path=path) break try: files = _zip_directory_cache[path] except KeyError: files = _read_directory(path) _zip_directory_cache[path] = files self._files = files self.archive = path # a prefix directory following the ZIP file path. self.prefix = _bootstrap_external._path_join(*prefix[::-1]) if self.prefix: self.prefix += path_sep
def load_module(self, fullname): """load_module(fullname) -> module. Load the module specified by 'fullname'. 'fullname' must be the fully qualified (dotted) module name. It returns the imported module, or raises ZipImportError if it wasn't found. """ code, ispackage, modpath = _get_module_code(self, fullname) mod = sys.modules.get(fullname) if mod is None or not isinstance(mod, _module_type): mod = _module_type(fullname) sys.modules[fullname] = mod mod.__loader__ = self try: if ispackage: # add __path__ to the module *before* the code gets # executed path = _get_module_path(self, fullname) fullpath = _bootstrap_external._path_join(self.archive, path) mod.__path__ = [fullpath] if not hasattr(mod, '__builtins__'): mod.__builtins__ = __builtins__ _bootstrap_external._fix_up_module(mod.__dict__, fullname, modpath) exec(code, mod.__dict__) except: del sys.modules[fullname] raise try: mod = sys.modules[fullname] except KeyError: raise ImportError( f'Loaded module {fullname!r} not found in sys.modules') _bootstrap._verbose_message('import {} # loaded from Zip {}', fullname, modpath) return mod
def get_source(self, fullname): """get_source(fullname) -> source string. Return the source code for the specified module. Raise ZipImportError if the module couldn't be found, return None if the archive does contain the module, but has no source for it. """ mi = _get_module_info(self, fullname) if mi is None: raise ZipImportError(f"can't find module {fullname!r}", name=fullname) path = _get_module_path(self, fullname) if mi: fullpath = _bootstrap_external._path_join(path, '__init__.py') else: fullpath = f'{path}.py' try: toc_entry = self._files[fullpath] except KeyError: # we have the module, but no source return None return _get_data(self.archive, toc_entry).decode()
def load_module(self, fullname): """load_module(fullname) -> module. Load the module specified by 'fullname'. 'fullname' must be the fully qualified (dotted) module name. It returns the imported module, or raises ZipImportError if it wasn't found. """ code, ispackage, modpath = _get_module_code(self, fullname) mod = sys.modules.get(fullname) if mod is None or not isinstance(mod, _module_type): mod = _module_type(fullname) sys.modules[fullname] = mod mod.__loader__ = self try: if ispackage: # add __path__ to the module *before* the code gets # executed path = _get_module_path(self, fullname) fullpath = _bootstrap_external._path_join(self.archive, path) mod.__path__ = [fullpath] if not hasattr(mod, '__builtins__'): mod.__builtins__ = __builtins__ _bootstrap_external._fix_up_module(mod.__dict__, fullname, modpath) exec(code, mod.__dict__) except: del sys.modules[fullname] raise try: mod = sys.modules[fullname] except KeyError: raise ImportError(f'Loaded module {fullname!r} not found in sys.modules') _bootstrap._verbose_message('import {} # loaded from Zip {}', fullname, modpath) return mod
def _read_directory(archive): try: fp = _io.open_code(archive) except OSError: raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive) with fp: try: fp.seek(-END_CENTRAL_DIR_SIZE, 2) header_position = fp.tell() buffer = fp.read(END_CENTRAL_DIR_SIZE) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if len(buffer) != END_CENTRAL_DIR_SIZE: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if buffer[:4] != STRING_END_ARCHIVE: # Bad: End of Central Dir signature # Check if there's a comment. try: fp.seek(0, 2) file_size = fp.tell() except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) max_comment_start = max( file_size - MAX_COMMENT_LEN - END_CENTRAL_DIR_SIZE, 0) try: fp.seek(max_comment_start) data = fp.read() except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) pos = data.rfind(STRING_END_ARCHIVE) if pos < 0: raise ZipImportError(f'not a Zip file: {archive!r}', path=archive) buffer = data[pos:pos + END_CENTRAL_DIR_SIZE] if len(buffer) != END_CENTRAL_DIR_SIZE: raise ZipImportError(f"corrupt Zip file: {archive!r}", path=archive) header_position = file_size - len(data) + pos header_size = _unpack_uint32(buffer[12:16]) header_offset = _unpack_uint32(buffer[16:20]) if header_position < header_size: raise ZipImportError(f'bad central directory size: {archive!r}', path=archive) if header_position < header_offset: raise ZipImportError(f'bad central directory offset: {archive!r}', path=archive) header_position -= header_size arc_offset = header_position - header_offset if arc_offset < 0: raise ZipImportError( f'bad central directory size or offset: {archive!r}', path=archive) files = {} # Start of Central Directory count = 0 try: fp.seek(header_position) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) while True: buffer = fp.read(46) if len(buffer) < 4: raise EOFError('EOF read where not expected') # Start of file header if buffer[:4] != b'PK\x01\x02': break # Bad: Central Dir File Header if len(buffer) != 46: raise EOFError('EOF read where not expected') flags = _unpack_uint16(buffer[8:10]) compress = _unpack_uint16(buffer[10:12]) time = _unpack_uint16(buffer[12:14]) date = _unpack_uint16(buffer[14:16]) crc = _unpack_uint32(buffer[16:20]) data_size = _unpack_uint32(buffer[20:24]) file_size = _unpack_uint32(buffer[24:28]) name_size = _unpack_uint16(buffer[28:30]) extra_size = _unpack_uint16(buffer[30:32]) comment_size = _unpack_uint16(buffer[32:34]) file_offset = _unpack_uint32(buffer[42:46]) header_size = name_size + extra_size + comment_size if file_offset > header_offset: raise ZipImportError(f'bad local header offset: {archive!r}', path=archive) file_offset += arc_offset try: name = fp.read(name_size) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if len(name) != name_size: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) # On Windows, calling fseek to skip over the fields we don't use is # slower than reading the data because fseek flushes stdio's # internal buffers. See issue #8745. try: if len(fp.read(header_size - name_size)) != header_size - name_size: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if flags & 0x800: # UTF-8 file names extension name = name.decode() else: # Historical ZIP filename encoding try: name = name.decode('ascii') except UnicodeDecodeError: name = name.decode('latin1').translate(cp437_table) name = name.replace('/', path_sep) path = _bootstrap_external._path_join(archive, name) t = (path, compress, data_size, file_size, file_offset, time, date, crc) files[name] = t count += 1 _bootstrap._verbose_message('zipimport: found {} names in {!r}', count, archive) return files
def _read_directory(archive): try: fp = _io.open(archive, 'rb') except OSError: raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive) with fp: try: fp.seek(-END_CENTRAL_DIR_SIZE, 2) header_position = fp.tell() buffer = fp.read(END_CENTRAL_DIR_SIZE) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if len(buffer) != END_CENTRAL_DIR_SIZE: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if buffer[:4] != STRING_END_ARCHIVE: # Bad: End of Central Dir signature # Check if there's a comment. try: fp.seek(0, 2) file_size = fp.tell() except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) max_comment_start = max(file_size - MAX_COMMENT_LEN - END_CENTRAL_DIR_SIZE, 0) try: fp.seek(max_comment_start) data = fp.read() except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) pos = data.rfind(STRING_END_ARCHIVE) if pos < 0: raise ZipImportError(f'not a Zip file: {archive!r}', path=archive) buffer = data[pos:pos+END_CENTRAL_DIR_SIZE] if len(buffer) != END_CENTRAL_DIR_SIZE: raise ZipImportError(f"corrupt Zip file: {archive!r}", path=archive) header_position = file_size - len(data) + pos header_size = _unpack_uint32(buffer[12:16]) header_offset = _unpack_uint32(buffer[16:20]) if header_position < header_size: raise ZipImportError(f'bad central directory size: {archive!r}', path=archive) if header_position < header_offset: raise ZipImportError(f'bad central directory offset: {archive!r}', path=archive) header_position -= header_size arc_offset = header_position - header_offset if arc_offset < 0: raise ZipImportError(f'bad central directory size or offset: {archive!r}', path=archive) files = {} # Start of Central Directory count = 0 try: fp.seek(header_position) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) while True: buffer = fp.read(46) if len(buffer) < 4: raise EOFError('EOF read where not expected') # Start of file header if buffer[:4] != b'PK\x01\x02': break # Bad: Central Dir File Header if len(buffer) != 46: raise EOFError('EOF read where not expected') flags = _unpack_uint16(buffer[8:10]) compress = _unpack_uint16(buffer[10:12]) time = _unpack_uint16(buffer[12:14]) date = _unpack_uint16(buffer[14:16]) crc = _unpack_uint32(buffer[16:20]) data_size = _unpack_uint32(buffer[20:24]) file_size = _unpack_uint32(buffer[24:28]) name_size = _unpack_uint16(buffer[28:30]) extra_size = _unpack_uint16(buffer[30:32]) comment_size = _unpack_uint16(buffer[32:34]) file_offset = _unpack_uint32(buffer[42:46]) header_size = name_size + extra_size + comment_size if file_offset > header_offset: raise ZipImportError(f'bad local header offset: {archive!r}', path=archive) file_offset += arc_offset try: name = fp.read(name_size) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if len(name) != name_size: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) # On Windows, calling fseek to skip over the fields we don't use is # slower than reading the data because fseek flushes stdio's # internal buffers. See issue #8745. try: if len(fp.read(header_size - name_size)) != header_size - name_size: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) if flags & 0x800: # UTF-8 file names extension name = name.decode() else: # Historical ZIP filename encoding try: name = name.decode('ascii') except UnicodeDecodeError: name = name.decode('latin1').translate(cp437_table) name = name.replace('/', path_sep) path = _bootstrap_external._path_join(archive, name) t = (path, compress, data_size, file_size, file_offset, time, date, crc) files[name] = t count += 1 _bootstrap._verbose_message('zipimport: found {} names in {!r}', count, archive) return files