• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 """Core implementation of import.
2 
3 This module is NOT meant to be directly imported! It has been designed such
4 that it can be bootstrapped into Python as the implementation of import. As
5 such it requires the injection of specific modules and attributes in order to
6 work. 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 
23 def _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 
40 def _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 
48 def _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 
61 class _DeadlockError(RuntimeError):
62     pass
63 
64 
65 class _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 
142 class _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 
163 class _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 
179 def _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 
216 def _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 ###############################################
233 def _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 
244 def _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 
252 def _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 
263 def _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.
275 def _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 
294 def _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 
320 class 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 
365         # file-location attributes
366         self._set_fileattr = False
367         self._cached = None
368 
369     def __repr__(self):
370         args = ['name={!r}'.format(self.name),
371                 'loader={!r}'.format(self.loader)]
372         if self.origin is not None:
373             args.append('origin={!r}'.format(self.origin))
374         if self.submodule_search_locations is not None:
375             args.append('submodule_search_locations={}'
376                         .format(self.submodule_search_locations))
377         return '{}({})'.format(self.__class__.__name__, ', '.join(args))
378 
379     def __eq__(self, other):
380         smsl = self.submodule_search_locations
381         try:
382             return (self.name == other.name and
383                     self.loader == other.loader and
384                     self.origin == other.origin and
385                     smsl == other.submodule_search_locations and
386                     self.cached == other.cached and
387                     self.has_location == other.has_location)
388         except AttributeError:
389             return NotImplemented
390 
391     @property
392     def cached(self):
393         if self._cached is None:
394             if self.origin is not None and self._set_fileattr:
395                 if _bootstrap_external is None:
396                     raise NotImplementedError
397                 self._cached = _bootstrap_external._get_cached(self.origin)
398         return self._cached
399 
400     @cached.setter
401     def cached(self, cached):
402         self._cached = cached
403 
404     @property
405     def parent(self):
406         """The name of the module's parent."""
407         if self.submodule_search_locations is None:
408             return self.name.rpartition('.')[0]
409         else:
410             return self.name
411 
412     @property
413     def has_location(self):
414         return self._set_fileattr
415 
416     @has_location.setter
417     def has_location(self, value):
418         self._set_fileattr = bool(value)
419 
420 
421 def spec_from_loader(name, loader, *, origin=None, is_package=None):
422     """Return a module spec based on various loader methods."""
423     if hasattr(loader, 'get_filename'):
424         if _bootstrap_external is None:
425             raise NotImplementedError
426         spec_from_file_location = _bootstrap_external.spec_from_file_location
427 
428         if is_package is None:
429             return spec_from_file_location(name, loader=loader)
430         search = [] if is_package else None
431         return spec_from_file_location(name, loader=loader,
432                                        submodule_search_locations=search)
433 
434     if is_package is None:
435         if hasattr(loader, 'is_package'):
436             try:
437                 is_package = loader.is_package(name)
438             except ImportError:
439                 is_package = None  # aka, undefined
440         else:
441             # the default
442             is_package = False
443 
444     return ModuleSpec(name, loader, origin=origin, is_package=is_package)
445 
446 
447 def _spec_from_module(module, loader=None, origin=None):
448     # This function is meant for use in _setup().
449     try:
450         spec = module.__spec__
451     except AttributeError:
452         pass
453     else:
454         if spec is not None:
455             return spec
456 
457     name = module.__name__
458     if loader is None:
459         try:
460             loader = module.__loader__
461         except AttributeError:
462             # loader will stay None.
463             pass
464     try:
465         location = module.__file__
466     except AttributeError:
467         location = None
468     if origin is None:
469         if location is None:
470             try:
471                 origin = loader._ORIGIN
472             except AttributeError:
473                 origin = None
474         else:
475             origin = location
476     try:
477         cached = module.__cached__
478     except AttributeError:
479         cached = None
480     try:
481         submodule_search_locations = list(module.__path__)
482     except AttributeError:
483         submodule_search_locations = None
484 
485     spec = ModuleSpec(name, loader, origin=origin)
486     spec._set_fileattr = False if location is None else True
487     spec.cached = cached
488     spec.submodule_search_locations = submodule_search_locations
489     return spec
490 
491 
492 def _init_module_attrs(spec, module, *, override=False):
493     # The passed-in module may be not support attribute assignment,
494     # in which case we simply don't set the attributes.
495     # __name__
496     if (override or getattr(module, '__name__', None) is None):
497         try:
498             module.__name__ = spec.name
499         except AttributeError:
500             pass
501     # __loader__
502     if override or getattr(module, '__loader__', None) is None:
503         loader = spec.loader
504         if loader is None:
505             # A backward compatibility hack.
506             if spec.submodule_search_locations is not None:
507                 if _bootstrap_external is None:
508                     raise NotImplementedError
509                 _NamespaceLoader = _bootstrap_external._NamespaceLoader
510 
511                 loader = _NamespaceLoader.__new__(_NamespaceLoader)
512                 loader._path = spec.submodule_search_locations
513                 spec.loader = loader
514                 # While the docs say that module.__file__ is not set for
515                 # built-in modules, and the code below will avoid setting it if
516                 # spec.has_location is false, this is incorrect for namespace
517                 # packages.  Namespace packages have no location, but their
518                 # __spec__.origin is None, and thus their module.__file__
519                 # should also be None for consistency.  While a bit of a hack,
520                 # this is the best place to ensure this consistency.
521                 #
522                 # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module
523                 # and bpo-32305
524                 module.__file__ = None
525         try:
526             module.__loader__ = loader
527         except AttributeError:
528             pass
529     # __package__
530     if override or getattr(module, '__package__', None) is None:
531         try:
532             module.__package__ = spec.parent
533         except AttributeError:
534             pass
535     # __spec__
536     try:
537         module.__spec__ = spec
538     except AttributeError:
539         pass
540     # __path__
541     if override or getattr(module, '__path__', None) is None:
542         if spec.submodule_search_locations is not None:
543             try:
544                 module.__path__ = spec.submodule_search_locations
545             except AttributeError:
546                 pass
547     # __file__/__cached__
548     if spec.has_location:
549         if override or getattr(module, '__file__', None) is None:
550             try:
551                 module.__file__ = spec.origin
552             except AttributeError:
553                 pass
554 
555         if override or getattr(module, '__cached__', None) is None:
556             if spec.cached is not None:
557                 try:
558                     module.__cached__ = spec.cached
559                 except AttributeError:
560                     pass
561     return module
562 
563 
564 def module_from_spec(spec):
565     """Create a module based on the provided spec."""
566     # Typically loaders will not implement create_module().
567     module = None
568     if hasattr(spec.loader, 'create_module'):
569         # If create_module() returns `None` then it means default
570         # module creation should be used.
571         module = spec.loader.create_module(spec)
572     elif hasattr(spec.loader, 'exec_module'):
573         raise ImportError('loaders that define exec_module() '
574                           'must also define create_module()')
575     if module is None:
576         module = _new_module(spec.name)
577     _init_module_attrs(spec, module)
578     return module
579 
580 
581 def _module_repr_from_spec(spec):
582     """Return the repr to use for the module."""
583     # We mostly replicate _module_repr() using the spec attributes.
584     name = '?' if spec.name is None else spec.name
585     if spec.origin is None:
586         if spec.loader is None:
587             return '<module {!r}>'.format(name)
588         else:
589             return '<module {!r} ({!r})>'.format(name, spec.loader)
590     else:
591         if spec.has_location:
592             return '<module {!r} from {!r}>'.format(name, spec.origin)
593         else:
594             return '<module {!r} ({})>'.format(spec.name, spec.origin)
595 
596 
597 # Used by importlib.reload() and _load_module_shim().
598 def _exec(spec, module):
599     """Execute the spec's specified module in an existing module's namespace."""
600     name = spec.name
601     with _ModuleLockManager(name):
602         if sys.modules.get(name) is not module:
603             msg = 'module {!r} not in sys.modules'.format(name)
604             raise ImportError(msg, name=name)
605         try:
606             if spec.loader is None:
607                 if spec.submodule_search_locations is None:
608                     raise ImportError('missing loader', name=spec.name)
609                 # Namespace package.
610                 _init_module_attrs(spec, module, override=True)
611             else:
612                 _init_module_attrs(spec, module, override=True)
613                 if not hasattr(spec.loader, 'exec_module'):
614                     msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
615                            "falling back to load_module()")
616                     _warnings.warn(msg, ImportWarning)
617                     spec.loader.load_module(name)
618                 else:
619                     spec.loader.exec_module(module)
620         finally:
621             # Update the order of insertion into sys.modules for module
622             # clean-up at shutdown.
623             module = sys.modules.pop(spec.name)
624             sys.modules[spec.name] = module
625     return module
626 
627 
628 def _load_backward_compatible(spec):
629     # It is assumed that all callers have been warned about using load_module()
630     # appropriately before calling this function.
631     try:
632         spec.loader.load_module(spec.name)
633     except:
634         if spec.name in sys.modules:
635             module = sys.modules.pop(spec.name)
636             sys.modules[spec.name] = module
637         raise
638     # The module must be in sys.modules at this point!
639     # Move it to the end of sys.modules.
640     module = sys.modules.pop(spec.name)
641     sys.modules[spec.name] = module
642     if getattr(module, '__loader__', None) is None:
643         try:
644             module.__loader__ = spec.loader
645         except AttributeError:
646             pass
647     if getattr(module, '__package__', None) is None:
648         try:
649             # Since module.__path__ may not line up with
650             # spec.submodule_search_paths, we can't necessarily rely
651             # on spec.parent here.
652             module.__package__ = module.__name__
653             if not hasattr(module, '__path__'):
654                 module.__package__ = spec.name.rpartition('.')[0]
655         except AttributeError:
656             pass
657     if getattr(module, '__spec__', None) is None:
658         try:
659             module.__spec__ = spec
660         except AttributeError:
661             pass
662     return module
663 
664 def _load_unlocked(spec):
665     # A helper for direct use by the import system.
666     if spec.loader is not None:
667         # Not a namespace package.
668         if not hasattr(spec.loader, 'exec_module'):
669             msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
670                     "falling back to load_module()")
671             _warnings.warn(msg, ImportWarning)
672             return _load_backward_compatible(spec)
673 
674     module = module_from_spec(spec)
675 
676     # This must be done before putting the module in sys.modules
677     # (otherwise an optimization shortcut in import.c becomes
678     # wrong).
679     spec._initializing = True
680     try:
681         sys.modules[spec.name] = module
682         try:
683             if spec.loader is None:
684                 if spec.submodule_search_locations is None:
685                     raise ImportError('missing loader', name=spec.name)
686                 # A namespace package so do nothing.
687             else:
688                 spec.loader.exec_module(module)
689         except:
690             try:
691                 del sys.modules[spec.name]
692             except KeyError:
693                 pass
694             raise
695         # Move the module to the end of sys.modules.
696         # We don't ensure that the import-related module attributes get
697         # set in the sys.modules replacement case.  Such modules are on
698         # their own.
699         module = sys.modules.pop(spec.name)
700         sys.modules[spec.name] = module
701         _verbose_message('import {!r} # {!r}', spec.name, spec.loader)
702     finally:
703         spec._initializing = False
704 
705     return module
706 
707 # A method used during testing of _load_unlocked() and by
708 # _load_module_shim().
709 def _load(spec):
710     """Return a new module object, loaded by the spec's loader.
711 
712     The module is not added to its parent.
713 
714     If a module is already in sys.modules, that existing module gets
715     clobbered.
716 
717     """
718     with _ModuleLockManager(spec.name):
719         return _load_unlocked(spec)
720 
721 
722 # Loaders #####################################################################
723 
724 class BuiltinImporter:
725 
726     """Meta path import for built-in modules.
727 
728     All methods are either class or static methods to avoid the need to
729     instantiate the class.
730 
731     """
732 
733     _ORIGIN = "built-in"
734 
735     @staticmethod
736     def module_repr(module):
737         """Return repr for the module.
738 
739         The method is deprecated.  The import machinery does the job itself.
740 
741         """
742         _warnings.warn("BuiltinImporter.module_repr() is deprecated and "
743                        "slated for removal in Python 3.12", DeprecationWarning)
744         return f'<module {module.__name__!r} ({BuiltinImporter._ORIGIN})>'
745 
746     @classmethod
747     def find_spec(cls, fullname, path=None, target=None):
748         if path is not None:
749             return 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 
804 class 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 find_spec(cls, fullname, path=None, target=None):
828         if _imp.is_frozen(fullname):
829             return spec_from_loader(fullname, cls, origin=cls._ORIGIN)
830         else:
831             return None
832 
833     @classmethod
834     def find_module(cls, fullname, path=None):
835         """Find a frozen module.
836 
837         This method is deprecated.  Use find_spec() instead.
838 
839         """
840         _warnings.warn("FrozenImporter.find_module() is deprecated and "
841                        "slated for removal in Python 3.12; use find_spec() instead",
842                        DeprecationWarning)
843         return cls if _imp.is_frozen(fullname) else None
844 
845     @staticmethod
846     def create_module(spec):
847         """Use default semantics for module creation."""
848 
849     @staticmethod
850     def exec_module(module):
851         name = module.__spec__.name
852         if not _imp.is_frozen(name):
853             raise ImportError('{!r} is not a frozen module'.format(name),
854                               name=name)
855         code = _call_with_frames_removed(_imp.get_frozen_object, name)
856         exec(code, module.__dict__)
857 
858     @classmethod
859     def load_module(cls, fullname):
860         """Load a frozen module.
861 
862         This method is deprecated.  Use exec_module() instead.
863 
864         """
865         # Warning about deprecation implemented in _load_module_shim().
866         return _load_module_shim(cls, fullname)
867 
868     @classmethod
869     @_requires_frozen
870     def get_code(cls, fullname):
871         """Return the code object for the frozen module."""
872         return _imp.get_frozen_object(fullname)
873 
874     @classmethod
875     @_requires_frozen
876     def get_source(cls, fullname):
877         """Return None as frozen modules do not have source code."""
878         return None
879 
880     @classmethod
881     @_requires_frozen
882     def is_package(cls, fullname):
883         """Return True if the frozen module is a package."""
884         return _imp.is_frozen_package(fullname)
885 
886 
887 # Import itself ###############################################################
888 
889 class _ImportLockContext:
890 
891     """Context manager for the import lock."""
892 
893     def __enter__(self):
894         """Acquire the import lock."""
895         _imp.acquire_lock()
896 
897     def __exit__(self, exc_type, exc_value, exc_traceback):
898         """Release the import lock regardless of any raised exceptions."""
899         _imp.release_lock()
900 
901 
902 def _resolve_name(name, package, level):
903     """Resolve a relative module name to an absolute one."""
904     bits = package.rsplit('.', level - 1)
905     if len(bits) < level:
906         raise ImportError('attempted relative import beyond top-level package')
907     base = bits[0]
908     return '{}.{}'.format(base, name) if name else base
909 
910 
911 def _find_spec_legacy(finder, name, path):
912     msg = (f"{_object_name(finder)}.find_spec() not found; "
913                            "falling back to find_module()")
914     _warnings.warn(msg, ImportWarning)
915     loader = finder.find_module(name, path)
916     if loader is None:
917         return None
918     return spec_from_loader(name, loader)
919 
920 
921 def _find_spec(name, path, target=None):
922     """Find a module's spec."""
923     meta_path = sys.meta_path
924     if meta_path is None:
925         # PyImport_Cleanup() is running or has been called.
926         raise ImportError("sys.meta_path is None, Python is likely "
927                           "shutting down")
928 
929     if not meta_path:
930         _warnings.warn('sys.meta_path is empty', ImportWarning)
931 
932     # We check sys.modules here for the reload case.  While a passed-in
933     # target will usually indicate a reload there is no guarantee, whereas
934     # sys.modules provides one.
935     is_reload = name in sys.modules
936     for finder in meta_path:
937         with _ImportLockContext():
938             try:
939                 find_spec = finder.find_spec
940             except AttributeError:
941                 spec = _find_spec_legacy(finder, name, path)
942                 if spec is None:
943                     continue
944             else:
945                 spec = find_spec(name, path, target)
946         if spec is not None:
947             # The parent import may have already imported this module.
948             if not is_reload and name in sys.modules:
949                 module = sys.modules[name]
950                 try:
951                     __spec__ = module.__spec__
952                 except AttributeError:
953                     # We use the found spec since that is the one that
954                     # we would have used if the parent module hadn't
955                     # beaten us to the punch.
956                     return spec
957                 else:
958                     if __spec__ is None:
959                         return spec
960                     else:
961                         return __spec__
962             else:
963                 return spec
964     else:
965         return None
966 
967 
968 def _sanity_check(name, package, level):
969     """Verify arguments are "sane"."""
970     if not isinstance(name, str):
971         raise TypeError('module name must be str, not {}'.format(type(name)))
972     if level < 0:
973         raise ValueError('level must be >= 0')
974     if level > 0:
975         if not isinstance(package, str):
976             raise TypeError('__package__ not set to a string')
977         elif not package:
978             raise ImportError('attempted relative import with no known parent '
979                               'package')
980     if not name and level == 0:
981         raise ValueError('Empty module name')
982 
983 
984 _ERR_MSG_PREFIX = 'No module named '
985 _ERR_MSG = _ERR_MSG_PREFIX + '{!r}'
986 
987 def _find_and_load_unlocked(name, import_):
988     path = None
989     parent = name.rpartition('.')[0]
990     if parent:
991         if parent not in sys.modules:
992             _call_with_frames_removed(import_, parent)
993         # Crazy side-effects!
994         if name in sys.modules:
995             return sys.modules[name]
996         parent_module = sys.modules[parent]
997         try:
998             path = parent_module.__path__
999         except AttributeError:
1000             msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent)
1001             raise ModuleNotFoundError(msg, name=name) from None
1002     spec = _find_spec(name, path)
1003     if spec is None:
1004         raise ModuleNotFoundError(_ERR_MSG.format(name), name=name)
1005     else:
1006         module = _load_unlocked(spec)
1007     if parent:
1008         # Set the module as an attribute on its parent.
1009         parent_module = sys.modules[parent]
1010         child = name.rpartition('.')[2]
1011         try:
1012             setattr(parent_module, child, module)
1013         except AttributeError:
1014             msg = f"Cannot set an attribute on {parent!r} for child module {child!r}"
1015             _warnings.warn(msg, ImportWarning)
1016     return module
1017 
1018 
1019 _NEEDS_LOADING = object()
1020 
1021 
1022 def _find_and_load(name, import_):
1023     """Find and load the module."""
1024     with _ModuleLockManager(name):
1025         module = sys.modules.get(name, _NEEDS_LOADING)
1026         if module is _NEEDS_LOADING:
1027             return _find_and_load_unlocked(name, import_)
1028 
1029     if module is None:
1030         message = ('import of {} halted; '
1031                    'None in sys.modules'.format(name))
1032         raise ModuleNotFoundError(message, name=name)
1033 
1034     _lock_unlock_module(name)
1035     return module
1036 
1037 
1038 def _gcd_import(name, package=None, level=0):
1039     """Import and return the module based on its name, the package the call is
1040     being made from, and the level adjustment.
1041 
1042     This function represents the greatest common denominator of functionality
1043     between import_module and __import__. This includes setting __package__ if
1044     the loader did not.
1045 
1046     """
1047     _sanity_check(name, package, level)
1048     if level > 0:
1049         name = _resolve_name(name, package, level)
1050     return _find_and_load(name, _gcd_import)
1051 
1052 
1053 def _handle_fromlist(module, fromlist, import_, *, recursive=False):
1054     """Figure out what __import__ should return.
1055 
1056     The import_ parameter is a callable which takes the name of module to
1057     import. It is required to decouple the function from assuming importlib's
1058     import implementation is desired.
1059 
1060     """
1061     # The hell that is fromlist ...
1062     # If a package was imported, try to import stuff from fromlist.
1063     for x in fromlist:
1064         if not isinstance(x, str):
1065             if recursive:
1066                 where = module.__name__ + '.__all__'
1067             else:
1068                 where = "``from list''"
1069             raise TypeError(f"Item in {where} must be str, "
1070                             f"not {type(x).__name__}")
1071         elif x == '*':
1072             if not recursive and hasattr(module, '__all__'):
1073                 _handle_fromlist(module, module.__all__, import_,
1074                                  recursive=True)
1075         elif not hasattr(module, x):
1076             from_name = '{}.{}'.format(module.__name__, x)
1077             try:
1078                 _call_with_frames_removed(import_, from_name)
1079             except ModuleNotFoundError as exc:
1080                 # Backwards-compatibility dictates we ignore failed
1081                 # imports triggered by fromlist for modules that don't
1082                 # exist.
1083                 if (exc.name == from_name and
1084                     sys.modules.get(from_name, _NEEDS_LOADING) is not None):
1085                     continue
1086                 raise
1087     return module
1088 
1089 
1090 def _calc___package__(globals):
1091     """Calculate what __package__ should be.
1092 
1093     __package__ is not guaranteed to be defined or could be set to None
1094     to represent that its proper value is unknown.
1095 
1096     """
1097     package = globals.get('__package__')
1098     spec = globals.get('__spec__')
1099     if package is not None:
1100         if spec is not None and package != spec.parent:
1101             _warnings.warn("__package__ != __spec__.parent "
1102                            f"({package!r} != {spec.parent!r})",
1103                            ImportWarning, stacklevel=3)
1104         return package
1105     elif spec is not None:
1106         return spec.parent
1107     else:
1108         _warnings.warn("can't resolve package from __spec__ or __package__, "
1109                        "falling back on __name__ and __path__",
1110                        ImportWarning, stacklevel=3)
1111         package = globals['__name__']
1112         if '__path__' not in globals:
1113             package = package.rpartition('.')[0]
1114     return package
1115 
1116 
1117 def __import__(name, globals=None, locals=None, fromlist=(), level=0):
1118     """Import a module.
1119 
1120     The 'globals' argument is used to infer where the import is occurring from
1121     to handle relative imports. The 'locals' argument is ignored. The
1122     'fromlist' argument specifies what should exist as attributes on the module
1123     being imported (e.g. ``from module import <fromlist>``).  The 'level'
1124     argument represents the package location to import from in a relative
1125     import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
1126 
1127     """
1128     if level == 0:
1129         module = _gcd_import(name)
1130     else:
1131         globals_ = globals if globals is not None else {}
1132         package = _calc___package__(globals_)
1133         module = _gcd_import(name, package, level)
1134     if not fromlist:
1135         # Return up to the first dot in 'name'. This is complicated by the fact
1136         # that 'name' may be relative.
1137         if level == 0:
1138             return _gcd_import(name.partition('.')[0])
1139         elif not name:
1140             return module
1141         else:
1142             # Figure out where to slice the module's name up to the first dot
1143             # in 'name'.
1144             cut_off = len(name) - len(name.partition('.')[0])
1145             # Slice end needs to be positive to alleviate need to special-case
1146             # when ``'.' not in name``.
1147             return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
1148     elif hasattr(module, '__path__'):
1149         return _handle_fromlist(module, fromlist, _gcd_import)
1150     else:
1151         return module
1152 
1153 
1154 def _builtin_from_name(name):
1155     spec = BuiltinImporter.find_spec(name)
1156     if spec is None:
1157         raise ImportError('no built-in module named ' + name)
1158     return _load_unlocked(spec)
1159 
1160 
1161 def _setup(sys_module, _imp_module):
1162     """Setup importlib by importing needed built-in modules and injecting them
1163     into the global namespace.
1164 
1165     As sys is needed for sys.modules access and _imp is needed to load built-in
1166     modules, those two modules must be explicitly passed in.
1167 
1168     """
1169     global _imp, sys
1170     _imp = _imp_module
1171     sys = sys_module
1172 
1173     # Set up the spec for existing builtin/frozen modules.
1174     module_type = type(sys)
1175     for name, module in sys.modules.items():
1176         if isinstance(module, module_type):
1177             if name in sys.builtin_module_names:
1178                 loader = BuiltinImporter
1179             elif _imp.is_frozen(name):
1180                 loader = FrozenImporter
1181             else:
1182                 continue
1183             spec = _spec_from_module(module, loader)
1184             _init_module_attrs(spec, module)
1185 
1186     # Directly load built-in modules needed during bootstrap.
1187     self_module = sys.modules[__name__]
1188     for builtin_name in ('_thread', '_warnings', '_weakref'):
1189         if builtin_name not in sys.modules:
1190             builtin_module = _builtin_from_name(builtin_name)
1191         else:
1192             builtin_module = sys.modules[builtin_name]
1193         setattr(self_module, builtin_name, builtin_module)
1194 
1195 
1196 def _install(sys_module, _imp_module):
1197     """Install importers for builtin and frozen modules"""
1198     _setup(sys_module, _imp_module)
1199 
1200     sys.meta_path.append(BuiltinImporter)
1201     sys.meta_path.append(FrozenImporter)
1202 
1203 
1204 def _install_external_importers():
1205     """Install importers that require external filesystem access"""
1206     global _bootstrap_external
1207     import _frozen_importlib_external
1208     _bootstrap_external = _frozen_importlib_external
1209     _frozen_importlib_external._install(sys.modules[__name__])
1210