pyimod03_importers.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. #-----------------------------------------------------------------------------
  2. # Copyright (c) 2005-2021, PyInstaller Development Team.
  3. #
  4. # Distributed under the terms of the GNU General Public License (version 2
  5. # or later) with exception for distributing the bootloader.
  6. #
  7. # The full license is in the file COPYING.txt, distributed with this software.
  8. #
  9. # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
  10. #-----------------------------------------------------------------------------
  11. """
  12. PEP-302 and PEP-451 importers for frozen applications.
  13. """
  14. ### **NOTE** This module is used during bootstrap.
  15. ### Import *ONLY* builtin modules.
  16. ### List of built-in modules: sys.builtin_module_names
  17. import sys
  18. import _frozen_importlib
  19. import pyimod01_os_path as pyi_os_path
  20. from pyimod02_archive import ArchiveReadError, ZlibArchiveReader
  21. SYS_PREFIX = sys._MEIPASS + pyi_os_path.os_sep
  22. SYS_PREFIXLEN = len(SYS_PREFIX)
  23. # In Python 3 it is recommended to use class 'types.ModuleType' to create a new module.
  24. # However, 'types' module is not a built-in module. The 'types' module uses this trick
  25. # with using type() function:
  26. imp_new_module = type(sys)
  27. if sys.flags.verbose and sys.stderr:
  28. def trace(msg, *a):
  29. sys.stderr.write(msg % a)
  30. sys.stderr.write("\n")
  31. else:
  32. def trace(msg, *a):
  33. pass
  34. class FrozenPackageImporter(object):
  35. """
  36. Wrapper class for FrozenImporter that imports one specific fullname from
  37. a module named by an alternate fullname. The alternate fullname is derived from the
  38. __path__ of the package module containing that module.
  39. This is called by FrozenImporter.find_module whenever a module is found as a result
  40. of searching module.__path__
  41. """
  42. def __init__(self, importer, entry_name):
  43. self._entry_name = entry_name
  44. self._importer = importer
  45. def load_module(self, fullname):
  46. # Deprecated in Python 3.4, see PEP-451
  47. return self._importer.load_module(fullname, self._entry_name)
  48. class FrozenImporter(object):
  49. """
  50. Load bytecode of Python modules from the executable created by PyInstaller.
  51. Python bytecode is zipped and appended to the executable.
  52. NOTE: PYZ format cannot be replaced by zipimport module.
  53. The problem is that we have no control over zipimport; for instance,
  54. it doesn't work if the zip file is embedded into a PKG appended
  55. to an executable, like we create in one-file.
  56. This is PEP-302 finder and loader class for the ``sys.meta_path`` hook.
  57. A PEP-302 finder requires method find_module() to return loader
  58. class with method load_module(). Both these methods are implemented
  59. in one class.
  60. This is also a PEP-451 finder and loader class for the ModuleSpec type
  61. import system. A PEP-451 finder requires method find_spec(), a PEP-451
  62. loader requires methods exec_module(), load_module(9 and (optionally)
  63. create_module(). All these methods are implemented in this one class.
  64. To use this class just call
  65. FrozenImporter.install()
  66. """
  67. def __init__(self):
  68. """
  69. Load, unzip and initialize the Zip archive bundled with the executable.
  70. """
  71. # Examine all items in sys.path and the one like /path/executable_name?117568
  72. # is the correct executable with bundled zip archive. Use this value
  73. # for the ZlibArchiveReader class and remove this item from sys.path.
  74. # It was needed only for FrozenImporter class. Wrong path from sys.path
  75. # Raises ArchiveReadError exception.
  76. for pyz_filepath in sys.path:
  77. try:
  78. # Unzip zip archive bundled with the executable.
  79. self._pyz_archive = ZlibArchiveReader(pyz_filepath)
  80. # Verify the integrity of the zip archive with Python modules.
  81. # This is already done when creating the ZlibArchiveReader instance.
  82. #self._pyz_archive.checkmagic()
  83. # End this method since no Exception was raised we can assume
  84. # ZlibArchiveReader was successfully loaded. Let's remove 'pyz_filepath'
  85. # from sys.path.
  86. sys.path.remove(pyz_filepath)
  87. # Some runtime hook might need access to the list of available
  88. # frozen module. Let's make them accessible as a set().
  89. self.toc = set(self._pyz_archive.toc.keys())
  90. # Return - no error was raised.
  91. trace("# PyInstaller: FrozenImporter(%s)", pyz_filepath)
  92. return
  93. except IOError:
  94. # Item from sys.path is not ZlibArchiveReader let's try next.
  95. continue
  96. except ArchiveReadError:
  97. # Item from sys.path is not ZlibArchiveReader let's try next.
  98. continue
  99. # sys.path does not contain filename of executable with bundled zip archive.
  100. # Raise import error.
  101. raise ImportError("Can't load frozen modules.")
  102. # Private helper
  103. def _is_pep420_namespace_package(self, fullname):
  104. if fullname in self.toc:
  105. try:
  106. return self._pyz_archive.is_pep420_namespace_package(fullname)
  107. except Exception as e:
  108. raise ImportError(
  109. 'Loader FrozenImporter cannot handle module ' + fullname
  110. ) from e
  111. else:
  112. raise ImportError(
  113. 'Loader FrozenImporter cannot handle module ' + fullname
  114. )
  115. def find_module(self, fullname, path=None):
  116. # Deprecated in Python 3.4, see PEP-451
  117. """
  118. PEP-302 finder.find_module() method for the ``sys.meta_path`` hook.
  119. fullname fully qualified name of the module
  120. path None for a top-level module, or package.__path__
  121. for submodules or subpackages.
  122. Return a loader object if the module was found, or None if it wasn't.
  123. If find_module() raises an exception, it will be propagated to the
  124. caller, aborting the import.
  125. """
  126. module_loader = None # None means - no module found in this importer.
  127. if fullname in self.toc:
  128. # Tell the import machinery to use self.load_module() to load the module.
  129. module_loader = self
  130. trace("import %s # PyInstaller PYZ", fullname)
  131. elif path is not None:
  132. # Try to handle module.__path__ modifications by the modules themselves
  133. # Reverse the fake __path__ we added to the package module to a
  134. # dotted module name and add the tail module from fullname onto that
  135. # to synthesize a new fullname
  136. modname = fullname.split('.')[-1]
  137. for p in path:
  138. if not p.startswith(SYS_PREFIX):
  139. continue
  140. p = p[SYS_PREFIXLEN:]
  141. parts = p.split(pyi_os_path.os_sep)
  142. if not parts: continue
  143. if not parts[0]:
  144. parts = parts[1:]
  145. parts.append(modname)
  146. entry_name = ".".join(parts)
  147. if entry_name in self.toc:
  148. module_loader = FrozenPackageImporter(self, entry_name)
  149. trace("import %s as %s # PyInstaller PYZ (__path__ override: %s)",
  150. entry_name, fullname, p)
  151. break
  152. # Release the interpreter's import lock.
  153. if module_loader is None:
  154. trace("# %s not found in PYZ", fullname)
  155. return module_loader
  156. def load_module(self, fullname, entry_name=None):
  157. # Deprecated in Python 3.4, see PEP-451
  158. """
  159. PEP-302 loader.load_module() method for the ``sys.meta_path`` hook.
  160. Return the loaded module (instance of imp_new_module()) or raises
  161. an exception, preferably ImportError if an existing exception
  162. is not being propagated.
  163. When called from FrozenPackageImporter, `entry_name` is the name of the
  164. module as it is stored in the archive. This module will be loaded and installed
  165. into sys.modules using `fullname` as its name
  166. """
  167. # Acquire the interpreter's import lock.
  168. module = None
  169. if entry_name is None:
  170. entry_name = fullname
  171. try:
  172. # PEP302 If there is an existing module object named 'fullname'
  173. # in sys.modules, the loader must use that existing module.
  174. module = sys.modules.get(fullname)
  175. # Module not in sys.modules - load it and it to sys.modules.
  176. if module is None:
  177. # Load code object from the bundled ZIP archive.
  178. is_pkg, bytecode = self._pyz_archive.extract(entry_name)
  179. # Create new empty 'module' object.
  180. module = imp_new_module(fullname)
  181. # TODO Replace bytecode.co_filename by something more meaningful:
  182. # e.g. /absolute/path/frozen_executable/path/to/module/module_name.pyc
  183. # Paths from developer machine are masked.
  184. # Set __file__ attribute of a module relative to the
  185. # executable so that data files can be found.
  186. module.__file__ = self.get_filename(entry_name)
  187. ### Set __path__ if 'fullname' is a package.
  188. # Python has modules and packages. A Python package is container
  189. # for several modules or packages.
  190. if is_pkg:
  191. # If a module has a __path__ attribute, the import mechanism
  192. # will treat it as a package.
  193. #
  194. # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to the
  195. # correct path where PyInstaller should find bundled dynamic
  196. # libraries. In one-file mode it points to the tmp directory where
  197. # bundled files are extracted at execution time.
  198. #
  199. # __path__ cannot be empty list because 'wx' module prepends something to it.
  200. # It cannot contain value 'sys.prefix' because 'xml.etree.cElementTree' fails
  201. # Otherwise.
  202. #
  203. # Set __path__ to point to 'sys.prefix/package/subpackage'.
  204. module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)]
  205. ### Set __loader__
  206. # The attribute __loader__ improves support for module 'pkg_resources' and
  207. # with the frozen apps the following functions are working:
  208. # pkg_resources.resource_string(), pkg_resources.resource_stream().
  209. module.__loader__ = self
  210. ### Set __package__
  211. # Accoring to PEP302 this attribute must be set.
  212. # When it is present, relative imports will be based on this
  213. # attribute rather than the module __name__ attribute.
  214. # More details can be found in PEP366.
  215. # For ordinary modules this is set like:
  216. # 'aa.bb.cc.dd' -> 'aa.bb.cc'
  217. if is_pkg:
  218. module.__package__ = fullname
  219. else:
  220. module.__package__ = fullname.rsplit('.', 1)[0]
  221. ### Set __spec__
  222. # In Python 3.4 was introduced module attribute __spec__ to
  223. # consolidate all module attributes.
  224. module.__spec__ = _frozen_importlib.ModuleSpec(
  225. entry_name, self, is_package=is_pkg)
  226. ### Add module object to sys.modules dictionary.
  227. # Module object must be in sys.modules before the loader
  228. # executes the module code. This is crucial because the module
  229. # code may (directly or indirectly) import itself; adding it
  230. # to sys.modules beforehand prevents unbounded recursion in the
  231. # worst case and multiple loading in the best.
  232. sys.modules[fullname] = module
  233. # Run the module code.
  234. exec(bytecode, module.__dict__)
  235. # Reread the module from sys.modules in case it's changed itself
  236. module = sys.modules[fullname]
  237. except Exception:
  238. # Remove 'fullname' from sys.modules if it was appended there.
  239. if fullname in sys.modules:
  240. sys.modules.pop(fullname)
  241. # TODO Do we need to raise different types of Exceptions for better debugging?
  242. # PEP302 requires to raise ImportError exception.
  243. #raise ImportError("Can't load frozen module: %s" % fullname)
  244. raise
  245. # Module returned only in case of no exception.
  246. return module
  247. ### Optional Extensions to the PEP-302 Importer Protocol
  248. def is_package(self, fullname):
  249. if fullname in self.toc:
  250. try:
  251. return self._pyz_archive.is_package(fullname)
  252. except Exception as e:
  253. raise ImportError(
  254. 'Loader FrozenImporter cannot handle module ' + fullname
  255. ) from e
  256. else:
  257. raise ImportError('Loader FrozenImporter cannot handle module ' + fullname)
  258. def get_code(self, fullname):
  259. """
  260. Get the code object associated with the module.
  261. ImportError should be raised if module not found.
  262. """
  263. try:
  264. if fullname == '__main__':
  265. # Special handling for __main__ module; the bootloader
  266. # should store code object to _pyi_main_co attribute of
  267. # the module.
  268. return sys.modules['__main__']._pyi_main_co
  269. # extract() returns None if fullname not in the archive, and the
  270. # subsequent subscription attempt raises exception, which
  271. # is turned into ImportError.
  272. return self._pyz_archive.extract(fullname)[1]
  273. except Exception as e:
  274. raise ImportError(
  275. 'Loader FrozenImporter cannot handle module ' + fullname
  276. ) from e
  277. def get_source(self, fullname):
  278. """
  279. Method should return the source code for the module as a string.
  280. But frozen modules does not contain source code.
  281. Return None.
  282. """
  283. if fullname in self.toc:
  284. # Try loading .py file from the filesystem
  285. filename = pyi_os_path.os_path_join(
  286. SYS_PREFIX,
  287. fullname.replace('.', pyi_os_path.os_sep) + '.py')
  288. try:
  289. with open(filename, 'r') as fp:
  290. return fp.read()
  291. except FileNotFoundError:
  292. pass
  293. return None
  294. else:
  295. # ImportError should be raised if module not found.
  296. raise ImportError('No module named ' + fullname)
  297. def get_data(self, path):
  298. """
  299. This returns the data as a string, or raise IOError if the "file"
  300. wasn't found. The data is always returned as if "binary" mode was used.
  301. This method is useful getting resources with 'pkg_resources' that are
  302. bundled with Python modules in the PYZ archive.
  303. The 'path' argument is a path that can be constructed by munging
  304. module.__file__ (or pkg.__path__ items)
  305. """
  306. assert path.startswith(SYS_PREFIX)
  307. fullname = path[SYS_PREFIXLEN:]
  308. if fullname in self.toc:
  309. # If the file is in the archive, return this
  310. return self._pyz_archive.extract(fullname)[1]
  311. else:
  312. # Otherwise try to fetch it from the filesystem. Since
  313. # __file__ attribute works properly just try to open and
  314. # read it.
  315. with open(path, 'rb') as fp:
  316. return fp.read()
  317. def get_filename(self, fullname):
  318. """
  319. This method should return the value that __file__ would be set to
  320. if the named module was loaded. If the module is not found, then
  321. ImportError should be raised.
  322. """
  323. # The absolute absolute path to the executable is taken from
  324. # sys.prefix. In onefile mode it points to the temp directory where
  325. # files are unpacked by PyInstaller. Then, append the appropriate
  326. # suffix (__init__.pyc for a package, or just .pyc for a module).
  327. # Method is_package() will raise ImportError if module not found.
  328. if self.is_package(fullname):
  329. filename = pyi_os_path.os_path_join(pyi_os_path.os_path_join(SYS_PREFIX,
  330. fullname.replace('.', pyi_os_path.os_sep)), '__init__.pyc')
  331. else:
  332. filename = pyi_os_path.os_path_join(SYS_PREFIX,
  333. fullname.replace('.', pyi_os_path.os_sep) + '.pyc')
  334. return filename
  335. def find_spec(self, fullname, path=None, target=None):
  336. """
  337. PEP-451 finder.find_spec() method for the ``sys.meta_path`` hook.
  338. fullname fully qualified name of the module
  339. path None for a top-level module, or package.__path__ for
  340. submodules or subpackages.
  341. target unused by this Finder
  342. Finders are still responsible for identifying, and typically creating,
  343. the loader that should be used to load a module. That loader will now
  344. be stored in the module spec returned by find_spec() rather than
  345. returned directly. As is currently the case without the PEP-452, if a
  346. loader would be costly to create, that loader can be designed to defer
  347. the cost until later.
  348. Finders must return ModuleSpec objects when find_spec() is called.
  349. This new method replaces find_module() and find_loader() (in the
  350. PathEntryFinder case). If a loader does not have find_spec(),
  351. find_module() and find_loader() are used instead, for
  352. backward-compatibility.
  353. """
  354. entry_name = None # None means - no module found in this importer.
  355. if fullname in self.toc:
  356. entry_name = fullname
  357. trace("import %s # PyInstaller PYZ", fullname)
  358. elif path is not None:
  359. # Try to handle module.__path__ modifications by the modules themselves
  360. # Reverse the fake __path__ we added to the package module to a
  361. # dotted module name and add the tail module from fullname onto that
  362. # to synthesize a new fullname
  363. modname = fullname.rsplit('.')[-1]
  364. for p in path:
  365. if not p.startswith(SYS_PREFIX):
  366. continue
  367. p = p[SYS_PREFIXLEN:]
  368. parts = p.split(pyi_os_path.os_sep)
  369. if not parts: continue
  370. if not parts[0]:
  371. parts = parts[1:]
  372. parts.append(modname)
  373. entry_name = ".".join(parts)
  374. if entry_name in self.toc:
  375. trace("import %s as %s # PyInstaller PYZ (__path__ override: %s)",
  376. entry_name, fullname, p)
  377. break
  378. else:
  379. entry_name = None
  380. if entry_name is None:
  381. trace("# %s not found in PYZ", fullname)
  382. return None
  383. if self._is_pep420_namespace_package(entry_name):
  384. # PEP-420 namespace package; as per PEP 451, we need to
  385. # return a spec with "loader" set to None (a.k.a. not set)
  386. spec = _frozen_importlib.ModuleSpec(
  387. fullname, None,
  388. is_package=True)
  389. # Set submodule_search_locations, which seems to fill the
  390. # __path__ attribute.
  391. spec.submodule_search_locations = [
  392. pyi_os_path.os_path_dirname(self.get_filename(entry_name))
  393. ]
  394. return spec
  395. # origin has to be the filename
  396. origin = self.get_filename(entry_name)
  397. is_pkg = self.is_package(entry_name)
  398. spec = _frozen_importlib.ModuleSpec(
  399. fullname, self,
  400. is_package=is_pkg, origin=origin,
  401. # Provide the entry_name for the loader to use during loading
  402. loader_state = entry_name)
  403. # Make the import machinery set __file__.
  404. # PEP 451 says: "has_location" is true if the module is locatable. In
  405. # that case the spec's origin is used as the location and __file__ is
  406. # set to spec.origin. If additional location information is required
  407. # (e.g. zipimport), that information may be stored in
  408. # spec.loader_state.
  409. spec.has_location = True
  410. # Set submodule_search_locations for packages. Seems to be
  411. # required for importlib_resources from 3.2.0 - see issue #5395.
  412. if is_pkg:
  413. spec.submodule_search_locations = [
  414. pyi_os_path.os_path_dirname(self.get_filename(entry_name))
  415. ]
  416. return spec
  417. def create_module(self, spec):
  418. """
  419. PEP-451 loader.create_module() method for the ``sys.meta_path`` hook.
  420. Loaders may also implement create_module() that will return a new
  421. module to exec. It may return None to indicate that the default module
  422. creation code should be used. One use case, though atypical, for
  423. create_module() is to provide a module that is a subclass of the
  424. builtin module type. Most loaders will not need to implement
  425. create_module(),
  426. create_module() should properly handle the case where it is called
  427. more than once for the same spec/module. This may include returning
  428. None or raising ImportError.
  429. """
  430. # Opposed to what is defined in PEP-451, this method is not optional.
  431. # We want the default results, so we simply return None (which is
  432. # handled for su my the import machinery). See
  433. # https://bugs.python.org/issue23014 for more information.
  434. return None
  435. def exec_module(self, module):
  436. """
  437. PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook.
  438. Loaders will have a new method, exec_module(). Its only job is to
  439. "exec" the module and consequently populate the module's namespace. It
  440. is not responsible for creating or preparing the module object, nor
  441. for any cleanup afterward. It has no return value. exec_module() will
  442. be used during both loading and reloading.
  443. exec_module() should properly handle the case where it is called more
  444. than once. For some kinds of modules this may mean raising ImportError
  445. every time after the first time the method is called. This is
  446. particularly relevant for reloading, where some kinds of modules do
  447. not support in-place reloading.
  448. """
  449. spec = module.__spec__
  450. bytecode = self.get_code(spec.loader_state)
  451. # Set by the import machinery
  452. assert hasattr(module, '__file__')
  453. # If `submodule_search_locations` is not None, this is a package;
  454. # set __path__.
  455. if spec.submodule_search_locations is not None:
  456. # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to
  457. # the correct path where PyInstaller should find bundled dynamic
  458. # libraries. In one-file mode it points to the tmp directory where
  459. # bundled files are extracted at execution time.
  460. #
  461. # __path__ cannot be empty list because 'wx' module prepends
  462. # something to it. It cannot contain value 'sys.prefix' because
  463. # 'xml.etree.cElementTree' fails otherwise.
  464. #
  465. # Set __path__ to point to 'sys.prefix/package/subpackage'.
  466. module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)]
  467. exec(bytecode, module.__dict__)
  468. def install():
  469. """
  470. Install FrozenImporter class and other classes into the import machinery.
  471. This class method (static method) installs the FrozenImporter class into
  472. the import machinery of the running process. The importer is added
  473. to sys.meta_path. It could be added to sys.path_hooks but sys.meta_path
  474. is processed by Python before looking at sys.path!
  475. The order of processing import hooks in sys.meta_path:
  476. 1. built-in modules
  477. 2. modules from the bundled ZIP archive
  478. 3. C extension modules
  479. 4. Modules from sys.path
  480. """
  481. # Ensure Python looks in the bundled zip archive for modules before any
  482. # other places.
  483. fimp = FrozenImporter()
  484. sys.meta_path.append(fimp)
  485. # On Windows there is importer _frozen_importlib.WindowsRegistryFinder that
  486. # looks for Python modules in Windows registry. The frozen executable should
  487. # not look for anything in the Windows registry. Remove this importer from
  488. # sys.meta_path.
  489. for item in sys.meta_path:
  490. if hasattr(item, '__name__') and item.__name__ == 'WindowsRegistryFinder':
  491. sys.meta_path.remove(item)
  492. break
  493. # _frozen_importlib.PathFinder is also able to handle Python C
  494. # extensions. However, PyInstaller needs its own importer since it
  495. # uses extension names like 'module.submodle.so' (instead of paths).
  496. # As of Python 3.7.0b2, there are several PathFinder instances (and
  497. # duplicate ones) on sys.meta_path. This propobly is a bug, see
  498. # https://bugs.python.org/issue33128. Thus we need to move all of them
  499. # to the end, eliminating duplicates .
  500. pathFinders = []
  501. for item in reversed(sys.meta_path):
  502. if getattr(item, '__name__', None) == 'PathFinder':
  503. sys.meta_path.remove(item)
  504. if not item in pathFinders:
  505. pathFinders.append(item)
  506. sys.meta_path.extend(reversed(pathFinders))
  507. # TODO Do we need for Python 3 _frozen_importlib.FrozenImporter? Could it be also removed?
  508. # Set the FrozenImporter as loader for __main__, in order for python
  509. # to treat __main__ as a module instead of a built-in.
  510. try:
  511. sys.modules['__main__'].__loader__ = fimp
  512. except Exception:
  513. pass