1#-----------------------------------------------------------------------------
2# Copyright (c) 2005-2019, PyInstaller Development Team.
3#
4# Distributed under the terms of the GNU General Public License with exception
5# for distributing bootloader.
6#
7# The full license is in the file COPYING.txt, distributed with this software.
8#-----------------------------------------------------------------------------
9
10"""
11PEP-302 and PEP-451 importers for frozen applications.
12"""
13
14
15### **NOTE** This module is used during bootstrap.
16### Import *ONLY* builtin modules.
17### List of built-in modules: sys.builtin_module_names
18
19
20
21import sys
22import pyimod01_os_path as pyi_os_path
23
24from pyimod02_archive import ArchiveReadError, ZlibArchiveReader
25
26
27SYS_PREFIX = sys._MEIPASS
28SYS_PREFIXLEN = len(SYS_PREFIX)
29
30# In Python 3.3+ tne locking scheme has changed to per-module locks for the most part.
31# Global locking should not be required in Python 3.3+
32if sys.version_info[0:2] < (3, 3):
33    # TODO Implement this for Python 3.2 - 'imp' is not a built-in module anymore.
34    import imp
35    imp_lock = imp.acquire_lock
36    imp_unlock = imp.release_lock
37    # Find the platform specific extension suffixes.
38    # For Python 2 we need the info-tuples for loading
39    EXTENSION_SUFFIXES = dict((f[0], f) for f in imp.get_suffixes()
40                              if f[2] == imp.C_EXTENSION)
41    # Function to create a new module object from pyz archive.
42    imp_new_module = imp.new_module
43else:
44    # Dumb locking functions - do nothing.
45    def imp_lock(): pass
46    def imp_unlock(): pass
47    import _frozen_importlib
48    if sys.version_info[1] <= 4:
49        # Python 3.3, 3.4
50        EXTENSION_SUFFIXES = _frozen_importlib.EXTENSION_SUFFIXES
51        EXTENSION_LOADER = _frozen_importlib.ExtensionFileLoader
52    else:
53        # Since Python 3.5+ some attributes were moved to '_bootstrap_external'.
54        EXTENSION_SUFFIXES = _frozen_importlib._bootstrap_external.EXTENSION_SUFFIXES
55        EXTENSION_LOADER = _frozen_importlib._bootstrap_external.ExtensionFileLoader
56
57    # In Python 3 it is recommended to use class 'types.ModuleType' to create a new module.
58    # However, 'types' module is not a built-in module. The 'types' module uses this trick
59    # with using type() function:
60    imp_new_module = type(sys)
61
62if sys.flags.verbose:
63    def trace(msg, *a):
64        sys.stderr.write(msg % a)
65        sys.stderr.write("\n")
66else:
67    def trace(msg, *a):
68        pass
69
70# Python 3 has it's own BuiltinImporter, we use this for Python2 only
71class BuiltinImporter(object):
72    """
73    PEP-302 wrapper of the built-in modules for sys.meta_path.
74
75    This wrapper ensures that import machinery will not look for built-in
76    modules in the bundled ZIP archive.
77    """
78    def find_module(self, fullname, path=None):
79        # Deprecated in Python 3.4, see PEP-451
80        imp_lock()
81        module_loader = None  # None means - no module found by this importer.
82
83        # Look in the list of built-in modules.
84        if fullname in sys.builtin_module_names:
85            module_loader = self
86
87        imp_unlock()
88        return module_loader
89
90    def load_module(self, fullname, path=None):
91        # Deprecated in Python 3.4, see PEP-451
92        imp_lock()
93
94        try:
95            # PEP302 If there is an existing module object named 'fullname'
96            # in sys.modules, the loader must use that existing module.
97            module = sys.modules.get(fullname)
98            if module is None:
99                module = imp.init_builtin(fullname)
100
101        except Exception:
102            # Remove 'fullname' from sys.modules if it was appended there.
103            if fullname in sys.modules:
104                sys.modules.pop(fullname)
105            raise  # Raise the same exception again.
106
107        finally:
108            # Release the interpreter's import lock.
109            imp_unlock()
110
111        return module
112
113    ### Optional Extensions to the PEP-302 Importer Protocol
114
115    def is_package(self, fullname):
116        """
117        Return always False since built-in modules are never packages.
118        """
119        if fullname in sys.builtin_module_names:
120            return False
121        else:
122            # ImportError should be raised if module not found.
123            raise ImportError('No module named ' + fullname)
124
125    def get_code(self, fullname):
126        """
127        Return None for a built-in module.
128        """
129        if fullname in sys.builtin_module_names:
130            return None
131        else:
132            # ImportError should be raised if module not found.
133            raise ImportError('No module named ' + fullname)
134
135    def get_source(self, fullname):
136        """
137        Return None for a built-in module.
138        """
139        if fullname in sys.builtin_module_names:
140            return None
141        else:
142            # ImportError should be raised if module not found.
143            raise ImportError('No module named ' + fullname)
144
145
146class FrozenPackageImporter(object):
147    """
148    Wrapper class for FrozenImporter that imports one specific fullname from
149    a module named by an alternate fullname. The alternate fullname is derived from the
150    __path__ of the package module containing that module.
151
152    This is called by FrozenImporter.find_module whenever a module is found as a result
153    of searching module.__path__
154    """
155    def __init__(self, importer, entry_name):
156        self._entry_name = entry_name
157        self._importer = importer
158
159    def load_module(self, fullname):
160        # Deprecated in Python 3.4, see PEP-451
161        return self._importer.load_module(fullname, self._entry_name)
162
163
164class FrozenImporter(object):
165    """
166    Load bytecode of Python modules from the executable created by PyInstaller.
167
168    Python bytecode is zipped and appended to the executable.
169
170    NOTE: PYZ format cannot be replaced by zipimport module.
171
172    The problem is that we have no control over zipimport; for instance,
173    it doesn't work if the zip file is embedded into a PKG appended
174    to an executable, like we create in one-file.
175
176    This is PEP-302 finder and loader class for the ``sys.meta_path`` hook.
177    A PEP-302 finder requires method find_module() to return loader
178    class with method load_module(). Both these methods are implemented
179    in one class.
180
181    This is also a PEP-451 finder and loader class for the ModuleSpec type
182    import system. A PEP-451 finder requires method find_spec(), a PEP-451
183    loader requires methods exec_module(), load_module(9 and (optionally)
184    create_module(). All these methods are implemented in this one class.
185
186    To use this class just call
187
188        FrozenImporter.install()
189    """
190
191    def __init__(self):
192        """
193        Load, unzip and initialize the Zip archive bundled with the executable.
194        """
195        # Examine all items in sys.path and the one like /path/executable_name?117568
196        # is the correct executable with bundled zip archive. Use this value
197        # for the ZlibArchiveReader class and remove this item from sys.path.
198        # It was needed only for FrozenImporter class. Wrong path from sys.path
199        # Raises ArchiveReadError exception.
200        for pyz_filepath in sys.path:
201            # We need to acquire the interpreter's import lock here
202            # because ZlibArchiveReader() seeks through and reads from the
203            # zip archive.
204            imp_lock()
205            try:
206                # Unzip zip archive bundled with the executable.
207                self._pyz_archive = ZlibArchiveReader(pyz_filepath)
208                # Verify the integrity of the zip archive with Python modules.
209                # This is already done when creating the ZlibArchiveReader instance.
210                #self._pyz_archive.checkmagic()
211
212                # End this method since no Exception was raised we can assume
213                # ZlibArchiveReader was successfully loaded. Let's remove 'pyz_filepath'
214                # from sys.path.
215                sys.path.remove(pyz_filepath)
216                # Some runtime hook might need access to the list of available
217                # frozen module. Let's make them accessible as a set().
218                self.toc = set(self._pyz_archive.toc.keys())
219                # Return - no error was raised.
220                trace("# PyInstaller: FrozenImporter(%s)", pyz_filepath)
221                return
222            except IOError:
223                # Item from sys.path is not ZlibArchiveReader let's try next.
224                continue
225            except ArchiveReadError:
226                # Item from sys.path is not ZlibArchiveReader let's try next.
227                continue
228            finally:
229                imp_unlock()
230        # sys.path does not contain filename of executable with bundled zip archive.
231        # Raise import error.
232        raise ImportError("Can't load frozen modules.")
233
234
235    def __call__(self, path):
236        """
237        PEP-302 sys.path_hook processor. is_py2: This is only needed for Python
238        2; see comments at `path_hook installation`_.
239
240        sys.path_hook is a list of callables, which will be checked in
241        sequence to determine if they can handle a given path item.
242        """
243
244        if path.startswith(SYS_PREFIX):
245            fullname = path[SYS_PREFIXLEN+1:].replace(pyi_os_path.os_sep, '.')
246            loader = self.find_module(fullname)
247            if loader is not None:
248                return loader
249        raise ImportError(path)
250
251
252    def find_module(self, fullname, path=None):
253        # Deprecated in Python 3.4, see PEP-451
254        """
255        PEP-302 finder.find_module() method for the ``sys.meta_path`` hook.
256
257        fullname     fully qualified name of the module
258        path         None for a top-level module, or package.__path__
259                     for submodules or subpackages.
260
261        Return a loader object if the module was found, or None if it wasn't.
262        If find_module() raises an exception, it will be propagated to the
263        caller, aborting the import.
264        """
265
266        # Acquire the interpreter's import lock for the current thread. This
267        # lock should be used by import hooks to ensure thread-safety when
268        # importing modules.
269
270        imp_lock()
271        module_loader = None  # None means - no module found in this importer.
272
273        if fullname in self.toc:
274            # Tell the import machinery to use self.load_module() to load the module.
275            module_loader = self
276            trace("import %s # PyInstaller PYZ", fullname)
277        elif path is not None:
278            # Try to handle module.__path__ modifications by the modules themselves
279            # Reverse the fake __path__ we added to the package module to a
280            # dotted module name and add the tail module from fullname onto that
281            # to synthesize a new fullname
282            modname = fullname.split('.')[-1]
283
284            for p in path:
285                p = p[SYS_PREFIXLEN+1:]
286                parts = p.split(pyi_os_path.os_sep)
287                if not parts: continue
288                if not parts[0]:
289                    parts = parts[1:]
290                parts.append(modname)
291                entry_name = ".".join(parts)
292                if entry_name in self.toc:
293                    module_loader = FrozenPackageImporter(self, entry_name)
294                    trace("import %s as %s # PyInstaller PYZ (__path__ override: %s)",
295                          entry_name, fullname, p)
296                    break
297        # Release the interpreter's import lock.
298        imp_unlock()
299        if module_loader is None:
300            trace("# %s not found in PYZ", fullname)
301        return module_loader
302
303    def load_module(self, fullname, entry_name=None):
304        # Deprecated in Python 3.4, see PEP-451
305        """
306        PEP-302 loader.load_module() method for the ``sys.meta_path`` hook.
307
308        Return the loaded module (instance of imp_new_module()) or raises
309        an exception, preferably ImportError if an existing exception
310        is not being propagated.
311
312        When called from FrozenPackageImporter, `entry_name` is the name of the
313        module as it is stored in the archive. This module will be loaded and installed
314        into sys.modules using `fullname` as its name
315        """
316        # Acquire the interpreter's import lock.
317        imp_lock()
318        module = None
319        if entry_name is None:
320            entry_name = fullname
321        try:
322            # PEP302 If there is an existing module object named 'fullname'
323            # in sys.modules, the loader must use that existing module.
324            module = sys.modules.get(fullname)
325
326            # Module not in sys.modules - load it and it to sys.modules.
327            if module is None:
328                # Load code object from the bundled ZIP archive.
329                is_pkg, bytecode = self._pyz_archive.extract(entry_name)
330                # Create new empty 'module' object.
331                module = imp_new_module(fullname)
332
333                # TODO Replace bytecode.co_filename by something more meaningful:
334                # e.g. /absolute/path/frozen_executable/path/to/module/module_name.pyc
335                # Paths from developer machine are masked.
336
337                # Set __file__ attribute of a module relative to the
338                # executable so that data files can be found.
339                module.__file__ = self.get_filename(entry_name)
340
341                ### Set __path__  if 'fullname' is a package.
342                # Python has modules and packages. A Python package is container
343                # for several modules or packages.
344                if is_pkg:
345
346                    # If a module has a __path__ attribute, the import mechanism
347                    # will treat it as a package.
348                    #
349                    # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to the
350                    # correct path where PyInstaller should find bundled dynamic
351                    # libraries. In one-file mode it points to the tmp directory where
352                    # bundled files are extracted at execution time.
353                    #
354                    # __path__ cannot be empty list because 'wx' module prepends something to it.
355                    # It cannot contain value 'sys.prefix' because 'xml.etree.cElementTree' fails
356                    # Otherwise.
357                    #
358                    # Set __path__ to point to 'sys.prefix/package/subpackage'.
359                    module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)]
360
361                ### Set __loader__
362                # The attribute __loader__ improves support for module 'pkg_resources' and
363                # with the frozen apps the following functions are working:
364                # pkg_resources.resource_string(), pkg_resources.resource_stream().
365                module.__loader__ = self
366
367                ### Set __package__
368                # Accoring to PEP302 this attribute must be set.
369                # When it is present, relative imports will be based on this
370                # attribute rather than the module __name__ attribute.
371                # More details can be found in PEP366.
372                # For ordinary modules this is set like:
373                #     'aa.bb.cc.dd'  ->  'aa.bb.cc'
374                if is_pkg:
375                    module.__package__ = fullname
376                else:
377                    module.__package__ = fullname.rsplit('.', 1)[0]
378
379                ### Set __spec__ for Python 3.4+
380                # In Python 3.4 was introduced module attribute __spec__ to
381                # consolidate all module attributes.
382                if sys.version_info[0:2] > (3, 3):
383                    module.__spec__ = _frozen_importlib.ModuleSpec(
384                        entry_name, self, is_package=is_pkg)
385
386                ### Add module object to sys.modules dictionary.
387                # Module object must be in sys.modules before the loader
388                # executes the module code. This is crucial because the module
389                # code may (directly or indirectly) import itself; adding it
390                # to sys.modules beforehand prevents unbounded recursion in the
391                # worst case and multiple loading in the best.
392                sys.modules[fullname] = module
393
394                # Run the module code.
395                exec(bytecode, module.__dict__)
396                # Reread the module from sys.modules in case it's changed itself
397                module = sys.modules[fullname]
398
399        except Exception:
400            # Remove 'fullname' from sys.modules if it was appended there.
401            if fullname in sys.modules:
402                sys.modules.pop(fullname)
403            # TODO Do we need to raise different types of Exceptions for better debugging?
404            # PEP302 requires to raise ImportError exception.
405            #raise ImportError("Can't load frozen module: %s" % fullname)
406
407            raise
408
409        finally:
410            # Release the interpreter's import lock.
411            imp_unlock()
412
413
414        # Module returned only in case of no exception.
415        return module
416
417    ### Optional Extensions to the PEP-302 Importer Protocol
418
419    def is_package(self, fullname):
420        if fullname in self.toc:
421            try:
422                return self._pyz_archive.is_package(fullname)
423            except Exception:
424                raise ImportError('Loader FrozenImporter cannot handle module ' + fullname)
425        else:
426            raise ImportError('Loader FrozenImporter cannot handle module ' + fullname)
427
428    def get_code(self, fullname):
429        """
430        Get the code object associated with the module.
431
432        ImportError should be raised if module not found.
433        """
434        try:
435            # extract() returns None if fullname not in the archive, thus the
436            # next line will raise an execpion which will be catched just
437            # below and raise the ImportError.
438            return self._pyz_archive.extract(fullname)[1]
439        except:
440            raise ImportError('Loader FrozenImporter cannot handle module ' + fullname)
441
442    def get_source(self, fullname):
443        """
444        Method should return the source code for the module as a string.
445        But frozen modules does not contain source code.
446
447        Return None.
448        """
449        if fullname in self.toc:
450            return None
451        else:
452            # ImportError should be raised if module not found.
453            raise ImportError('No module named ' + fullname)
454
455    def get_data(self, path):
456        """
457        This returns the data as a string, or raise IOError if the "file"
458        wasn't found. The data is always returned as if "binary" mode was used.
459
460        This method is useful getting resources with 'pkg_resources' that are
461        bundled with Python modules in the PYZ archive.
462
463        The 'path' argument is a path that can be constructed by munging
464        module.__file__ (or pkg.__path__ items)
465        """
466        assert path.startswith(SYS_PREFIX + pyi_os_path.os_sep)
467        fullname = path[SYS_PREFIXLEN+1:]
468        if fullname in self.toc:
469            # If the file is in the archive, return this
470            return self._pyz_archive.extract(fullname)[1]
471        else:
472            # Otherwise try to fetch it from the filesystem. Since
473            # __file__ attribute works properly just try to open and
474            # read it.
475            with open(path, 'rb') as fp:
476                return fp.read()
477
478    def get_filename(self, fullname):
479        """
480        This method should return the value that __file__ would be set to
481        if the named module was loaded. If the module is not found, then
482        ImportError should be raised.
483        """
484        # The absolute absolute path to the executable is taken from
485        # sys.prefix. In onefile mode it points to the temp directory where
486        # files are unpacked by PyInstaller. Then, append the appropriate
487        # suffix (__init__.pyc for a package, or just .pyc for a module).
488        # Method is_package() will raise ImportError if module not found.
489        if self.is_package(fullname):
490            filename = pyi_os_path.os_path_join(pyi_os_path.os_path_join(SYS_PREFIX,
491                fullname.replace('.', pyi_os_path.os_sep)), '__init__.pyc')
492        else:
493            filename = pyi_os_path.os_path_join(SYS_PREFIX,
494                fullname.replace('.', pyi_os_path.os_sep) + '.pyc')
495        return filename
496
497    def find_spec(self, fullname, path=None, target=None):
498        """
499        PEP-451 finder.find_spec() method for the ``sys.meta_path`` hook.
500
501        fullname     fully qualified name of the module
502        path         None for a top-level module, or package.__path__ for
503                     submodules or subpackages.
504        target       unused by this Finder
505
506        Finders are still responsible for identifying, and typically creating,
507        the loader that should be used to load a module. That loader will now
508        be stored in the module spec returned by find_spec() rather than
509        returned directly. As is currently the case without the PEP-452, if a
510        loader would be costly to create, that loader can be designed to defer
511        the cost until later.
512
513        Finders must return ModuleSpec objects when find_spec() is called.
514        This new method replaces find_module() and find_loader() (in the
515        PathEntryFinder case). If a loader does not have find_spec(),
516        find_module() and find_loader() are used instead, for
517        backward-compatibility.
518        """
519        entry_name = None  # None means - no module found in this importer.
520
521        if fullname in self.toc:
522            entry_name = fullname
523            trace("import %s # PyInstaller PYZ", fullname)
524        elif path is not None:
525            # Try to handle module.__path__ modifications by the modules themselves
526            # Reverse the fake __path__ we added to the package module to a
527            # dotted module name and add the tail module from fullname onto that
528            # to synthesize a new fullname
529            modname = fullname.rsplit('.')[-1]
530
531            for p in path:
532                p = p[SYS_PREFIXLEN+1:]
533                parts = p.split(pyi_os_path.os_sep)
534                if not parts: continue
535                if not parts[0]:
536                    parts = parts[1:]
537                parts.append(modname)
538                entry_name = ".".join(parts)
539                if entry_name in self.toc:
540                    trace("import %s as %s # PyInstaller PYZ (__path__ override: %s)",
541                          entry_name, fullname, p)
542                    break
543            else:
544                entry_name = None
545
546        if entry_name is None:
547            trace("# %s not found in PYZ", fullname)
548            return None
549
550        # origin has to be the filename
551        origin = self.get_filename(entry_name)
552        is_pkg = self.is_package(entry_name)
553
554        spec =  _frozen_importlib.ModuleSpec(
555            fullname, self,
556            is_package=is_pkg, origin=origin,
557            # Provide the entry_name for the loader to use during loading
558            loader_state = entry_name)
559
560        # Make the import machinery set __file__.
561        # PEP 451 says: "has_location" is true if the module is locatable. In
562        # that case the spec's origin is used as the location and __file__ is
563        # set to spec.origin. If additional location information is required
564        # (e.g. zipimport), that information may be stored in
565        # spec.loader_state.
566        spec.has_location = True
567        return spec
568
569    def create_module(self, spec):
570        """
571        PEP-451 loader.create_module() method for the ``sys.meta_path`` hook.
572
573        Loaders may also implement create_module() that will return a new
574        module to exec. It may return None to indicate that the default module
575        creation code should be used. One use case, though atypical, for
576        create_module() is to provide a module that is a subclass of the
577        builtin module type. Most loaders will not need to implement
578        create_module(),
579
580        create_module() should properly handle the case where it is called
581        more than once for the same spec/module. This may include returning
582        None or raising ImportError.
583        """
584        # Opposed to what is defined in PEP-451, this method is not optional.
585        # We want the default results, so we simply return None (which is
586        # handled for su my the import machinery). See
587        # https://bugs.python.org/issue23014 for more information.
588        return None
589
590    def exec_module(self, module):
591        """
592        PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook.
593
594        Loaders will have a new method, exec_module(). Its only job is to
595        "exec" the module and consequently populate the module's namespace. It
596        is not responsible for creating or preparing the module object, nor
597        for any cleanup afterward. It has no return value. exec_module() will
598        be used during both loading and reloading.
599
600        exec_module() should properly handle the case where it is called more
601        than once. For some kinds of modules this may mean raising ImportError
602        every time after the first time the method is called. This is
603        particularly relevant for reloading, where some kinds of modules do
604        not support in-place reloading.
605        """
606        spec = module.__spec__
607        bytecode = self.get_code(spec.loader_state)
608
609        # Set by the import machinery
610        assert hasattr(module, '__file__')
611
612        # If `submodule_search_locations` is not None, this is a package;
613        # set __path__.
614        if spec.submodule_search_locations is not None:
615            # Since PYTHONHOME is set in bootloader, 'sys.prefix' points to
616            # the correct path where PyInstaller should find bundled dynamic
617            # libraries. In one-file mode it points to the tmp directory where
618            # bundled files are extracted at execution time.
619            #
620            # __path__ cannot be empty list because 'wx' module prepends
621            # something to it. It cannot contain value 'sys.prefix' because
622            # 'xml.etree.cElementTree' fails otherwise.
623            #
624            # Set __path__ to point to 'sys.prefix/package/subpackage'.
625            module.__path__ = [pyi_os_path.os_path_dirname(module.__file__)]
626
627        exec(bytecode, module.__dict__)
628
629
630# is_py2: This is only needed for Python 2.
631class CExtensionImporter(object):
632    """
633    PEP-302 hook for sys.meta_path to load Python C extension modules.
634
635    C extension modules are present on the sys.prefix as filenames:
636
637        full.module.name.pyd
638        full.module.name.so
639        full.module.name.cpython-33m.so
640        full.module.name.abi3.so
641    """
642    def __init__(self):
643        # Cache directory content for faster module lookup without
644        # file system access.
645        files = pyi_os_path.os_listdir(SYS_PREFIX)
646        self._file_cache = set(files)
647
648    def find_module(self, fullname, path=None):
649        # Deprecated in Python 3.4, see PEP-451
650        imp_lock()
651        module_loader = None  # None means - no module found by this importer.
652
653        # Look in the file list of sys.prefix path (alias PYTHONHOME).
654        for ext in EXTENSION_SUFFIXES:
655            if fullname + ext in self._file_cache:
656                module_loader = self
657                break
658
659        imp_unlock()
660        return module_loader
661
662    def load_module(self, fullname, path=None):
663        # Deprecated in Python 3.4, see PEP-451
664        imp_lock()
665
666        module = None
667
668        try:
669            if sys.version_info[0] == 2:
670                # Python 2 implementation - TODO drop or improve it. 'imp' module is no longer built-in.
671                # PEP302 If there is an existing module object named 'fullname'
672                # in sys.modules, the loader must use that existing module.
673                module = sys.modules.get(fullname)
674
675                if module is None:
676                    # Need to search for the filename again, since to
677                    # be thread-safe we can't store it in find_module().
678                    for ext, ext_tuple in EXTENSION_SUFFIXES.iteritems():
679                        filename = fullname + ext
680                        if filename in self._file_cache:
681                            break
682                    filename = pyi_os_path.os_path_join(SYS_PREFIX, filename)
683                    with open(filename, 'rb') as fp:
684                        module = imp.load_module(fullname, fp, filename, ext_tuple)
685                    # Set __file__ attribute.
686                    if hasattr(module, '__setattr__'):
687                        module.__file__ = filename
688                    else:
689                        # Some modules (eg: Python for .NET) have no __setattr__
690                        # and dict entry have to be set.
691                        module.__dict__['__file__'] = filename
692            else:
693                # PEP302 If there is an existing module object named 'fullname'
694                # in sys.modules, the loader must use that existing module.
695                module = sys.modules.get(fullname)
696                if module is None:
697                    # Python 3 implementation.
698                    for ext in EXTENSION_SUFFIXES:
699                        filename = pyi_os_path.os_path_join(SYS_PREFIX, fullname + ext)
700                        # Test if a file exists.
701                        # Cannot use os.path.exists. Use workaround with function open().
702                        # No exception means that a file exists.
703                        try:
704                            with open(filename):
705                                pass
706                        except IOError:
707                            # Continue trying new suffix.
708                            continue
709                        # Load module.
710                        loader = EXTENSION_LOADER(fullname, filename)
711                        try:
712                            module = loader.load_module(fullname)
713                        except ImportError as e:
714                            raise ImportError('%s: %s' % (e, fullname))
715
716        except Exception:
717            # Remove 'fullname' from sys.modules if it was appended there.
718            if fullname in sys.modules:
719                sys.modules.pop(fullname)
720            raise  # Raise the same exception again.
721
722        finally:
723            # Release the interpreter's import lock.
724            imp_unlock()
725
726        return module
727
728    ### Optional Extensions to the PEP302 Importer Protocol
729
730    def is_package(self, fullname):
731        """
732        Return always False since C extension modules are never packages.
733        """
734        return False
735
736    def get_code(self, fullname):
737        """
738        Return None for a C extension module.
739        """
740        for ext in EXTENSION_SUFFIXES:
741            if fullname + ext in self._file_cache:
742                return None
743        # If module was not found then function still continues.
744        # ImportError should be raised if module not found.
745        raise ImportError('No module named ' + fullname)
746
747    def get_source(self, fullname):
748        """
749        Return None for a C extension module.
750        """
751        # Same implementation as function self.get_code().
752        return self.get_code(fullname)
753
754    def get_data(self, path):
755        """
756        This returns the data as a string, or raise IOError if the "file"
757        wasn't found. The data is always returned as if "binary" mode was used.
758
759        The 'path' argument is a path that can be constructed by munging
760        module.__file__ (or pkg.__path__ items)
761        """
762        # Since __file__ attribute works properly just try to open and read it.
763        with open(path, 'rb') as fp:
764            return fp.read()
765
766    def get_filename(self, fullname):
767        """
768        This method should return the value that __file__ would be set to
769        if the named module was loaded. If the module is not found, then
770        ImportError should be raised.
771        """
772        for ext in EXTENSION_SUFFIXES:
773            if fullname + ext in self._file_cache:
774                return pyi_os_path.os_path_join(SYS_PREFIX, fullname + ext)
775        # ImportError should be raised if module not found.
776        raise ImportError('No module named ' + fullname)
777
778
779def install():
780    """
781    Install FrozenImporter class and other classes into the import machinery.
782
783    This class method (static method) installs the FrozenImporter class into
784    the import machinery of the running process. The importer is added
785    to sys.meta_path. It could be added to sys.path_hooks but sys.meta_path
786    is processed by Python before looking at sys.path!
787
788    The order of processing import hooks in sys.meta_path:
789
790    1. built-in modules
791    2. modules from the bundled ZIP archive
792    3. C extension modules
793    4. Modules from sys.path
794    """
795    # Python 3 already has _frozen_importlib.BuiltinImporter on sys.meta_path.
796    if sys.version_info[0] == 2:
797        # First look in the built-in modules and not bundled ZIP archive.
798        sys.meta_path.append(BuiltinImporter())
799
800    # Ensure Python looks in the bundled zip archive for modules before any
801    # other places.
802    fimp = FrozenImporter()
803    sys.meta_path.append(fimp)
804
805    if sys.version_info[0] == 2:
806        # _`path_hook installation`: Add the FrozenImporter to `sys.path_hook`,
807        # too, since `pkgutil.get_loader()` does not use `sys.meta_path`. See
808        # issue #1689.
809        sys.path_hooks.append(fimp)
810
811        # Import hook for renamed C extension modules. The path hook above means
812        # that the standard Python import system for C extensions will only work
813        # if those extensions are not in a submodule. In particular: A C
814        # extension such as ``foo.bar`` hasn't been loaded. ``sys.meta_path`` is
815        # checked, but provides no loader. ``sys.path_hooks`` is checked, and
816        # claims that it loads anything in ``foo``. Therefore, the default
817        # Python import mechanism will not be invoked, per `PEP 302
818        # <https://www.python.org/dev/peps/pep-0302/#id28>`_. This casues the
819        # import to fail, since the ``FrozenImporter`` class doesn't load C
820        # extensions.
821        sys.meta_path.append(CExtensionImporter())
822
823    else:
824        # On Windows there is importer _frozen_importlib.WindowsRegistryFinder that
825        # looks for Python modules in Windows registry. The frozen executable should
826        # not look for anything in the Windows registry. Remove this importer from
827        # sys.meta_path.
828        for item in sys.meta_path:
829            if hasattr(item, '__name__') and item.__name__ == 'WindowsRegistryFinder':
830                sys.meta_path.remove(item)
831                break
832        # _frozen_importlib.PathFinder is also able to handle Python C
833        # extensions. However, PyInstaller needs its own importer since it
834        # uses extension names like 'module.submodle.so' (instead of paths).
835        # As of Python 3.7.0b2, there are several PathFinder instances (and
836        # duplicate ones) on sys.meta_path. This propobly is a bug, see
837        # https://bugs.python.org/issue33128. Thus we need to move all of them
838        # to the end, eliminating duplicates .
839        pathFinders = []
840        for item in reversed(sys.meta_path):
841            if getattr(item, '__name__', None) == 'PathFinder':
842                sys.meta_path.remove(item)
843                if not item in pathFinders:
844                    pathFinders.append(item)
845        sys.meta_path.extend(reversed(pathFinders))
846        # TODO Do we need for Python 3 _frozen_importlib.FrozenImporter? Could it be also removed?
847