• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# For a list that can have a weakref to it.
55class _List(list):
56    __slots__ = ("__weakref__",)
57
58
59# Copied from weakref.py with some simplifications and modifications unique to
60# bootstrapping importlib. Many methods were simply deleting for simplicity, so if they
61# are needed in the future they may work if simply copied back in.
62class _WeakValueDictionary:
63
64    def __init__(self):
65        self_weakref = _weakref.ref(self)
66
67        # Inlined to avoid issues with inheriting from _weakref.ref before _weakref is
68        # set by _setup(). Since there's only one instance of this class, this is
69        # not expensive.
70        class KeyedRef(_weakref.ref):
71
72            __slots__ = "key",
73
74            def __new__(type, ob, key):
75                self = super().__new__(type, ob, type.remove)
76                self.key = key
77                return self
78
79            def __init__(self, ob, key):
80                super().__init__(ob, self.remove)
81
82            @staticmethod
83            def remove(wr):
84                nonlocal self_weakref
85
86                self = self_weakref()
87                if self is not None:
88                    if self._iterating:
89                        self._pending_removals.append(wr.key)
90                    else:
91                        _weakref._remove_dead_weakref(self.data, wr.key)
92
93        self._KeyedRef = KeyedRef
94        self.clear()
95
96    def clear(self):
97        self._pending_removals = []
98        self._iterating = set()
99        self.data = {}
100
101    def _commit_removals(self):
102        pop = self._pending_removals.pop
103        d = self.data
104        while True:
105            try:
106                key = pop()
107            except IndexError:
108                return
109            _weakref._remove_dead_weakref(d, key)
110
111    def get(self, key, default=None):
112        if self._pending_removals:
113            self._commit_removals()
114        try:
115            wr = self.data[key]
116        except KeyError:
117            return default
118        else:
119            if (o := wr()) is None:
120                return default
121            else:
122                return o
123
124    def setdefault(self, key, default=None):
125        try:
126            o = self.data[key]()
127        except KeyError:
128            o = None
129        if o is None:
130            if self._pending_removals:
131                self._commit_removals()
132            self.data[key] = self._KeyedRef(default, key)
133            return default
134        else:
135            return o
136
137
138# A dict mapping module names to weakrefs of _ModuleLock instances.
139# Dictionary protected by the global import lock.
140_module_locks = {}
141
142# A dict mapping thread IDs to weakref'ed lists of _ModuleLock instances.
143# This maps a thread to the module locks it is blocking on acquiring.  The
144# values are lists because a single thread could perform a re-entrant import
145# and be "in the process" of blocking on locks for more than one module.  A
146# thread can be "in the process" because a thread cannot actually block on
147# acquiring more than one lock but it can have set up bookkeeping that reflects
148# that it intends to block on acquiring more than one lock.
149#
150# The dictionary uses a WeakValueDictionary to avoid keeping unnecessary
151# lists around, regardless of GC runs. This way there's no memory leak if
152# the list is no longer needed (GH-106176).
153_blocking_on = None
154
155
156class _BlockingOnManager:
157    """A context manager responsible to updating ``_blocking_on``."""
158    def __init__(self, thread_id, lock):
159        self.thread_id = thread_id
160        self.lock = lock
161
162    def __enter__(self):
163        """Mark the running thread as waiting for self.lock. via _blocking_on."""
164        # Interactions with _blocking_on are *not* protected by the global
165        # import lock here because each thread only touches the state that it
166        # owns (state keyed on its thread id).  The global import lock is
167        # re-entrant (i.e., a single thread may take it more than once) so it
168        # wouldn't help us be correct in the face of re-entrancy either.
169
170        self.blocked_on = _blocking_on.setdefault(self.thread_id, _List())
171        self.blocked_on.append(self.lock)
172
173    def __exit__(self, *args, **kwargs):
174        """Remove self.lock from this thread's _blocking_on list."""
175        self.blocked_on.remove(self.lock)
176
177
178class _DeadlockError(RuntimeError):
179    pass
180
181
182
183def _has_deadlocked(target_id, *, seen_ids, candidate_ids, blocking_on):
184    """Check if 'target_id' is holding the same lock as another thread(s).
185
186    The search within 'blocking_on' starts with the threads listed in
187    'candidate_ids'.  'seen_ids' contains any threads that are considered
188    already traversed in the search.
189
190    Keyword arguments:
191    target_id     -- The thread id to try to reach.
192    seen_ids      -- A set of threads that have already been visited.
193    candidate_ids -- The thread ids from which to begin.
194    blocking_on   -- A dict representing the thread/blocking-on graph.  This may
195                     be the same object as the global '_blocking_on' but it is
196                     a parameter to reduce the impact that global mutable
197                     state has on the result of this function.
198    """
199    if target_id in candidate_ids:
200        # If we have already reached the target_id, we're done - signal that it
201        # is reachable.
202        return True
203
204    # Otherwise, try to reach the target_id from each of the given candidate_ids.
205    for tid in candidate_ids:
206        if not (candidate_blocking_on := blocking_on.get(tid)):
207            # There are no edges out from this node, skip it.
208            continue
209        elif tid in seen_ids:
210            # bpo 38091: the chain of tid's we encounter here eventually leads
211            # to a fixed point or a cycle, but does not reach target_id.
212            # This means we would not actually deadlock.  This can happen if
213            # other threads are at the beginning of acquire() below.
214            return False
215        seen_ids.add(tid)
216
217        # Follow the edges out from this thread.
218        edges = [lock.owner for lock in candidate_blocking_on]
219        if _has_deadlocked(target_id, seen_ids=seen_ids, candidate_ids=edges,
220                blocking_on=blocking_on):
221            return True
222
223    return False
224
225
226class _ModuleLock:
227    """A recursive lock implementation which is able to detect deadlocks
228    (e.g. thread 1 trying to take locks A then B, and thread 2 trying to
229    take locks B then A).
230    """
231
232    def __init__(self, name):
233        # Create an RLock for protecting the import process for the
234        # corresponding module.  Since it is an RLock, a single thread will be
235        # able to take it more than once.  This is necessary to support
236        # re-entrancy in the import system that arises from (at least) signal
237        # handlers and the garbage collector.  Consider the case of:
238        #
239        #  import foo
240        #  -> ...
241        #     -> importlib._bootstrap._ModuleLock.acquire
242        #        -> ...
243        #           -> <garbage collector>
244        #              -> __del__
245        #                 -> import foo
246        #                    -> ...
247        #                       -> importlib._bootstrap._ModuleLock.acquire
248        #                          -> _BlockingOnManager.__enter__
249        #
250        # If a different thread than the running one holds the lock then the
251        # thread will have to block on taking the lock, which is what we want
252        # for thread safety.
253        self.lock = _thread.RLock()
254        self.wakeup = _thread.allocate_lock()
255
256        # The name of the module for which this is a lock.
257        self.name = name
258
259        # Can end up being set to None if this lock is not owned by any thread
260        # or the thread identifier for the owning thread.
261        self.owner = None
262
263        # Represent the number of times the owning thread has acquired this lock
264        # via a list of True.  This supports RLock-like ("re-entrant lock")
265        # behavior, necessary in case a single thread is following a circular
266        # import dependency and needs to take the lock for a single module
267        # more than once.
268        #
269        # Counts are represented as a list of True because list.append(True)
270        # and list.pop() are both atomic and thread-safe in CPython and it's hard
271        # to find another primitive with the same properties.
272        self.count = []
273
274        # This is a count of the number of threads that are blocking on
275        # self.wakeup.acquire() awaiting to get their turn holding this module
276        # lock.  When the module lock is released, if this is greater than
277        # zero, it is decremented and `self.wakeup` is released one time.  The
278        # intent is that this will let one other thread make more progress on
279        # acquiring this module lock.  This repeats until all the threads have
280        # gotten a turn.
281        #
282        # This is incremented in self.acquire() when a thread notices it is
283        # going to have to wait for another thread to finish.
284        #
285        # See the comment above count for explanation of the representation.
286        self.waiters = []
287
288    def has_deadlock(self):
289        # To avoid deadlocks for concurrent or re-entrant circular imports,
290        # look at _blocking_on to see if any threads are blocking
291        # on getting the import lock for any module for which the import lock
292        # is held by this thread.
293        return _has_deadlocked(
294            # Try to find this thread.
295            target_id=_thread.get_ident(),
296            seen_ids=set(),
297            # Start from the thread that holds the import lock for this
298            # module.
299            candidate_ids=[self.owner],
300            # Use the global "blocking on" state.
301            blocking_on=_blocking_on,
302        )
303
304    def acquire(self):
305        """
306        Acquire the module lock.  If a potential deadlock is detected,
307        a _DeadlockError is raised.
308        Otherwise, the lock is always acquired and True is returned.
309        """
310        tid = _thread.get_ident()
311        with _BlockingOnManager(tid, self):
312            while True:
313                # Protect interaction with state on self with a per-module
314                # lock.  This makes it safe for more than one thread to try to
315                # acquire the lock for a single module at the same time.
316                with self.lock:
317                    if self.count == [] or self.owner == tid:
318                        # If the lock for this module is unowned then we can
319                        # take the lock immediately and succeed.  If the lock
320                        # for this module is owned by the running thread then
321                        # we can also allow the acquire to succeed.  This
322                        # supports circular imports (thread T imports module A
323                        # which imports module B which imports module A).
324                        self.owner = tid
325                        self.count.append(True)
326                        return True
327
328                    # At this point we know the lock is held (because count !=
329                    # 0) by another thread (because owner != tid).  We'll have
330                    # to get in line to take the module lock.
331
332                    # But first, check to see if this thread would create a
333                    # deadlock by acquiring this module lock.  If it would
334                    # then just stop with an error.
335                    #
336                    # It's not clear who is expected to handle this error.
337                    # There is one handler in _lock_unlock_module but many
338                    # times this method is called when entering the context
339                    # manager _ModuleLockManager instead - so _DeadlockError
340                    # will just propagate up to application code.
341                    #
342                    # This seems to be more than just a hypothetical -
343                    # https://stackoverflow.com/questions/59509154
344                    # https://github.com/encode/django-rest-framework/issues/7078
345                    if self.has_deadlock():
346                        raise _DeadlockError(f'deadlock detected by {self!r}')
347
348                    # Check to see if we're going to be able to acquire the
349                    # lock.  If we are going to have to wait then increment
350                    # the waiters so `self.release` will know to unblock us
351                    # later on.  We do this part non-blockingly so we don't
352                    # get stuck here before we increment waiters.  We have
353                    # this extra acquire call (in addition to the one below,
354                    # outside the self.lock context manager) to make sure
355                    # self.wakeup is held when the next acquire is called (so
356                    # we block).  This is probably needlessly complex and we
357                    # should just take self.wakeup in the return codepath
358                    # above.
359                    if self.wakeup.acquire(False):
360                        self.waiters.append(None)
361
362                # Now take the lock in a blocking fashion.  This won't
363                # complete until the thread holding this lock
364                # (self.owner) calls self.release.
365                self.wakeup.acquire()
366
367                # Taking the lock has served its purpose (making us wait), so we can
368                # give it up now.  We'll take it w/o blocking again on the
369                # next iteration around this 'while' loop.
370                self.wakeup.release()
371
372    def release(self):
373        tid = _thread.get_ident()
374        with self.lock:
375            if self.owner != tid:
376                raise RuntimeError('cannot release un-acquired lock')
377            assert len(self.count) > 0
378            self.count.pop()
379            if not len(self.count):
380                self.owner = None
381                if len(self.waiters) > 0:
382                    self.waiters.pop()
383                    self.wakeup.release()
384
385    def __repr__(self):
386        return f'_ModuleLock({self.name!r}) at {id(self)}'
387
388
389class _DummyModuleLock:
390    """A simple _ModuleLock equivalent for Python builds without
391    multi-threading support."""
392
393    def __init__(self, name):
394        self.name = name
395        self.count = 0
396
397    def acquire(self):
398        self.count += 1
399        return True
400
401    def release(self):
402        if self.count == 0:
403            raise RuntimeError('cannot release un-acquired lock')
404        self.count -= 1
405
406    def __repr__(self):
407        return f'_DummyModuleLock({self.name!r}) at {id(self)}'
408
409
410class _ModuleLockManager:
411
412    def __init__(self, name):
413        self._name = name
414        self._lock = None
415
416    def __enter__(self):
417        self._lock = _get_module_lock(self._name)
418        self._lock.acquire()
419
420    def __exit__(self, *args, **kwargs):
421        self._lock.release()
422
423
424# The following two functions are for consumption by Python/import.c.
425
426def _get_module_lock(name):
427    """Get or create the module lock for a given module name.
428
429    Acquire/release internally the global import lock to protect
430    _module_locks."""
431
432    _imp.acquire_lock()
433    try:
434        try:
435            lock = _module_locks[name]()
436        except KeyError:
437            lock = None
438
439        if lock is None:
440            if _thread is None:
441                lock = _DummyModuleLock(name)
442            else:
443                lock = _ModuleLock(name)
444
445            def cb(ref, name=name):
446                _imp.acquire_lock()
447                try:
448                    # bpo-31070: Check if another thread created a new lock
449                    # after the previous lock was destroyed
450                    # but before the weakref callback was called.
451                    if _module_locks.get(name) is ref:
452                        del _module_locks[name]
453                finally:
454                    _imp.release_lock()
455
456            _module_locks[name] = _weakref.ref(lock, cb)
457    finally:
458        _imp.release_lock()
459
460    return lock
461
462
463def _lock_unlock_module(name):
464    """Acquires then releases the module lock for a given module name.
465
466    This is used to ensure a module is completely initialized, in the
467    event it is being imported by another thread.
468    """
469    lock = _get_module_lock(name)
470    try:
471        lock.acquire()
472    except _DeadlockError:
473        # Concurrent circular import, we'll accept a partially initialized
474        # module object.
475        pass
476    else:
477        lock.release()
478
479# Frame stripping magic ###############################################
480def _call_with_frames_removed(f, *args, **kwds):
481    """remove_importlib_frames in import.c will always remove sequences
482    of importlib frames that end with a call to this function
483
484    Use it instead of a normal call in places where including the importlib
485    frames introduces unwanted noise into the traceback (e.g. when executing
486    module code)
487    """
488    return f(*args, **kwds)
489
490
491def _verbose_message(message, *args, verbosity=1):
492    """Print the message to stderr if -v/PYTHONVERBOSE is turned on."""
493    if sys.flags.verbose >= verbosity:
494        if not message.startswith(('#', 'import ')):
495            message = '# ' + message
496        print(message.format(*args), file=sys.stderr)
497
498
499def _requires_builtin(fxn):
500    """Decorator to verify the named module is built-in."""
501    def _requires_builtin_wrapper(self, fullname):
502        if fullname not in sys.builtin_module_names:
503            raise ImportError(f'{fullname!r} is not a built-in module',
504                              name=fullname)
505        return fxn(self, fullname)
506    _wrap(_requires_builtin_wrapper, fxn)
507    return _requires_builtin_wrapper
508
509
510def _requires_frozen(fxn):
511    """Decorator to verify the named module is frozen."""
512    def _requires_frozen_wrapper(self, fullname):
513        if not _imp.is_frozen(fullname):
514            raise ImportError(f'{fullname!r} is not a frozen module',
515                              name=fullname)
516        return fxn(self, fullname)
517    _wrap(_requires_frozen_wrapper, fxn)
518    return _requires_frozen_wrapper
519
520
521# Typically used by loader classes as a method replacement.
522def _load_module_shim(self, fullname):
523    """Load the specified module into sys.modules and return it.
524
525    This method is deprecated.  Use loader.exec_module() instead.
526
527    """
528    msg = ("the load_module() method is deprecated and slated for removal in "
529          "Python 3.12; use exec_module() instead")
530    _warnings.warn(msg, DeprecationWarning)
531    spec = spec_from_loader(fullname, self)
532    if fullname in sys.modules:
533        module = sys.modules[fullname]
534        _exec(spec, module)
535        return sys.modules[fullname]
536    else:
537        return _load(spec)
538
539# Module specifications #######################################################
540
541def _module_repr(module):
542    """The implementation of ModuleType.__repr__()."""
543    loader = getattr(module, '__loader__', None)
544    if spec := getattr(module, "__spec__", None):
545        return _module_repr_from_spec(spec)
546    # Fall through to a catch-all which always succeeds.
547    try:
548        name = module.__name__
549    except AttributeError:
550        name = '?'
551    try:
552        filename = module.__file__
553    except AttributeError:
554        if loader is None:
555            return f'<module {name!r}>'
556        else:
557            return f'<module {name!r} ({loader!r})>'
558    else:
559        return f'<module {name!r} from {filename!r}>'
560
561
562class ModuleSpec:
563    """The specification for a module, used for loading.
564
565    A module's spec is the source for information about the module.  For
566    data associated with the module, including source, use the spec's
567    loader.
568
569    `name` is the absolute name of the module.  `loader` is the loader
570    to use when loading the module.  `parent` is the name of the
571    package the module is in.  The parent is derived from the name.
572
573    `is_package` determines if the module is considered a package or
574    not.  On modules this is reflected by the `__path__` attribute.
575
576    `origin` is the specific location used by the loader from which to
577    load the module, if that information is available.  When filename is
578    set, origin will match.
579
580    `has_location` indicates that a spec's "origin" reflects a location.
581    When this is True, `__file__` attribute of the module is set.
582
583    `cached` is the location of the cached bytecode file, if any.  It
584    corresponds to the `__cached__` attribute.
585
586    `submodule_search_locations` is the sequence of path entries to
587    search when importing submodules.  If set, is_package should be
588    True--and False otherwise.
589
590    Packages are simply modules that (may) have submodules.  If a spec
591    has a non-None value in `submodule_search_locations`, the import
592    system will consider modules loaded from the spec as packages.
593
594    Only finders (see importlib.abc.MetaPathFinder and
595    importlib.abc.PathEntryFinder) should modify ModuleSpec instances.
596
597    """
598
599    def __init__(self, name, loader, *, origin=None, loader_state=None,
600                 is_package=None):
601        self.name = name
602        self.loader = loader
603        self.origin = origin
604        self.loader_state = loader_state
605        self.submodule_search_locations = [] if is_package else None
606        self._uninitialized_submodules = []
607
608        # file-location attributes
609        self._set_fileattr = False
610        self._cached = None
611
612    def __repr__(self):
613        args = [f'name={self.name!r}', f'loader={self.loader!r}']
614        if self.origin is not None:
615            args.append(f'origin={self.origin!r}')
616        if self.submodule_search_locations is not None:
617            args.append(f'submodule_search_locations={self.submodule_search_locations}')
618        return f'{self.__class__.__name__}({", ".join(args)})'
619
620    def __eq__(self, other):
621        smsl = self.submodule_search_locations
622        try:
623            return (self.name == other.name and
624                    self.loader == other.loader and
625                    self.origin == other.origin and
626                    smsl == other.submodule_search_locations and
627                    self.cached == other.cached and
628                    self.has_location == other.has_location)
629        except AttributeError:
630            return NotImplemented
631
632    @property
633    def cached(self):
634        if self._cached is None:
635            if self.origin is not None and self._set_fileattr:
636                if _bootstrap_external is None:
637                    raise NotImplementedError
638                self._cached = _bootstrap_external._get_cached(self.origin)
639        return self._cached
640
641    @cached.setter
642    def cached(self, cached):
643        self._cached = cached
644
645    @property
646    def parent(self):
647        """The name of the module's parent."""
648        if self.submodule_search_locations is None:
649            return self.name.rpartition('.')[0]
650        else:
651            return self.name
652
653    @property
654    def has_location(self):
655        return self._set_fileattr
656
657    @has_location.setter
658    def has_location(self, value):
659        self._set_fileattr = bool(value)
660
661
662def spec_from_loader(name, loader, *, origin=None, is_package=None):
663    """Return a module spec based on various loader methods."""
664    if origin is None:
665        origin = getattr(loader, '_ORIGIN', None)
666
667    if not origin and hasattr(loader, 'get_filename'):
668        if _bootstrap_external is None:
669            raise NotImplementedError
670        spec_from_file_location = _bootstrap_external.spec_from_file_location
671
672        if is_package is None:
673            return spec_from_file_location(name, loader=loader)
674        search = [] if is_package else None
675        return spec_from_file_location(name, loader=loader,
676                                       submodule_search_locations=search)
677
678    if is_package is None:
679        if hasattr(loader, 'is_package'):
680            try:
681                is_package = loader.is_package(name)
682            except ImportError:
683                is_package = None  # aka, undefined
684        else:
685            # the default
686            is_package = False
687
688    return ModuleSpec(name, loader, origin=origin, is_package=is_package)
689
690
691def _spec_from_module(module, loader=None, origin=None):
692    # This function is meant for use in _setup().
693    try:
694        spec = module.__spec__
695    except AttributeError:
696        pass
697    else:
698        if spec is not None:
699            return spec
700
701    name = module.__name__
702    if loader is None:
703        try:
704            loader = module.__loader__
705        except AttributeError:
706            # loader will stay None.
707            pass
708    try:
709        location = module.__file__
710    except AttributeError:
711        location = None
712    if origin is None:
713        if loader is not None:
714            origin = getattr(loader, '_ORIGIN', None)
715        if not origin and location is not None:
716            origin = location
717    try:
718        cached = module.__cached__
719    except AttributeError:
720        cached = None
721    try:
722        submodule_search_locations = list(module.__path__)
723    except AttributeError:
724        submodule_search_locations = None
725
726    spec = ModuleSpec(name, loader, origin=origin)
727    spec._set_fileattr = False if location is None else (origin == location)
728    spec.cached = cached
729    spec.submodule_search_locations = submodule_search_locations
730    return spec
731
732
733def _init_module_attrs(spec, module, *, override=False):
734    # The passed-in module may be not support attribute assignment,
735    # in which case we simply don't set the attributes.
736    # __name__
737    if (override or getattr(module, '__name__', None) is None):
738        try:
739            module.__name__ = spec.name
740        except AttributeError:
741            pass
742    # __loader__
743    if override or getattr(module, '__loader__', None) is None:
744        loader = spec.loader
745        if loader is None:
746            # A backward compatibility hack.
747            if spec.submodule_search_locations is not None:
748                if _bootstrap_external is None:
749                    raise NotImplementedError
750                NamespaceLoader = _bootstrap_external.NamespaceLoader
751
752                loader = NamespaceLoader.__new__(NamespaceLoader)
753                loader._path = spec.submodule_search_locations
754                spec.loader = loader
755                # While the docs say that module.__file__ is not set for
756                # built-in modules, and the code below will avoid setting it if
757                # spec.has_location is false, this is incorrect for namespace
758                # packages.  Namespace packages have no location, but their
759                # __spec__.origin is None, and thus their module.__file__
760                # should also be None for consistency.  While a bit of a hack,
761                # this is the best place to ensure this consistency.
762                #
763                # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module
764                # and bpo-32305
765                module.__file__ = None
766        try:
767            module.__loader__ = loader
768        except AttributeError:
769            pass
770    # __package__
771    if override or getattr(module, '__package__', None) is None:
772        try:
773            module.__package__ = spec.parent
774        except AttributeError:
775            pass
776    # __spec__
777    try:
778        module.__spec__ = spec
779    except AttributeError:
780        pass
781    # __path__
782    if override or getattr(module, '__path__', None) is None:
783        if spec.submodule_search_locations is not None:
784            # XXX We should extend __path__ if it's already a list.
785            try:
786                module.__path__ = spec.submodule_search_locations
787            except AttributeError:
788                pass
789    # __file__/__cached__
790    if spec.has_location:
791        if override or getattr(module, '__file__', None) is None:
792            try:
793                module.__file__ = spec.origin
794            except AttributeError:
795                pass
796
797        if override or getattr(module, '__cached__', None) is None:
798            if spec.cached is not None:
799                try:
800                    module.__cached__ = spec.cached
801                except AttributeError:
802                    pass
803    return module
804
805
806def module_from_spec(spec):
807    """Create a module based on the provided spec."""
808    # Typically loaders will not implement create_module().
809    module = None
810    if hasattr(spec.loader, 'create_module'):
811        # If create_module() returns `None` then it means default
812        # module creation should be used.
813        module = spec.loader.create_module(spec)
814    elif hasattr(spec.loader, 'exec_module'):
815        raise ImportError('loaders that define exec_module() '
816                          'must also define create_module()')
817    if module is None:
818        module = _new_module(spec.name)
819    _init_module_attrs(spec, module)
820    return module
821
822
823def _module_repr_from_spec(spec):
824    """Return the repr to use for the module."""
825    name = '?' if spec.name is None else spec.name
826    if spec.origin is None:
827        loader = spec.loader
828        if loader is None:
829            return f'<module {name!r}>'
830        elif (
831            _bootstrap_external is not None
832            and isinstance(loader, _bootstrap_external.NamespaceLoader)
833        ):
834            return f'<module {name!r} (namespace) from {list(loader._path)}>'
835        else:
836            return f'<module {name!r} ({loader!r})>'
837    else:
838        if spec.has_location:
839            return f'<module {name!r} from {spec.origin!r}>'
840        else:
841            return f'<module {spec.name!r} ({spec.origin})>'
842
843
844# Used by importlib.reload() and _load_module_shim().
845def _exec(spec, module):
846    """Execute the spec's specified module in an existing module's namespace."""
847    name = spec.name
848    with _ModuleLockManager(name):
849        if sys.modules.get(name) is not module:
850            msg = f'module {name!r} not in sys.modules'
851            raise ImportError(msg, name=name)
852        try:
853            if spec.loader is None:
854                if spec.submodule_search_locations is None:
855                    raise ImportError('missing loader', name=spec.name)
856                # Namespace package.
857                _init_module_attrs(spec, module, override=True)
858            else:
859                _init_module_attrs(spec, module, override=True)
860                if not hasattr(spec.loader, 'exec_module'):
861                    msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
862                           "falling back to load_module()")
863                    _warnings.warn(msg, ImportWarning)
864                    spec.loader.load_module(name)
865                else:
866                    spec.loader.exec_module(module)
867        finally:
868            # Update the order of insertion into sys.modules for module
869            # clean-up at shutdown.
870            module = sys.modules.pop(spec.name)
871            sys.modules[spec.name] = module
872    return module
873
874
875def _load_backward_compatible(spec):
876    # It is assumed that all callers have been warned about using load_module()
877    # appropriately before calling this function.
878    try:
879        spec.loader.load_module(spec.name)
880    except:
881        if spec.name in sys.modules:
882            module = sys.modules.pop(spec.name)
883            sys.modules[spec.name] = module
884        raise
885    # The module must be in sys.modules at this point!
886    # Move it to the end of sys.modules.
887    module = sys.modules.pop(spec.name)
888    sys.modules[spec.name] = module
889    if getattr(module, '__loader__', None) is None:
890        try:
891            module.__loader__ = spec.loader
892        except AttributeError:
893            pass
894    if getattr(module, '__package__', None) is None:
895        try:
896            # Since module.__path__ may not line up with
897            # spec.submodule_search_paths, we can't necessarily rely
898            # on spec.parent here.
899            module.__package__ = module.__name__
900            if not hasattr(module, '__path__'):
901                module.__package__ = spec.name.rpartition('.')[0]
902        except AttributeError:
903            pass
904    if getattr(module, '__spec__', None) is None:
905        try:
906            module.__spec__ = spec
907        except AttributeError:
908            pass
909    return module
910
911def _load_unlocked(spec):
912    # A helper for direct use by the import system.
913    if spec.loader is not None:
914        # Not a namespace package.
915        if not hasattr(spec.loader, 'exec_module'):
916            msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
917                    "falling back to load_module()")
918            _warnings.warn(msg, ImportWarning)
919            return _load_backward_compatible(spec)
920
921    module = module_from_spec(spec)
922
923    # This must be done before putting the module in sys.modules
924    # (otherwise an optimization shortcut in import.c becomes
925    # wrong).
926    spec._initializing = True
927    try:
928        sys.modules[spec.name] = module
929        try:
930            if spec.loader is None:
931                if spec.submodule_search_locations is None:
932                    raise ImportError('missing loader', name=spec.name)
933                # A namespace package so do nothing.
934            else:
935                spec.loader.exec_module(module)
936        except:
937            try:
938                del sys.modules[spec.name]
939            except KeyError:
940                pass
941            raise
942        # Move the module to the end of sys.modules.
943        # We don't ensure that the import-related module attributes get
944        # set in the sys.modules replacement case.  Such modules are on
945        # their own.
946        module = sys.modules.pop(spec.name)
947        sys.modules[spec.name] = module
948        _verbose_message('import {!r} # {!r}', spec.name, spec.loader)
949    finally:
950        spec._initializing = False
951
952    return module
953
954# A method used during testing of _load_unlocked() and by
955# _load_module_shim().
956def _load(spec):
957    """Return a new module object, loaded by the spec's loader.
958
959    The module is not added to its parent.
960
961    If a module is already in sys.modules, that existing module gets
962    clobbered.
963
964    """
965    with _ModuleLockManager(spec.name):
966        return _load_unlocked(spec)
967
968
969# Loaders #####################################################################
970
971class BuiltinImporter:
972
973    """Meta path import for built-in modules.
974
975    All methods are either class or static methods to avoid the need to
976    instantiate the class.
977
978    """
979
980    _ORIGIN = "built-in"
981
982    @classmethod
983    def find_spec(cls, fullname, path=None, target=None):
984        if _imp.is_builtin(fullname):
985            return spec_from_loader(fullname, cls, origin=cls._ORIGIN)
986        else:
987            return None
988
989    @staticmethod
990    def create_module(spec):
991        """Create a built-in module"""
992        if spec.name not in sys.builtin_module_names:
993            raise ImportError(f'{spec.name!r} is not a built-in module',
994                              name=spec.name)
995        return _call_with_frames_removed(_imp.create_builtin, spec)
996
997    @staticmethod
998    def exec_module(module):
999        """Exec a built-in module"""
1000        _call_with_frames_removed(_imp.exec_builtin, module)
1001
1002    @classmethod
1003    @_requires_builtin
1004    def get_code(cls, fullname):
1005        """Return None as built-in modules do not have code objects."""
1006        return None
1007
1008    @classmethod
1009    @_requires_builtin
1010    def get_source(cls, fullname):
1011        """Return None as built-in modules do not have source code."""
1012        return None
1013
1014    @classmethod
1015    @_requires_builtin
1016    def is_package(cls, fullname):
1017        """Return False as built-in modules are never packages."""
1018        return False
1019
1020    load_module = classmethod(_load_module_shim)
1021
1022
1023class FrozenImporter:
1024
1025    """Meta path import for frozen modules.
1026
1027    All methods are either class or static methods to avoid the need to
1028    instantiate the class.
1029
1030    """
1031
1032    _ORIGIN = "frozen"
1033
1034    @classmethod
1035    def _fix_up_module(cls, module):
1036        spec = module.__spec__
1037        state = spec.loader_state
1038        if state is None:
1039            # The module is missing FrozenImporter-specific values.
1040
1041            # Fix up the spec attrs.
1042            origname = vars(module).pop('__origname__', None)
1043            assert origname, 'see PyImport_ImportFrozenModuleObject()'
1044            ispkg = hasattr(module, '__path__')
1045            assert _imp.is_frozen_package(module.__name__) == ispkg, ispkg
1046            filename, pkgdir = cls._resolve_filename(origname, spec.name, ispkg)
1047            spec.loader_state = type(sys.implementation)(
1048                filename=filename,
1049                origname=origname,
1050            )
1051            __path__ = spec.submodule_search_locations
1052            if ispkg:
1053                assert __path__ == [], __path__
1054                if pkgdir:
1055                    spec.submodule_search_locations.insert(0, pkgdir)
1056            else:
1057                assert __path__ is None, __path__
1058
1059            # Fix up the module attrs (the bare minimum).
1060            assert not hasattr(module, '__file__'), module.__file__
1061            if filename:
1062                try:
1063                    module.__file__ = filename
1064                except AttributeError:
1065                    pass
1066            if ispkg:
1067                if module.__path__ != __path__:
1068                    assert module.__path__ == [], module.__path__
1069                    module.__path__.extend(__path__)
1070        else:
1071            # These checks ensure that _fix_up_module() is only called
1072            # in the right places.
1073            __path__ = spec.submodule_search_locations
1074            ispkg = __path__ is not None
1075            # Check the loader state.
1076            assert sorted(vars(state)) == ['filename', 'origname'], state
1077            if state.origname:
1078                # The only frozen modules with "origname" set are stdlib modules.
1079                (__file__, pkgdir,
1080                 ) = cls._resolve_filename(state.origname, spec.name, ispkg)
1081                assert state.filename == __file__, (state.filename, __file__)
1082                if pkgdir:
1083                    assert __path__ == [pkgdir], (__path__, pkgdir)
1084                else:
1085                    assert __path__ == ([] if ispkg else None), __path__
1086            else:
1087                __file__ = None
1088                assert state.filename is None, state.filename
1089                assert __path__ == ([] if ispkg else None), __path__
1090            # Check the file attrs.
1091            if __file__:
1092                assert hasattr(module, '__file__')
1093                assert module.__file__ == __file__, (module.__file__, __file__)
1094            else:
1095                assert not hasattr(module, '__file__'), module.__file__
1096            if ispkg:
1097                assert hasattr(module, '__path__')
1098                assert module.__path__ == __path__, (module.__path__, __path__)
1099            else:
1100                assert not hasattr(module, '__path__'), module.__path__
1101        assert not spec.has_location
1102
1103    @classmethod
1104    def _resolve_filename(cls, fullname, alias=None, ispkg=False):
1105        if not fullname or not getattr(sys, '_stdlib_dir', None):
1106            return None, None
1107        try:
1108            sep = cls._SEP
1109        except AttributeError:
1110            sep = cls._SEP = '\\' if sys.platform == 'win32' else '/'
1111
1112        if fullname != alias:
1113            if fullname.startswith('<'):
1114                fullname = fullname[1:]
1115                if not ispkg:
1116                    fullname = f'{fullname}.__init__'
1117            else:
1118                ispkg = False
1119        relfile = fullname.replace('.', sep)
1120        if ispkg:
1121            pkgdir = f'{sys._stdlib_dir}{sep}{relfile}'
1122            filename = f'{pkgdir}{sep}__init__.py'
1123        else:
1124            pkgdir = None
1125            filename = f'{sys._stdlib_dir}{sep}{relfile}.py'
1126        return filename, pkgdir
1127
1128    @classmethod
1129    def find_spec(cls, fullname, path=None, target=None):
1130        info = _call_with_frames_removed(_imp.find_frozen, fullname)
1131        if info is None:
1132            return None
1133        # We get the marshaled data in exec_module() (the loader
1134        # part of the importer), instead of here (the finder part).
1135        # The loader is the usual place to get the data that will
1136        # be loaded into the module.  (For example, see _LoaderBasics
1137        # in _bootstrap_external.py.)  Most importantly, this importer
1138        # is simpler if we wait to get the data.
1139        # However, getting as much data in the finder as possible
1140        # to later load the module is okay, and sometimes important.
1141        # (That's why ModuleSpec.loader_state exists.)  This is
1142        # especially true if it avoids throwing away expensive data
1143        # the loader would otherwise duplicate later and can be done
1144        # efficiently.  In this case it isn't worth it.
1145        _, ispkg, origname = info
1146        spec = spec_from_loader(fullname, cls,
1147                                origin=cls._ORIGIN,
1148                                is_package=ispkg)
1149        filename, pkgdir = cls._resolve_filename(origname, fullname, ispkg)
1150        spec.loader_state = type(sys.implementation)(
1151            filename=filename,
1152            origname=origname,
1153        )
1154        if pkgdir:
1155            spec.submodule_search_locations.insert(0, pkgdir)
1156        return spec
1157
1158    @staticmethod
1159    def create_module(spec):
1160        """Set __file__, if able."""
1161        module = _new_module(spec.name)
1162        try:
1163            filename = spec.loader_state.filename
1164        except AttributeError:
1165            pass
1166        else:
1167            if filename:
1168                module.__file__ = filename
1169        return module
1170
1171    @staticmethod
1172    def exec_module(module):
1173        spec = module.__spec__
1174        name = spec.name
1175        code = _call_with_frames_removed(_imp.get_frozen_object, name)
1176        exec(code, module.__dict__)
1177
1178    @classmethod
1179    def load_module(cls, fullname):
1180        """Load a frozen module.
1181
1182        This method is deprecated.  Use exec_module() instead.
1183
1184        """
1185        # Warning about deprecation implemented in _load_module_shim().
1186        module = _load_module_shim(cls, fullname)
1187        info = _imp.find_frozen(fullname)
1188        assert info is not None
1189        _, ispkg, origname = info
1190        module.__origname__ = origname
1191        vars(module).pop('__file__', None)
1192        if ispkg:
1193            module.__path__ = []
1194        cls._fix_up_module(module)
1195        return module
1196
1197    @classmethod
1198    @_requires_frozen
1199    def get_code(cls, fullname):
1200        """Return the code object for the frozen module."""
1201        return _imp.get_frozen_object(fullname)
1202
1203    @classmethod
1204    @_requires_frozen
1205    def get_source(cls, fullname):
1206        """Return None as frozen modules do not have source code."""
1207        return None
1208
1209    @classmethod
1210    @_requires_frozen
1211    def is_package(cls, fullname):
1212        """Return True if the frozen module is a package."""
1213        return _imp.is_frozen_package(fullname)
1214
1215
1216# Import itself ###############################################################
1217
1218class _ImportLockContext:
1219
1220    """Context manager for the import lock."""
1221
1222    def __enter__(self):
1223        """Acquire the import lock."""
1224        _imp.acquire_lock()
1225
1226    def __exit__(self, exc_type, exc_value, exc_traceback):
1227        """Release the import lock regardless of any raised exceptions."""
1228        _imp.release_lock()
1229
1230
1231def _resolve_name(name, package, level):
1232    """Resolve a relative module name to an absolute one."""
1233    bits = package.rsplit('.', level - 1)
1234    if len(bits) < level:
1235        raise ImportError('attempted relative import beyond top-level package')
1236    base = bits[0]
1237    return f'{base}.{name}' if name else base
1238
1239
1240def _find_spec(name, path, target=None):
1241    """Find a module's spec."""
1242    meta_path = sys.meta_path
1243    if meta_path is None:
1244        # PyImport_Cleanup() is running or has been called.
1245        raise ImportError("sys.meta_path is None, Python is likely "
1246                          "shutting down")
1247
1248    if not meta_path:
1249        _warnings.warn('sys.meta_path is empty', ImportWarning)
1250
1251    # We check sys.modules here for the reload case.  While a passed-in
1252    # target will usually indicate a reload there is no guarantee, whereas
1253    # sys.modules provides one.
1254    is_reload = name in sys.modules
1255    for finder in meta_path:
1256        with _ImportLockContext():
1257            try:
1258                find_spec = finder.find_spec
1259            except AttributeError:
1260                continue
1261            else:
1262                spec = find_spec(name, path, target)
1263        if spec is not None:
1264            # The parent import may have already imported this module.
1265            if not is_reload and name in sys.modules:
1266                module = sys.modules[name]
1267                try:
1268                    __spec__ = module.__spec__
1269                except AttributeError:
1270                    # We use the found spec since that is the one that
1271                    # we would have used if the parent module hadn't
1272                    # beaten us to the punch.
1273                    return spec
1274                else:
1275                    if __spec__ is None:
1276                        return spec
1277                    else:
1278                        return __spec__
1279            else:
1280                return spec
1281    else:
1282        return None
1283
1284
1285def _sanity_check(name, package, level):
1286    """Verify arguments are "sane"."""
1287    if not isinstance(name, str):
1288        raise TypeError(f'module name must be str, not {type(name)}')
1289    if level < 0:
1290        raise ValueError('level must be >= 0')
1291    if level > 0:
1292        if not isinstance(package, str):
1293            raise TypeError('__package__ not set to a string')
1294        elif not package:
1295            raise ImportError('attempted relative import with no known parent '
1296                              'package')
1297    if not name and level == 0:
1298        raise ValueError('Empty module name')
1299
1300
1301_ERR_MSG_PREFIX = 'No module named '
1302_ERR_MSG = _ERR_MSG_PREFIX + '{!r}'
1303
1304def _find_and_load_unlocked(name, import_):
1305    path = None
1306    parent = name.rpartition('.')[0]
1307    parent_spec = None
1308    if parent:
1309        if parent not in sys.modules:
1310            _call_with_frames_removed(import_, parent)
1311        # Crazy side-effects!
1312        if name in sys.modules:
1313            return sys.modules[name]
1314        parent_module = sys.modules[parent]
1315        try:
1316            path = parent_module.__path__
1317        except AttributeError:
1318            msg = f'{_ERR_MSG_PREFIX}{name!r}; {parent!r} is not a package'
1319            raise ModuleNotFoundError(msg, name=name) from None
1320        parent_spec = parent_module.__spec__
1321        child = name.rpartition('.')[2]
1322    spec = _find_spec(name, path)
1323    if spec is None:
1324        raise ModuleNotFoundError(f'{_ERR_MSG_PREFIX}{name!r}', name=name)
1325    else:
1326        if parent_spec:
1327            # Temporarily add child we are currently importing to parent's
1328            # _uninitialized_submodules for circular import tracking.
1329            parent_spec._uninitialized_submodules.append(child)
1330        try:
1331            module = _load_unlocked(spec)
1332        finally:
1333            if parent_spec:
1334                parent_spec._uninitialized_submodules.pop()
1335    if parent:
1336        # Set the module as an attribute on its parent.
1337        parent_module = sys.modules[parent]
1338        try:
1339            setattr(parent_module, child, module)
1340        except AttributeError:
1341            msg = f"Cannot set an attribute on {parent!r} for child module {child!r}"
1342            _warnings.warn(msg, ImportWarning)
1343    return module
1344
1345
1346_NEEDS_LOADING = object()
1347
1348
1349def _find_and_load(name, import_):
1350    """Find and load the module."""
1351
1352    # Optimization: we avoid unneeded module locking if the module
1353    # already exists in sys.modules and is fully initialized.
1354    module = sys.modules.get(name, _NEEDS_LOADING)
1355    if (module is _NEEDS_LOADING or
1356        getattr(getattr(module, "__spec__", None), "_initializing", False)):
1357        with _ModuleLockManager(name):
1358            module = sys.modules.get(name, _NEEDS_LOADING)
1359            if module is _NEEDS_LOADING:
1360                return _find_and_load_unlocked(name, import_)
1361
1362        # Optimization: only call _bootstrap._lock_unlock_module() if
1363        # module.__spec__._initializing is True.
1364        # NOTE: because of this, initializing must be set *before*
1365        # putting the new module in sys.modules.
1366        _lock_unlock_module(name)
1367
1368    if module is None:
1369        message = f'import of {name} halted; None in sys.modules'
1370        raise ModuleNotFoundError(message, name=name)
1371
1372    return module
1373
1374
1375def _gcd_import(name, package=None, level=0):
1376    """Import and return the module based on its name, the package the call is
1377    being made from, and the level adjustment.
1378
1379    This function represents the greatest common denominator of functionality
1380    between import_module and __import__. This includes setting __package__ if
1381    the loader did not.
1382
1383    """
1384    _sanity_check(name, package, level)
1385    if level > 0:
1386        name = _resolve_name(name, package, level)
1387    return _find_and_load(name, _gcd_import)
1388
1389
1390def _handle_fromlist(module, fromlist, import_, *, recursive=False):
1391    """Figure out what __import__ should return.
1392
1393    The import_ parameter is a callable which takes the name of module to
1394    import. It is required to decouple the function from assuming importlib's
1395    import implementation is desired.
1396
1397    """
1398    # The hell that is fromlist ...
1399    # If a package was imported, try to import stuff from fromlist.
1400    for x in fromlist:
1401        if not isinstance(x, str):
1402            if recursive:
1403                where = module.__name__ + '.__all__'
1404            else:
1405                where = "``from list''"
1406            raise TypeError(f"Item in {where} must be str, "
1407                            f"not {type(x).__name__}")
1408        elif x == '*':
1409            if not recursive and hasattr(module, '__all__'):
1410                _handle_fromlist(module, module.__all__, import_,
1411                                 recursive=True)
1412        elif not hasattr(module, x):
1413            from_name = f'{module.__name__}.{x}'
1414            try:
1415                _call_with_frames_removed(import_, from_name)
1416            except ModuleNotFoundError as exc:
1417                # Backwards-compatibility dictates we ignore failed
1418                # imports triggered by fromlist for modules that don't
1419                # exist.
1420                if (exc.name == from_name and
1421                    sys.modules.get(from_name, _NEEDS_LOADING) is not None):
1422                    continue
1423                raise
1424    return module
1425
1426
1427def _calc___package__(globals):
1428    """Calculate what __package__ should be.
1429
1430    __package__ is not guaranteed to be defined or could be set to None
1431    to represent that its proper value is unknown.
1432
1433    """
1434    package = globals.get('__package__')
1435    spec = globals.get('__spec__')
1436    if package is not None:
1437        if spec is not None and package != spec.parent:
1438            _warnings.warn("__package__ != __spec__.parent "
1439                           f"({package!r} != {spec.parent!r})",
1440                           DeprecationWarning, stacklevel=3)
1441        return package
1442    elif spec is not None:
1443        return spec.parent
1444    else:
1445        _warnings.warn("can't resolve package from __spec__ or __package__, "
1446                       "falling back on __name__ and __path__",
1447                       ImportWarning, stacklevel=3)
1448        package = globals['__name__']
1449        if '__path__' not in globals:
1450            package = package.rpartition('.')[0]
1451    return package
1452
1453
1454def __import__(name, globals=None, locals=None, fromlist=(), level=0):
1455    """Import a module.
1456
1457    The 'globals' argument is used to infer where the import is occurring from
1458    to handle relative imports. The 'locals' argument is ignored. The
1459    'fromlist' argument specifies what should exist as attributes on the module
1460    being imported (e.g. ``from module import <fromlist>``).  The 'level'
1461    argument represents the package location to import from in a relative
1462    import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
1463
1464    """
1465    if level == 0:
1466        module = _gcd_import(name)
1467    else:
1468        globals_ = globals if globals is not None else {}
1469        package = _calc___package__(globals_)
1470        module = _gcd_import(name, package, level)
1471    if not fromlist:
1472        # Return up to the first dot in 'name'. This is complicated by the fact
1473        # that 'name' may be relative.
1474        if level == 0:
1475            return _gcd_import(name.partition('.')[0])
1476        elif not name:
1477            return module
1478        else:
1479            # Figure out where to slice the module's name up to the first dot
1480            # in 'name'.
1481            cut_off = len(name) - len(name.partition('.')[0])
1482            # Slice end needs to be positive to alleviate need to special-case
1483            # when ``'.' not in name``.
1484            return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
1485    elif hasattr(module, '__path__'):
1486        return _handle_fromlist(module, fromlist, _gcd_import)
1487    else:
1488        return module
1489
1490
1491def _builtin_from_name(name):
1492    spec = BuiltinImporter.find_spec(name)
1493    if spec is None:
1494        raise ImportError('no built-in module named ' + name)
1495    return _load_unlocked(spec)
1496
1497
1498def _setup(sys_module, _imp_module):
1499    """Setup importlib by importing needed built-in modules and injecting them
1500    into the global namespace.
1501
1502    As sys is needed for sys.modules access and _imp is needed to load built-in
1503    modules, those two modules must be explicitly passed in.
1504
1505    """
1506    global _imp, sys, _blocking_on
1507    _imp = _imp_module
1508    sys = sys_module
1509
1510    # Set up the spec for existing builtin/frozen modules.
1511    module_type = type(sys)
1512    for name, module in sys.modules.items():
1513        if isinstance(module, module_type):
1514            if name in sys.builtin_module_names:
1515                loader = BuiltinImporter
1516            elif _imp.is_frozen(name):
1517                loader = FrozenImporter
1518            else:
1519                continue
1520            spec = _spec_from_module(module, loader)
1521            _init_module_attrs(spec, module)
1522            if loader is FrozenImporter:
1523                loader._fix_up_module(module)
1524
1525    # Directly load built-in modules needed during bootstrap.
1526    self_module = sys.modules[__name__]
1527    for builtin_name in ('_thread', '_warnings', '_weakref'):
1528        if builtin_name not in sys.modules:
1529            builtin_module = _builtin_from_name(builtin_name)
1530        else:
1531            builtin_module = sys.modules[builtin_name]
1532        setattr(self_module, builtin_name, builtin_module)
1533
1534    # Instantiation requires _weakref to have been set.
1535    _blocking_on = _WeakValueDictionary()
1536
1537
1538def _install(sys_module, _imp_module):
1539    """Install importers for builtin and frozen modules"""
1540    _setup(sys_module, _imp_module)
1541
1542    sys.meta_path.append(BuiltinImporter)
1543    sys.meta_path.append(FrozenImporter)
1544
1545
1546def _install_external_importers():
1547    """Install importers that require external filesystem access"""
1548    global _bootstrap_external
1549    import _frozen_importlib_external
1550    _bootstrap_external = _frozen_importlib_external
1551    _frozen_importlib_external._install(sys.modules[__name__])
1552