xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/importlib/_bootstrap.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1"""Core implementation of import.
2
3This module is NOT meant to be directly imported! It has been designed such
4that it can be bootstrapped into Python as the implementation of import. As
5such it requires the injection of specific modules and attributes in order to
6work. One should use importlib as the public-facing version of this module.
7
8"""
9#
10# IMPORTANT: Whenever making changes to this module, be sure to run a top-level
11# `make regen-importlib` followed by `make` in order to get the frozen version
12# of the module updated. Not doing so will result in the Makefile to fail for
13# all others who don't have a ./python around to freeze the module
14# in the early stages of compilation.
15#
16
17# See importlib._setup() for what is injected into the global namespace.
18
19# When editing this code be aware that code executed at import time CANNOT
20# reference any injected objects! This includes not only global code but also
21# anything specified at the class level.
22
23def _object_name(obj):
24    try:
25        return obj.__qualname__
26    except AttributeError:
27        return type(obj).__qualname__
28
29# Bootstrap-related code ######################################################
30
31# Modules injected manually by _setup()
32_thread = None
33_warnings = None
34_weakref = None
35
36# Import done by _install_external_importers()
37_bootstrap_external = None
38
39
40def _wrap(new, old):
41    """Simple substitute for functools.update_wrapper."""
42    for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
43        if hasattr(old, replace):
44            setattr(new, replace, getattr(old, replace))
45    new.__dict__.update(old.__dict__)
46
47
48def _new_module(name):
49    return type(sys)(name)
50
51
52# Module-level locking ########################################################
53
54# A dict mapping module names to weakrefs of _ModuleLock instances
55# Dictionary protected by the global import lock
56_module_locks = {}
57# A dict mapping thread ids to _ModuleLock instances
58_blocking_on = {}
59
60
61class _DeadlockError(RuntimeError):
62    pass
63
64
65class _ModuleLock:
66    """A recursive lock implementation which is able to detect deadlocks
67    (e.g. thread 1 trying to take locks A then B, and thread 2 trying to
68    take locks B then A).
69    """
70
71    def __init__(self, name):
72        self.lock = _thread.allocate_lock()
73        self.wakeup = _thread.allocate_lock()
74        self.name = name
75        self.owner = None
76        self.count = 0
77        self.waiters = 0
78
79    def has_deadlock(self):
80        # Deadlock avoidance for concurrent circular imports.
81        me = _thread.get_ident()
82        tid = self.owner
83        seen = set()
84        while True:
85            lock = _blocking_on.get(tid)
86            if lock is None:
87                return False
88            tid = lock.owner
89            if tid == me:
90                return True
91            if tid in seen:
92                # bpo 38091: the chain of tid's we encounter here
93                # eventually leads to a fixpoint or a cycle, but
94                # does not reach 'me'.  This means we would not
95                # actually deadlock.  This can happen if other
96                # threads are at the beginning of acquire() below.
97                return False
98            seen.add(tid)
99
100    def acquire(self):
101        """
102        Acquire the module lock.  If a potential deadlock is detected,
103        a _DeadlockError is raised.
104        Otherwise, the lock is always acquired and True is returned.
105        """
106        tid = _thread.get_ident()
107        _blocking_on[tid] = self
108        try:
109            while True:
110                with self.lock:
111                    if self.count == 0 or self.owner == tid:
112                        self.owner = tid
113                        self.count += 1
114                        return True
115                    if self.has_deadlock():
116                        raise _DeadlockError('deadlock detected by %r' % self)
117                    if self.wakeup.acquire(False):
118                        self.waiters += 1
119                # Wait for a release() call
120                self.wakeup.acquire()
121                self.wakeup.release()
122        finally:
123            del _blocking_on[tid]
124
125    def release(self):
126        tid = _thread.get_ident()
127        with self.lock:
128            if self.owner != tid:
129                raise RuntimeError('cannot release un-acquired lock')
130            assert self.count > 0
131            self.count -= 1
132            if self.count == 0:
133                self.owner = None
134                if self.waiters:
135                    self.waiters -= 1
136                    self.wakeup.release()
137
138    def __repr__(self):
139        return '_ModuleLock({!r}) at {}'.format(self.name, id(self))
140
141
142class _DummyModuleLock:
143    """A simple _ModuleLock equivalent for Python builds without
144    multi-threading support."""
145
146    def __init__(self, name):
147        self.name = name
148        self.count = 0
149
150    def acquire(self):
151        self.count += 1
152        return True
153
154    def release(self):
155        if self.count == 0:
156            raise RuntimeError('cannot release un-acquired lock')
157        self.count -= 1
158
159    def __repr__(self):
160        return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self))
161
162
163class _ModuleLockManager:
164
165    def __init__(self, name):
166        self._name = name
167        self._lock = None
168
169    def __enter__(self):
170        self._lock = _get_module_lock(self._name)
171        self._lock.acquire()
172
173    def __exit__(self, *args, **kwargs):
174        self._lock.release()
175
176
177# The following two functions are for consumption by Python/import.c.
178
179def _get_module_lock(name):
180    """Get or create the module lock for a given module name.
181
182    Acquire/release internally the global import lock to protect
183    _module_locks."""
184
185    _imp.acquire_lock()
186    try:
187        try:
188            lock = _module_locks[name]()
189        except KeyError:
190            lock = None
191
192        if lock is None:
193            if _thread is None:
194                lock = _DummyModuleLock(name)
195            else:
196                lock = _ModuleLock(name)
197
198            def cb(ref, name=name):
199                _imp.acquire_lock()
200                try:
201                    # bpo-31070: Check if another thread created a new lock
202                    # after the previous lock was destroyed
203                    # but before the weakref callback was called.
204                    if _module_locks.get(name) is ref:
205                        del _module_locks[name]
206                finally:
207                    _imp.release_lock()
208
209            _module_locks[name] = _weakref.ref(lock, cb)
210    finally:
211        _imp.release_lock()
212
213    return lock
214
215
216def _lock_unlock_module(name):
217    """Acquires then releases the module lock for a given module name.
218
219    This is used to ensure a module is completely initialized, in the
220    event it is being imported by another thread.
221    """
222    lock = _get_module_lock(name)
223    try:
224        lock.acquire()
225    except _DeadlockError:
226        # Concurrent circular import, we'll accept a partially initialized
227        # module object.
228        pass
229    else:
230        lock.release()
231
232# Frame stripping magic ###############################################
233def _call_with_frames_removed(f, *args, **kwds):
234    """remove_importlib_frames in import.c will always remove sequences
235    of importlib frames that end with a call to this function
236
237    Use it instead of a normal call in places where including the importlib
238    frames introduces unwanted noise into the traceback (e.g. when executing
239    module code)
240    """
241    return f(*args, **kwds)
242
243
244def _verbose_message(message, *args, verbosity=1):
245    """Print the message to stderr if -v/PYTHONVERBOSE is turned on."""
246    if sys.flags.verbose >= verbosity:
247        if not message.startswith(('#', 'import ')):
248            message = '# ' + message
249        print(message.format(*args), file=sys.stderr)
250
251
252def _requires_builtin(fxn):
253    """Decorator to verify the named module is built-in."""
254    def _requires_builtin_wrapper(self, fullname):
255        if fullname not in sys.builtin_module_names:
256            raise ImportError('{!r} is not a built-in module'.format(fullname),
257                              name=fullname)
258        return fxn(self, fullname)
259    _wrap(_requires_builtin_wrapper, fxn)
260    return _requires_builtin_wrapper
261
262
263def _requires_frozen(fxn):
264    """Decorator to verify the named module is frozen."""
265    def _requires_frozen_wrapper(self, fullname):
266        if not _imp.is_frozen(fullname):
267            raise ImportError('{!r} is not a frozen module'.format(fullname),
268                              name=fullname)
269        return fxn(self, fullname)
270    _wrap(_requires_frozen_wrapper, fxn)
271    return _requires_frozen_wrapper
272
273
274# Typically used by loader classes as a method replacement.
275def _load_module_shim(self, fullname):
276    """Load the specified module into sys.modules and return it.
277
278    This method is deprecated.  Use loader.exec_module() instead.
279
280    """
281    msg = ("the load_module() method is deprecated and slated for removal in "
282          "Python 3.12; use exec_module() instead")
283    _warnings.warn(msg, DeprecationWarning)
284    spec = spec_from_loader(fullname, self)
285    if fullname in sys.modules:
286        module = sys.modules[fullname]
287        _exec(spec, module)
288        return sys.modules[fullname]
289    else:
290        return _load(spec)
291
292# Module specifications #######################################################
293
294def _module_repr(module):
295    """The implementation of ModuleType.__repr__()."""
296    loader = getattr(module, '__loader__', None)
297    if spec := getattr(module, "__spec__", None):
298        return _module_repr_from_spec(spec)
299    elif hasattr(loader, 'module_repr'):
300        try:
301            return loader.module_repr(module)
302        except Exception:
303            pass
304    # Fall through to a catch-all which always succeeds.
305    try:
306        name = module.__name__
307    except AttributeError:
308        name = '?'
309    try:
310        filename = module.__file__
311    except AttributeError:
312        if loader is None:
313            return '<module {!r}>'.format(name)
314        else:
315            return '<module {!r} ({!r})>'.format(name, loader)
316    else:
317        return '<module {!r} from {!r}>'.format(name, filename)
318
319
320class ModuleSpec:
321    """The specification for a module, used for loading.
322
323    A module's spec is the source for information about the module.  For
324    data associated with the module, including source, use the spec's
325    loader.
326
327    `name` is the absolute name of the module.  `loader` is the loader
328    to use when loading the module.  `parent` is the name of the
329    package the module is in.  The parent is derived from the name.
330
331    `is_package` determines if the module is considered a package or
332    not.  On modules this is reflected by the `__path__` attribute.
333
334    `origin` is the specific location used by the loader from which to
335    load the module, if that information is available.  When filename is
336    set, origin will match.
337
338    `has_location` indicates that a spec's "origin" reflects a location.
339    When this is True, `__file__` attribute of the module is set.
340
341    `cached` is the location of the cached bytecode file, if any.  It
342    corresponds to the `__cached__` attribute.
343
344    `submodule_search_locations` is the sequence of path entries to
345    search when importing submodules.  If set, is_package should be
346    True--and False otherwise.
347
348    Packages are simply modules that (may) have submodules.  If a spec
349    has a non-None value in `submodule_search_locations`, the import
350    system will consider modules loaded from the spec as packages.
351
352    Only finders (see importlib.abc.MetaPathFinder and
353    importlib.abc.PathEntryFinder) should modify ModuleSpec instances.
354
355    """
356
357    def __init__(self, name, loader, *, origin=None, loader_state=None,
358                 is_package=None):
359        self.name = name
360        self.loader = loader
361        self.origin = origin
362        self.loader_state = loader_state
363        self.submodule_search_locations = [] if is_package else None
364        self._uninitialized_submodules = []
365
366        # file-location attributes
367        self._set_fileattr = False
368        self._cached = None
369
370    def __repr__(self):
371        args = ['name={!r}'.format(self.name),
372                'loader={!r}'.format(self.loader)]
373        if self.origin is not None:
374            args.append('origin={!r}'.format(self.origin))
375        if self.submodule_search_locations is not None:
376            args.append('submodule_search_locations={}'
377                        .format(self.submodule_search_locations))
378        return '{}({})'.format(self.__class__.__name__, ', '.join(args))
379
380    def __eq__(self, other):
381        smsl = self.submodule_search_locations
382        try:
383            return (self.name == other.name and
384                    self.loader == other.loader and
385                    self.origin == other.origin and
386                    smsl == other.submodule_search_locations and
387                    self.cached == other.cached and
388                    self.has_location == other.has_location)
389        except AttributeError:
390            return NotImplemented
391
392    @property
393    def cached(self):
394        if self._cached is None:
395            if self.origin is not None and self._set_fileattr:
396                if _bootstrap_external is None:
397                    raise NotImplementedError
398                self._cached = _bootstrap_external._get_cached(self.origin)
399        return self._cached
400
401    @cached.setter
402    def cached(self, cached):
403        self._cached = cached
404
405    @property
406    def parent(self):
407        """The name of the module's parent."""
408        if self.submodule_search_locations is None:
409            return self.name.rpartition('.')[0]
410        else:
411            return self.name
412
413    @property
414    def has_location(self):
415        return self._set_fileattr
416
417    @has_location.setter
418    def has_location(self, value):
419        self._set_fileattr = bool(value)
420
421
422def spec_from_loader(name, loader, *, origin=None, is_package=None):
423    """Return a module spec based on various loader methods."""
424    if origin is None:
425        origin = getattr(loader, '_ORIGIN', None)
426
427    if not origin and hasattr(loader, 'get_filename'):
428        if _bootstrap_external is None:
429            raise NotImplementedError
430        spec_from_file_location = _bootstrap_external.spec_from_file_location
431
432        if is_package is None:
433            return spec_from_file_location(name, loader=loader)
434        search = [] if is_package else None
435        return spec_from_file_location(name, loader=loader,
436                                       submodule_search_locations=search)
437
438    if is_package is None:
439        if hasattr(loader, 'is_package'):
440            try:
441                is_package = loader.is_package(name)
442            except ImportError:
443                is_package = None  # aka, undefined
444        else:
445            # the default
446            is_package = False
447
448    return ModuleSpec(name, loader, origin=origin, is_package=is_package)
449
450
451def _spec_from_module(module, loader=None, origin=None):
452    # This function is meant for use in _setup().
453    try:
454        spec = module.__spec__
455    except AttributeError:
456        pass
457    else:
458        if spec is not None:
459            return spec
460
461    name = module.__name__
462    if loader is None:
463        try:
464            loader = module.__loader__
465        except AttributeError:
466            # loader will stay None.
467            pass
468    try:
469        location = module.__file__
470    except AttributeError:
471        location = None
472    if origin is None:
473        if loader is not None:
474            origin = getattr(loader, '_ORIGIN', None)
475        if not origin and location is not None:
476            origin = location
477    try:
478        cached = module.__cached__
479    except AttributeError:
480        cached = None
481    try:
482        submodule_search_locations = list(module.__path__)
483    except AttributeError:
484        submodule_search_locations = None
485
486    spec = ModuleSpec(name, loader, origin=origin)
487    spec._set_fileattr = False if location is None else (origin == location)
488    spec.cached = cached
489    spec.submodule_search_locations = submodule_search_locations
490    return spec
491
492
493def _init_module_attrs(spec, module, *, override=False):
494    # The passed-in module may be not support attribute assignment,
495    # in which case we simply don't set the attributes.
496    # __name__
497    if (override or getattr(module, '__name__', None) is None):
498        try:
499            module.__name__ = spec.name
500        except AttributeError:
501            pass
502    # __loader__
503    if override or getattr(module, '__loader__', None) is None:
504        loader = spec.loader
505        if loader is None:
506            # A backward compatibility hack.
507            if spec.submodule_search_locations is not None:
508                if _bootstrap_external is None:
509                    raise NotImplementedError
510                NamespaceLoader = _bootstrap_external.NamespaceLoader
511
512                loader = NamespaceLoader.__new__(NamespaceLoader)
513                loader._path = spec.submodule_search_locations
514                spec.loader = loader
515                # While the docs say that module.__file__ is not set for
516                # built-in modules, and the code below will avoid setting it if
517                # spec.has_location is false, this is incorrect for namespace
518                # packages.  Namespace packages have no location, but their
519                # __spec__.origin is None, and thus their module.__file__
520                # should also be None for consistency.  While a bit of a hack,
521                # this is the best place to ensure this consistency.
522                #
523                # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module
524                # and bpo-32305
525                module.__file__ = None
526        try:
527            module.__loader__ = loader
528        except AttributeError:
529            pass
530    # __package__
531    if override or getattr(module, '__package__', None) is None:
532        try:
533            module.__package__ = spec.parent
534        except AttributeError:
535            pass
536    # __spec__
537    try:
538        module.__spec__ = spec
539    except AttributeError:
540        pass
541    # __path__
542    if override or getattr(module, '__path__', None) is None:
543        if spec.submodule_search_locations is not None:
544            # XXX We should extend __path__ if it's already a list.
545            try:
546                module.__path__ = spec.submodule_search_locations
547            except AttributeError:
548                pass
549    # __file__/__cached__
550    if spec.has_location:
551        if override or getattr(module, '__file__', None) is None:
552            try:
553                module.__file__ = spec.origin
554            except AttributeError:
555                pass
556
557        if override or getattr(module, '__cached__', None) is None:
558            if spec.cached is not None:
559                try:
560                    module.__cached__ = spec.cached
561                except AttributeError:
562                    pass
563    return module
564
565
566def module_from_spec(spec):
567    """Create a module based on the provided spec."""
568    # Typically loaders will not implement create_module().
569    module = None
570    if hasattr(spec.loader, 'create_module'):
571        # If create_module() returns `None` then it means default
572        # module creation should be used.
573        module = spec.loader.create_module(spec)
574    elif hasattr(spec.loader, 'exec_module'):
575        raise ImportError('loaders that define exec_module() '
576                          'must also define create_module()')
577    if module is None:
578        module = _new_module(spec.name)
579    _init_module_attrs(spec, module)
580    return module
581
582
583def _module_repr_from_spec(spec):
584    """Return the repr to use for the module."""
585    # We mostly replicate _module_repr() using the spec attributes.
586    name = '?' if spec.name is None else spec.name
587    if spec.origin is None:
588        if spec.loader is None:
589            return '<module {!r}>'.format(name)
590        else:
591            return '<module {!r} ({!r})>'.format(name, spec.loader)
592    else:
593        if spec.has_location:
594            return '<module {!r} from {!r}>'.format(name, spec.origin)
595        else:
596            return '<module {!r} ({})>'.format(spec.name, spec.origin)
597
598
599# Used by importlib.reload() and _load_module_shim().
600def _exec(spec, module):
601    """Execute the spec's specified module in an existing module's namespace."""
602    name = spec.name
603    with _ModuleLockManager(name):
604        if sys.modules.get(name) is not module:
605            msg = 'module {!r} not in sys.modules'.format(name)
606            raise ImportError(msg, name=name)
607        try:
608            if spec.loader is None:
609                if spec.submodule_search_locations is None:
610                    raise ImportError('missing loader', name=spec.name)
611                # Namespace package.
612                _init_module_attrs(spec, module, override=True)
613            else:
614                _init_module_attrs(spec, module, override=True)
615                if not hasattr(spec.loader, 'exec_module'):
616                    msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
617                           "falling back to load_module()")
618                    _warnings.warn(msg, ImportWarning)
619                    spec.loader.load_module(name)
620                else:
621                    spec.loader.exec_module(module)
622        finally:
623            # Update the order of insertion into sys.modules for module
624            # clean-up at shutdown.
625            module = sys.modules.pop(spec.name)
626            sys.modules[spec.name] = module
627    return module
628
629
630def _load_backward_compatible(spec):
631    # It is assumed that all callers have been warned about using load_module()
632    # appropriately before calling this function.
633    try:
634        spec.loader.load_module(spec.name)
635    except:
636        if spec.name in sys.modules:
637            module = sys.modules.pop(spec.name)
638            sys.modules[spec.name] = module
639        raise
640    # The module must be in sys.modules at this point!
641    # Move it to the end of sys.modules.
642    module = sys.modules.pop(spec.name)
643    sys.modules[spec.name] = module
644    if getattr(module, '__loader__', None) is None:
645        try:
646            module.__loader__ = spec.loader
647        except AttributeError:
648            pass
649    if getattr(module, '__package__', None) is None:
650        try:
651            # Since module.__path__ may not line up with
652            # spec.submodule_search_paths, we can't necessarily rely
653            # on spec.parent here.
654            module.__package__ = module.__name__
655            if not hasattr(module, '__path__'):
656                module.__package__ = spec.name.rpartition('.')[0]
657        except AttributeError:
658            pass
659    if getattr(module, '__spec__', None) is None:
660        try:
661            module.__spec__ = spec
662        except AttributeError:
663            pass
664    return module
665
666def _load_unlocked(spec):
667    # A helper for direct use by the import system.
668    if spec.loader is not None:
669        # Not a namespace package.
670        if not hasattr(spec.loader, 'exec_module'):
671            msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
672                    "falling back to load_module()")
673            _warnings.warn(msg, ImportWarning)
674            return _load_backward_compatible(spec)
675
676    module = module_from_spec(spec)
677
678    # This must be done before putting the module in sys.modules
679    # (otherwise an optimization shortcut in import.c becomes
680    # wrong).
681    spec._initializing = True
682    try:
683        sys.modules[spec.name] = module
684        try:
685            if spec.loader is None:
686                if spec.submodule_search_locations is None:
687                    raise ImportError('missing loader', name=spec.name)
688                # A namespace package so do nothing.
689            else:
690                spec.loader.exec_module(module)
691        except:
692            try:
693                del sys.modules[spec.name]
694            except KeyError:
695                pass
696            raise
697        # Move the module to the end of sys.modules.
698        # We don't ensure that the import-related module attributes get
699        # set in the sys.modules replacement case.  Such modules are on
700        # their own.
701        module = sys.modules.pop(spec.name)
702        sys.modules[spec.name] = module
703        _verbose_message('import {!r} # {!r}', spec.name, spec.loader)
704    finally:
705        spec._initializing = False
706
707    return module
708
709# A method used during testing of _load_unlocked() and by
710# _load_module_shim().
711def _load(spec):
712    """Return a new module object, loaded by the spec's loader.
713
714    The module is not added to its parent.
715
716    If a module is already in sys.modules, that existing module gets
717    clobbered.
718
719    """
720    with _ModuleLockManager(spec.name):
721        return _load_unlocked(spec)
722
723
724# Loaders #####################################################################
725
726class BuiltinImporter:
727
728    """Meta path import for built-in modules.
729
730    All methods are either class or static methods to avoid the need to
731    instantiate the class.
732
733    """
734
735    _ORIGIN = "built-in"
736
737    @staticmethod
738    def module_repr(module):
739        """Return repr for the module.
740
741        The method is deprecated.  The import machinery does the job itself.
742
743        """
744        _warnings.warn("BuiltinImporter.module_repr() is deprecated and "
745                       "slated for removal in Python 3.12", DeprecationWarning)
746        return f'<module {module.__name__!r} ({BuiltinImporter._ORIGIN})>'
747
748    @classmethod
749    def find_spec(cls, fullname, path=None, target=None):
750        if _imp.is_builtin(fullname):
751            return spec_from_loader(fullname, cls, origin=cls._ORIGIN)
752        else:
753            return None
754
755    @classmethod
756    def find_module(cls, fullname, path=None):
757        """Find the built-in module.
758
759        If 'path' is ever specified then the search is considered a failure.
760
761        This method is deprecated.  Use find_spec() instead.
762
763        """
764        _warnings.warn("BuiltinImporter.find_module() is deprecated and "
765                       "slated for removal in Python 3.12; use find_spec() instead",
766                       DeprecationWarning)
767        spec = cls.find_spec(fullname, path)
768        return spec.loader if spec is not None else None
769
770    @staticmethod
771    def create_module(spec):
772        """Create a built-in module"""
773        if spec.name not in sys.builtin_module_names:
774            raise ImportError('{!r} is not a built-in module'.format(spec.name),
775                              name=spec.name)
776        return _call_with_frames_removed(_imp.create_builtin, spec)
777
778    @staticmethod
779    def exec_module(module):
780        """Exec a built-in module"""
781        _call_with_frames_removed(_imp.exec_builtin, module)
782
783    @classmethod
784    @_requires_builtin
785    def get_code(cls, fullname):
786        """Return None as built-in modules do not have code objects."""
787        return None
788
789    @classmethod
790    @_requires_builtin
791    def get_source(cls, fullname):
792        """Return None as built-in modules do not have source code."""
793        return None
794
795    @classmethod
796    @_requires_builtin
797    def is_package(cls, fullname):
798        """Return False as built-in modules are never packages."""
799        return False
800
801    load_module = classmethod(_load_module_shim)
802
803
804class FrozenImporter:
805
806    """Meta path import for frozen modules.
807
808    All methods are either class or static methods to avoid the need to
809    instantiate the class.
810
811    """
812
813    _ORIGIN = "frozen"
814
815    @staticmethod
816    def module_repr(m):
817        """Return repr for the module.
818
819        The method is deprecated.  The import machinery does the job itself.
820
821        """
822        _warnings.warn("FrozenImporter.module_repr() is deprecated and "
823                       "slated for removal in Python 3.12", DeprecationWarning)
824        return '<module {!r} ({})>'.format(m.__name__, FrozenImporter._ORIGIN)
825
826    @classmethod
827    def _fix_up_module(cls, module):
828        spec = module.__spec__
829        state = spec.loader_state
830        if state is None:
831            # The module is missing FrozenImporter-specific values.
832
833            # Fix up the spec attrs.
834            origname = vars(module).pop('__origname__', None)
835            assert origname, 'see PyImport_ImportFrozenModuleObject()'
836            ispkg = hasattr(module, '__path__')
837            assert _imp.is_frozen_package(module.__name__) == ispkg, ispkg
838            filename, pkgdir = cls._resolve_filename(origname, spec.name, ispkg)
839            spec.loader_state = type(sys.implementation)(
840                filename=filename,
841                origname=origname,
842            )
843            __path__ = spec.submodule_search_locations
844            if ispkg:
845                assert __path__ == [], __path__
846                if pkgdir:
847                    spec.submodule_search_locations.insert(0, pkgdir)
848            else:
849                assert __path__ is None, __path__
850
851            # Fix up the module attrs (the bare minimum).
852            assert not hasattr(module, '__file__'), module.__file__
853            if filename:
854                try:
855                    module.__file__ = filename
856                except AttributeError:
857                    pass
858            if ispkg:
859                if module.__path__ != __path__:
860                    assert module.__path__ == [], module.__path__
861                    module.__path__.extend(__path__)
862        else:
863            # These checks ensure that _fix_up_module() is only called
864            # in the right places.
865            __path__ = spec.submodule_search_locations
866            ispkg = __path__ is not None
867            # Check the loader state.
868            assert sorted(vars(state)) == ['filename', 'origname'], state
869            if state.origname:
870                # The only frozen modules with "origname" set are stdlib modules.
871                (__file__, pkgdir,
872                 ) = cls._resolve_filename(state.origname, spec.name, ispkg)
873                assert state.filename == __file__, (state.filename, __file__)
874                if pkgdir:
875                    assert __path__ == [pkgdir], (__path__, pkgdir)
876                else:
877                    assert __path__ == ([] if ispkg else None), __path__
878            else:
879                __file__ = None
880                assert state.filename is None, state.filename
881                assert __path__ == ([] if ispkg else None), __path__
882            # Check the file attrs.
883            if __file__:
884                assert hasattr(module, '__file__')
885                assert module.__file__ == __file__, (module.__file__, __file__)
886            else:
887                assert not hasattr(module, '__file__'), module.__file__
888            if ispkg:
889                assert hasattr(module, '__path__')
890                assert module.__path__ == __path__, (module.__path__, __path__)
891            else:
892                assert not hasattr(module, '__path__'), module.__path__
893        assert not spec.has_location
894
895    @classmethod
896    def _resolve_filename(cls, fullname, alias=None, ispkg=False):
897        if not fullname or not getattr(sys, '_stdlib_dir', None):
898            return None, None
899        try:
900            sep = cls._SEP
901        except AttributeError:
902            sep = cls._SEP = '\\' if sys.platform == 'win32' else '/'
903
904        if fullname != alias:
905            if fullname.startswith('<'):
906                fullname = fullname[1:]
907                if not ispkg:
908                    fullname = f'{fullname}.__init__'
909            else:
910                ispkg = False
911        relfile = fullname.replace('.', sep)
912        if ispkg:
913            pkgdir = f'{sys._stdlib_dir}{sep}{relfile}'
914            filename = f'{pkgdir}{sep}__init__.py'
915        else:
916            pkgdir = None
917            filename = f'{sys._stdlib_dir}{sep}{relfile}.py'
918        return filename, pkgdir
919
920    @classmethod
921    def find_spec(cls, fullname, path=None, target=None):
922        info = _call_with_frames_removed(_imp.find_frozen, fullname)
923        if info is None:
924            return None
925        # We get the marshaled data in exec_module() (the loader
926        # part of the importer), instead of here (the finder part).
927        # The loader is the usual place to get the data that will
928        # be loaded into the module.  (For example, see _LoaderBasics
929        # in _bootstra_external.py.)  Most importantly, this importer
930        # is simpler if we wait to get the data.
931        # However, getting as much data in the finder as possible
932        # to later load the module is okay, and sometimes important.
933        # (That's why ModuleSpec.loader_state exists.)  This is
934        # especially true if it avoids throwing away expensive data
935        # the loader would otherwise duplicate later and can be done
936        # efficiently.  In this case it isn't worth it.
937        _, ispkg, origname = info
938        spec = spec_from_loader(fullname, cls,
939                                origin=cls._ORIGIN,
940                                is_package=ispkg)
941        filename, pkgdir = cls._resolve_filename(origname, fullname, ispkg)
942        spec.loader_state = type(sys.implementation)(
943            filename=filename,
944            origname=origname,
945        )
946        if pkgdir:
947            spec.submodule_search_locations.insert(0, pkgdir)
948        return spec
949
950    @classmethod
951    def find_module(cls, fullname, path=None):
952        """Find a frozen module.
953
954        This method is deprecated.  Use find_spec() instead.
955
956        """
957        _warnings.warn("FrozenImporter.find_module() is deprecated and "
958                       "slated for removal in Python 3.12; use find_spec() instead",
959                       DeprecationWarning)
960        return cls if _imp.is_frozen(fullname) else None
961
962    @staticmethod
963    def create_module(spec):
964        """Set __file__, if able."""
965        module = _new_module(spec.name)
966        try:
967            filename = spec.loader_state.filename
968        except AttributeError:
969            pass
970        else:
971            if filename:
972                module.__file__ = filename
973        return module
974
975    @staticmethod
976    def exec_module(module):
977        spec = module.__spec__
978        name = spec.name
979        code = _call_with_frames_removed(_imp.get_frozen_object, name)
980        exec(code, module.__dict__)
981
982    @classmethod
983    def load_module(cls, fullname):
984        """Load a frozen module.
985
986        This method is deprecated.  Use exec_module() instead.
987
988        """
989        # Warning about deprecation implemented in _load_module_shim().
990        module = _load_module_shim(cls, fullname)
991        info = _imp.find_frozen(fullname)
992        assert info is not None
993        _, ispkg, origname = info
994        module.__origname__ = origname
995        vars(module).pop('__file__', None)
996        if ispkg:
997            module.__path__ = []
998        cls._fix_up_module(module)
999        return module
1000
1001    @classmethod
1002    @_requires_frozen
1003    def get_code(cls, fullname):
1004        """Return the code object for the frozen module."""
1005        return _imp.get_frozen_object(fullname)
1006
1007    @classmethod
1008    @_requires_frozen
1009    def get_source(cls, fullname):
1010        """Return None as frozen modules do not have source code."""
1011        return None
1012
1013    @classmethod
1014    @_requires_frozen
1015    def is_package(cls, fullname):
1016        """Return True if the frozen module is a package."""
1017        return _imp.is_frozen_package(fullname)
1018
1019
1020# Import itself ###############################################################
1021
1022class _ImportLockContext:
1023
1024    """Context manager for the import lock."""
1025
1026    def __enter__(self):
1027        """Acquire the import lock."""
1028        _imp.acquire_lock()
1029
1030    def __exit__(self, exc_type, exc_value, exc_traceback):
1031        """Release the import lock regardless of any raised exceptions."""
1032        _imp.release_lock()
1033
1034
1035def _resolve_name(name, package, level):
1036    """Resolve a relative module name to an absolute one."""
1037    bits = package.rsplit('.', level - 1)
1038    if len(bits) < level:
1039        raise ImportError('attempted relative import beyond top-level package')
1040    base = bits[0]
1041    return '{}.{}'.format(base, name) if name else base
1042
1043
1044def _find_spec_legacy(finder, name, path):
1045    msg = (f"{_object_name(finder)}.find_spec() not found; "
1046                           "falling back to find_module()")
1047    _warnings.warn(msg, ImportWarning)
1048    loader = finder.find_module(name, path)
1049    if loader is None:
1050        return None
1051    return spec_from_loader(name, loader)
1052
1053
1054def _find_spec(name, path, target=None):
1055    """Find a module's spec."""
1056    meta_path = sys.meta_path
1057    if meta_path is None:
1058        # PyImport_Cleanup() is running or has been called.
1059        raise ImportError("sys.meta_path is None, Python is likely "
1060                          "shutting down")
1061
1062    if not meta_path:
1063        _warnings.warn('sys.meta_path is empty', ImportWarning)
1064
1065    # We check sys.modules here for the reload case.  While a passed-in
1066    # target will usually indicate a reload there is no guarantee, whereas
1067    # sys.modules provides one.
1068    is_reload = name in sys.modules
1069    for finder in meta_path:
1070        with _ImportLockContext():
1071            try:
1072                find_spec = finder.find_spec
1073            except AttributeError:
1074                spec = _find_spec_legacy(finder, name, path)
1075                if spec is None:
1076                    continue
1077            else:
1078                spec = find_spec(name, path, target)
1079        if spec is not None:
1080            # The parent import may have already imported this module.
1081            if not is_reload and name in sys.modules:
1082                module = sys.modules[name]
1083                try:
1084                    __spec__ = module.__spec__
1085                except AttributeError:
1086                    # We use the found spec since that is the one that
1087                    # we would have used if the parent module hadn't
1088                    # beaten us to the punch.
1089                    return spec
1090                else:
1091                    if __spec__ is None:
1092                        return spec
1093                    else:
1094                        return __spec__
1095            else:
1096                return spec
1097    else:
1098        return None
1099
1100
1101def _sanity_check(name, package, level):
1102    """Verify arguments are "sane"."""
1103    if not isinstance(name, str):
1104        raise TypeError('module name must be str, not {}'.format(type(name)))
1105    if level < 0:
1106        raise ValueError('level must be >= 0')
1107    if level > 0:
1108        if not isinstance(package, str):
1109            raise TypeError('__package__ not set to a string')
1110        elif not package:
1111            raise ImportError('attempted relative import with no known parent '
1112                              'package')
1113    if not name and level == 0:
1114        raise ValueError('Empty module name')
1115
1116
1117_ERR_MSG_PREFIX = 'No module named '
1118_ERR_MSG = _ERR_MSG_PREFIX + '{!r}'
1119
1120def _find_and_load_unlocked(name, import_):
1121    path = None
1122    parent = name.rpartition('.')[0]
1123    parent_spec = None
1124    if parent:
1125        if parent not in sys.modules:
1126            _call_with_frames_removed(import_, parent)
1127        # Crazy side-effects!
1128        if name in sys.modules:
1129            return sys.modules[name]
1130        parent_module = sys.modules[parent]
1131        try:
1132            path = parent_module.__path__
1133        except AttributeError:
1134            msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent)
1135            raise ModuleNotFoundError(msg, name=name) from None
1136        parent_spec = parent_module.__spec__
1137        child = name.rpartition('.')[2]
1138    spec = _find_spec(name, path)
1139    if spec is None:
1140        raise ModuleNotFoundError(_ERR_MSG.format(name), name=name)
1141    else:
1142        if parent_spec:
1143            # Temporarily add child we are currently importing to parent's
1144            # _uninitialized_submodules for circular import tracking.
1145            parent_spec._uninitialized_submodules.append(child)
1146        try:
1147            module = _load_unlocked(spec)
1148        finally:
1149            if parent_spec:
1150                parent_spec._uninitialized_submodules.pop()
1151    if parent:
1152        # Set the module as an attribute on its parent.
1153        parent_module = sys.modules[parent]
1154        try:
1155            setattr(parent_module, child, module)
1156        except AttributeError:
1157            msg = f"Cannot set an attribute on {parent!r} for child module {child!r}"
1158            _warnings.warn(msg, ImportWarning)
1159    return module
1160
1161
1162_NEEDS_LOADING = object()
1163
1164
1165def _find_and_load(name, import_):
1166    """Find and load the module."""
1167
1168    # Optimization: we avoid unneeded module locking if the module
1169    # already exists in sys.modules and is fully initialized.
1170    module = sys.modules.get(name, _NEEDS_LOADING)
1171    if (module is _NEEDS_LOADING or
1172        getattr(getattr(module, "__spec__", None), "_initializing", False)):
1173        with _ModuleLockManager(name):
1174            module = sys.modules.get(name, _NEEDS_LOADING)
1175            if module is _NEEDS_LOADING:
1176                return _find_and_load_unlocked(name, import_)
1177
1178        # Optimization: only call _bootstrap._lock_unlock_module() if
1179        # module.__spec__._initializing is True.
1180        # NOTE: because of this, initializing must be set *before*
1181        # putting the new module in sys.modules.
1182        _lock_unlock_module(name)
1183
1184    if module is None:
1185        message = ('import of {} halted; '
1186                   'None in sys.modules'.format(name))
1187        raise ModuleNotFoundError(message, name=name)
1188
1189    return module
1190
1191
1192def _gcd_import(name, package=None, level=0):
1193    """Import and return the module based on its name, the package the call is
1194    being made from, and the level adjustment.
1195
1196    This function represents the greatest common denominator of functionality
1197    between import_module and __import__. This includes setting __package__ if
1198    the loader did not.
1199
1200    """
1201    _sanity_check(name, package, level)
1202    if level > 0:
1203        name = _resolve_name(name, package, level)
1204    return _find_and_load(name, _gcd_import)
1205
1206
1207def _handle_fromlist(module, fromlist, import_, *, recursive=False):
1208    """Figure out what __import__ should return.
1209
1210    The import_ parameter is a callable which takes the name of module to
1211    import. It is required to decouple the function from assuming importlib's
1212    import implementation is desired.
1213
1214    """
1215    # The hell that is fromlist ...
1216    # If a package was imported, try to import stuff from fromlist.
1217    for x in fromlist:
1218        if not isinstance(x, str):
1219            if recursive:
1220                where = module.__name__ + '.__all__'
1221            else:
1222                where = "``from list''"
1223            raise TypeError(f"Item in {where} must be str, "
1224                            f"not {type(x).__name__}")
1225        elif x == '*':
1226            if not recursive and hasattr(module, '__all__'):
1227                _handle_fromlist(module, module.__all__, import_,
1228                                 recursive=True)
1229        elif not hasattr(module, x):
1230            from_name = '{}.{}'.format(module.__name__, x)
1231            try:
1232                _call_with_frames_removed(import_, from_name)
1233            except ModuleNotFoundError as exc:
1234                # Backwards-compatibility dictates we ignore failed
1235                # imports triggered by fromlist for modules that don't
1236                # exist.
1237                if (exc.name == from_name and
1238                    sys.modules.get(from_name, _NEEDS_LOADING) is not None):
1239                    continue
1240                raise
1241    return module
1242
1243
1244def _calc___package__(globals):
1245    """Calculate what __package__ should be.
1246
1247    __package__ is not guaranteed to be defined or could be set to None
1248    to represent that its proper value is unknown.
1249
1250    """
1251    package = globals.get('__package__')
1252    spec = globals.get('__spec__')
1253    if package is not None:
1254        if spec is not None and package != spec.parent:
1255            _warnings.warn("__package__ != __spec__.parent "
1256                           f"({package!r} != {spec.parent!r})",
1257                           ImportWarning, stacklevel=3)
1258        return package
1259    elif spec is not None:
1260        return spec.parent
1261    else:
1262        _warnings.warn("can't resolve package from __spec__ or __package__, "
1263                       "falling back on __name__ and __path__",
1264                       ImportWarning, stacklevel=3)
1265        package = globals['__name__']
1266        if '__path__' not in globals:
1267            package = package.rpartition('.')[0]
1268    return package
1269
1270
1271def __import__(name, globals=None, locals=None, fromlist=(), level=0):
1272    """Import a module.
1273
1274    The 'globals' argument is used to infer where the import is occurring from
1275    to handle relative imports. The 'locals' argument is ignored. The
1276    'fromlist' argument specifies what should exist as attributes on the module
1277    being imported (e.g. ``from module import <fromlist>``).  The 'level'
1278    argument represents the package location to import from in a relative
1279    import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
1280
1281    """
1282    if level == 0:
1283        module = _gcd_import(name)
1284    else:
1285        globals_ = globals if globals is not None else {}
1286        package = _calc___package__(globals_)
1287        module = _gcd_import(name, package, level)
1288    if not fromlist:
1289        # Return up to the first dot in 'name'. This is complicated by the fact
1290        # that 'name' may be relative.
1291        if level == 0:
1292            return _gcd_import(name.partition('.')[0])
1293        elif not name:
1294            return module
1295        else:
1296            # Figure out where to slice the module's name up to the first dot
1297            # in 'name'.
1298            cut_off = len(name) - len(name.partition('.')[0])
1299            # Slice end needs to be positive to alleviate need to special-case
1300            # when ``'.' not in name``.
1301            return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
1302    elif hasattr(module, '__path__'):
1303        return _handle_fromlist(module, fromlist, _gcd_import)
1304    else:
1305        return module
1306
1307
1308def _builtin_from_name(name):
1309    spec = BuiltinImporter.find_spec(name)
1310    if spec is None:
1311        raise ImportError('no built-in module named ' + name)
1312    return _load_unlocked(spec)
1313
1314
1315def _setup(sys_module, _imp_module):
1316    """Setup importlib by importing needed built-in modules and injecting them
1317    into the global namespace.
1318
1319    As sys is needed for sys.modules access and _imp is needed to load built-in
1320    modules, those two modules must be explicitly passed in.
1321
1322    """
1323    global _imp, sys
1324    _imp = _imp_module
1325    sys = sys_module
1326
1327    # Set up the spec for existing builtin/frozen modules.
1328    module_type = type(sys)
1329    for name, module in sys.modules.items():
1330        if isinstance(module, module_type):
1331            if name in sys.builtin_module_names:
1332                loader = BuiltinImporter
1333            elif _imp.is_frozen(name):
1334                loader = FrozenImporter
1335            else:
1336                continue
1337            spec = _spec_from_module(module, loader)
1338            _init_module_attrs(spec, module)
1339            if loader is FrozenImporter:
1340                loader._fix_up_module(module)
1341
1342    # Directly load built-in modules needed during bootstrap.
1343    self_module = sys.modules[__name__]
1344    for builtin_name in ('_thread', '_warnings', '_weakref'):
1345        if builtin_name not in sys.modules:
1346            builtin_module = _builtin_from_name(builtin_name)
1347        else:
1348            builtin_module = sys.modules[builtin_name]
1349        setattr(self_module, builtin_name, builtin_module)
1350
1351
1352def _install(sys_module, _imp_module):
1353    """Install importers for builtin and frozen modules"""
1354    _setup(sys_module, _imp_module)
1355
1356    sys.meta_path.append(BuiltinImporter)
1357    sys.meta_path.append(FrozenImporter)
1358
1359
1360def _install_external_importers():
1361    """Install importers that require external filesystem access"""
1362    global _bootstrap_external
1363    import _frozen_importlib_external
1364    _bootstrap_external = _frozen_importlib_external
1365    _frozen_importlib_external._install(sys.modules[__name__])
1366