def exec_module(self, module): """ PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook. Loaders will have a new method, exec_module(). Its only job is to "exec" the module and consequently populate the module's namespace. It is not responsible for creating or preparing the module object, nor for any cleanup afterward. It has no return value. exec_module() will be used during both loading and reloading. exec_module() should properly handle the case where it is called more than once. For some kinds of modules this may mean raising ImportError every time after the first time the method is called. This is particularly relevant for reloading, where some kinds of modules do not support in-place reloading. """ spec = module.__spec__ bytecode = self.get_code(spec.loader_state) # Set by the import machinery assert hasattr(module, '__file__') # If `submodule_search_locations` is not None, this is a package; set __path__. if spec.submodule_search_locations is not None: # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to the correct path where PyInstaller should # find bundled dynamic libraries. In one-file mode it points to the tmp directory where bundled files are # extracted at execution time. # # __path__ cannot be empty list because 'wx' module prepends something to it. It cannot contain value # 'sys.prefix' because 'xml.etree.cElementTree' fails otherwise. # # Set __path__ to point to 'sys.prefix/package/subpackage'. module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)] exec(bytecode, module.__dict__)
def load_module(self, fullname, entry_name=None): """ PEP-302 loader.load_module() method for the ``sys.meta_path`` hook. Return the loaded module (instance of imp_new_module()) or raises an exception, preferably ImportError if an existing exception is not being propagated. When called from FrozenPackageImporter, `entry_name` is the name of the module as it is stored in the archive. This module will be loaded and installed into sys.modules using `fullname` as its name """ imp_lock() module = None if entry_name is None: entry_name = fullname try: try: module = sys.modules.get(fullname) if module is None: is_pkg, bytecode = self._pyz_archive.extract(entry_name) module = imp_new_module(fullname) module.__file__ = self.get_filename(entry_name) if is_pkg: module.__path__ = [ pyi_os_path.os_path_dirname(module.__file__) ] module.__loader__ = self if is_pkg: module.__package__ = fullname else: module.__package__ = fullname.rsplit('.', 1)[0] if sys.version_info[0:2] > (3, 3): module.__spec__ = _frozen_importlib.ModuleSpec( entry_name, self, is_package=is_pkg) sys.modules[fullname] = module exec bytecode in module.__dict__ module = sys.modules[fullname] except Exception: if fullname in sys.modules: sys.modules.pop(fullname) raise finally: imp_unlock() return module
def exec_module(self, module): """ PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook. Loaders will have a new method, exec_module(). Its only job is to "exec" the module and consequently populate the module's namespace. It is not responsible for creating or preparing the module object, nor for any cleanup afterward. It has no return value. exec_module() will be used during both loading and reloading. exec_module() should properly handle the case where it is called more than once. For some kinds of modules this may mean raising ImportError every time after the first time the method is called. This is particularly relevant for reloading, where some kinds of modules do not support in-place reloading. """ spec = module.__spec__ bytecode = self.get_code(spec.loader_state) # Set by the import machinery assert hasattr(module, '__file__') # If `submodule_search_locations` is not None, this is a package; # set __path__. if spec.submodule_search_locations is not None: # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to # the correct path where PyInstaller should find bundled dynamic # libraries. In one-file mode it points to the tmp directory where # bundled files are extracted at execution time. # # __path__ cannot be empty list because 'wx' module prepends # something to it. It cannot contain value 'sys.prefix' because # 'xml.etree.cElementTree' fails otherwise. # # Set __path__ to point to 'sys.prefix/package/subpackage'. module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)] exec(bytecode, module.__dict__)
def exec_module(self, module): """ PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook. Loaders will have a new method, exec_module(). Its only job is to "exec" the module and consequently populate the module's namespace. It is not responsible for creating or preparing the module object, nor for any cleanup afterward. It has no return value. exec_module() will be used during both loading and reloading. exec_module() should properly handle the case where it is called more than once. For some kinds of modules this may mean raising ImportError every time after the first time the method is called. This is particularly relevant for reloading, where some kinds of modules do not support in-place reloading. """ spec = module.__spec__ bytecode = self.get_code(spec.loader_state) assert hasattr(module, '__file__') if spec.submodule_search_locations is not None: module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)] exec bytecode in module.__dict__ return
def load_module(self, fullname, entry_name=None): # Deprecated in Python 3.4, see PEP-451 """ PEP-302 loader.load_module() method for the ``sys.meta_path`` hook. Return the loaded module (instance of imp_new_module()) or raises an exception, preferably ImportError if an existing exception is not being propagated. When called from FrozenPackageImporter, `entry_name` is the name of the module as it is stored in the archive. This module will be loaded and installed into sys.modules using `fullname` as its name """ # Acquire the interpreter's import lock. imp_lock() module = None if entry_name is None: entry_name = fullname try: # PEP302 If there is an existing module object named 'fullname' # in sys.modules, the loader must use that existing module. module = sys.modules.get(fullname) # Module not in sys.modules - load it and it to sys.modules. if module is None: # Load code object from the bundled ZIP archive. is_pkg, bytecode = self._pyz_archive.extract(entry_name) # Create new empty 'module' object. module = imp_new_module(fullname) # TODO Replace bytecode.co_filename by something more meaningful: # e.g. /absolute/path/frozen_executable/path/to/module/module_name.pyc # Paths from developer machine are masked. # Set __file__ attribute of a module relative to the # executable so that data files can be found. module.__file__ = self.get_filename(entry_name) ### Set __path__ if 'fullname' is a package. # Python has modules and packages. A Python package is container # for several modules or packages. if is_pkg: # If a module has a __path__ attribute, the import mechanism # will treat it as a package. # # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to the # correct path where PyInstaller should find bundled dynamic # libraries. In one-file mode it points to the tmp directory where # bundled files are extracted at execution time. # # __path__ cannot be empty list because 'wx' module prepends something to it. # It cannot contain value 'sys.prefix' because 'xml.etree.cElementTree' fails # Otherwise. # # Set __path__ to point to 'sys.prefix/package/subpackage'. module.__path__ = [ pyi_os_path.os_path_dirname(module.__file__) ] ### Set __loader__ # The attribute __loader__ improves support for module 'pkg_resources' and # with the frozen apps the following functions are working: # pkg_resources.resource_string(), pkg_resources.resource_stream(). module.__loader__ = self ### Set __package__ # Accoring to PEP302 this attribute must be set. # When it is present, relative imports will be based on this # attribute rather than the module __name__ attribute. # More details can be found in PEP366. # For ordinary modules this is set like: # 'aa.bb.cc.dd' -> 'aa.bb.cc' if is_pkg: module.__package__ = fullname else: module.__package__ = fullname.rsplit('.', 1)[0] ### Set __spec__ for Python 3.4+ # In Python 3.4 was introduced module attribute __spec__ to # consolidate all module attributes. if sys.version_info[0:2] > (3, 3): module.__spec__ = _frozen_importlib.ModuleSpec( entry_name, self, is_package=is_pkg) ### Add module object to sys.modules dictionary. # Module object must be in sys.modules before the loader # executes the module code. This is crucial because the module # code may (directly or indirectly) import itself; adding it # to sys.modules beforehand prevents unbounded recursion in the # worst case and multiple loading in the best. sys.modules[fullname] = module # Run the module code. exec(bytecode, module.__dict__) # Reread the module from sys.modules in case it's changed itself module = sys.modules[fullname] except Exception: # Remove 'fullname' from sys.modules if it was appended there. if fullname in sys.modules: sys.modules.pop(fullname) # TODO Do we need to raise different types of Exceptions for better debugging? # PEP302 requires to raise ImportError exception. #raise ImportError("Can't load frozen module: %s" % fullname) raise finally: # Release the interpreter's import lock. imp_unlock() # Module returned only in case of no exception. return module
def find_spec(self, fullname, path=None, target=None): """ PEP-451 finder.find_spec() method for the ``sys.meta_path`` hook. fullname fully qualified name of the module path None for a top-level module, or package.__path__ for submodules or subpackages. target unused by this Finder Finders are still responsible for identifying, and typically creating, the loader that should be used to load a module. That loader will now be stored in the module spec returned by find_spec() rather than returned directly. As is currently the case without the PEP-452, if a loader would be costly to create, that loader can be designed to defer the cost until later. Finders must return ModuleSpec objects when find_spec() is called. This new method replaces find_module() and find_loader() (in the PathEntryFinder case). If a loader does not have find_spec(), find_module() and find_loader() are used instead, for backward-compatibility. """ entry_name = None # None means - no module found in this importer. if fullname in self.toc: entry_name = fullname trace("import %s # PyInstaller PYZ", fullname) elif path is not None: # Try to handle module.__path__ modifications by the modules themselves # Reverse the fake __path__ we added to the package module to a # dotted module name and add the tail module from fullname onto that # to synthesize a new fullname modname = fullname.rsplit('.')[-1] for p in path: if not p.startswith(SYS_PREFIX): continue p = p[SYS_PREFIXLEN:] parts = p.split(pyi_os_path.os_sep) if not parts: continue if not parts[0]: parts = parts[1:] parts.append(modname) entry_name = ".".join(parts) if entry_name in self.toc: trace("import %s as %s # PyInstaller PYZ (__path__ override: %s)", entry_name, fullname, p) break else: entry_name = None if entry_name is None: trace("# %s not found in PYZ", fullname) return None if self._is_pep420_namespace_package(entry_name): # PEP-420 namespace package; as per PEP 451, we need to # return a spec with "loader" set to None (a.k.a. not set) spec = _frozen_importlib.ModuleSpec( fullname, None, is_package=True) # Set submodule_search_locations, which seems to fill the # __path__ attribute. spec.submodule_search_locations = [ pyi_os_path.os_path_dirname(self.get_filename(entry_name)) ] return spec # origin has to be the filename origin = self.get_filename(entry_name) is_pkg = self.is_package(entry_name) spec = _frozen_importlib.ModuleSpec( fullname, self, is_package=is_pkg, origin=origin, # Provide the entry_name for the loader to use during loading loader_state = entry_name) # Make the import machinery set __file__. # PEP 451 says: "has_location" is true if the module is locatable. In # that case the spec's origin is used as the location and __file__ is # set to spec.origin. If additional location information is required # (e.g. zipimport), that information may be stored in # spec.loader_state. spec.has_location = True # Set submodule_search_locations for packages. Seems to be # required for importlib_resources from 3.2.0 - see issue #5395. if is_pkg: spec.submodule_search_locations = [ pyi_os_path.os_path_dirname(self.get_filename(entry_name)) ] return spec
def load_module(self, fullname, real_fullname=None): """ PEP-302 loader.load_module() method for the ``sys.meta_path`` hook. Return the loaded module (instance of imp_new_module()) or raises an exception, preferably ImportError if an existing exception is not being propagated. When called from FrozenPackageImporter, `real_fullname` is the name of the module as it is stored in the archive. This module will be loaded and installed into sys.modules using `fullname` as its name """ # Acquire the interpreter's import lock. imp_lock() module = None if real_fullname is None: real_fullname=fullname try: # PEP302 If there is an existing module object named 'fullname' # in sys.modules, the loader must use that existing module. module = sys.modules.get(fullname) # Module not in sys.modules - load it and it to sys.modules. if module is None: # Load code object from the bundled ZIP archive. is_pkg, bytecode = self._pyz_archive.extract(real_fullname) # Create new empty 'module' object. module = imp_new_module(fullname) # TODO Replace bytecode.co_filename by something more meaningful: # e.g. /absolute/path/frozen_executable/path/to/module/module_name.pyc # Paths from developer machine are masked. ### Set __file__ attribute of a module relative to the executable # so that data files can be found. The absolute absolute path # to the executable is taken from sys.prefix. In onefile mode it # points to the temp directory where files are unpacked by PyInstaller. # Then, append the appropriate suffix (__init__.pyc for a package, or just .pyc for a module). if is_pkg: module.__file__ = pyi_os_path.os_path_join(pyi_os_path.os_path_join(SYS_PREFIX, fullname.replace('.', pyi_os_path.os_sep)), '__init__.pyc') else: module.__file__ = pyi_os_path.os_path_join(SYS_PREFIX, fullname.replace('.', pyi_os_path.os_sep) + '.pyc') ### Set __path__ if 'fullname' is a package. # Python has modules and packages. A Python package is container # for several modules or packages. if is_pkg: # If a module has a __path__ attribute, the import mechanism # will treat it as a package. # # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to the # correct path where PyInstaller should find bundled dynamic # libraries. In one-file mode it points to the tmp directory where # bundled files are extracted at execution time. # # __path__ cannot be empty list because 'wx' module prepends something to it. # It cannot contain value 'sys.prefix' because 'xml.etree.cElementTree' fails # Otherwise. # # Set __path__ to point to 'sys.prefix/package/subpackage'. module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)] ### Set __loader__ # The attribute __loader__ improves support for module 'pkg_resources' and # with the frozen apps the following functions are working: # pkg_resources.resource_string(), pkg_resources.resource_stream(). module.__loader__ = self ### Set __package__ # Accoring to PEP302 this attribute must be set. # When it is present, relative imports will be based on this # attribute rather than the module __name__ attribute. # More details can be found in PEP366. # For ordinary modules this is set like: # 'aa.bb.cc.dd' -> 'aa.bb.cc' if is_pkg: module.__package__ = fullname else: module.__package__ = fullname.rsplit('.', 1)[0] ### Set __spec__ for Python 3.4+ # In Python 3.4 was introduced module attribute __spec__ to # consolidate all module attributes. if sys.version_info[0:2] > (3, 3): module.__spec__ = _frozen_importlib.ModuleSpec( real_fullname, self, is_package=is_pkg) ### Add module object to sys.modules dictionary. # Module object must be in sys.modules before the loader # executes the module code. This is crucial because the module # code may (directly or indirectly) import itself; adding it # to sys.modules beforehand prevents unbounded recursion in the # worst case and multiple loading in the best. sys.modules[fullname] = module # Run the module code. exec(bytecode, module.__dict__) # Reread the module from sys.modules in case it's changed itself module = sys.modules[fullname] except Exception: # Remove 'fullname' from sys.modules if it was appended there. if fullname in sys.modules: sys.modules.pop(fullname) # TODO Do we need to raise different types of Exceptions for better debugging? # PEP302 requires to raise ImportError exception. #raise ImportError("Can't load frozen module: %s" % fullname) raise finally: # Release the interpreter's import lock. imp_unlock() # Module returned only in case of no exception. return module