class_docstr: A finder and loader that produces "accelerated" modules.
  
  When someone attempts to import the specified slow library with
  this finder enabled, we intercept the import and deliver an
  equivalent, accelerated, version of the module. This provides
  attributes and modules that check if they are being used from
  "within" the slow (or fast) library themselves. If this is the
  case, the implementation is forwarded to the actual slow library
  implementation, otherwise a proxy implementation is used (which
  attempts to call the fast version first).
code: def _populate_module(self, mod: ModuleType):
      mod_name = mod.__name__
  
      # Here we attempt to import "_fsproxy_slow_lib.x.y.z", but
      # "_fsproxy_slow_lib" does not exist anywhere as a real file, so
      # how does this work?
      # The importer attempts to import ".z" by first importing
      # "_fsproxy_slow_lib.x.y", this recurses until we find
      # "_fsproxy_slow_lib.x" (say), which does exist because we set that up
      # in __init__. Now the importer looks at the __path__
      # attribute of "x" and uses that to find the relative location
      # to look for "y". This __path__ points to the real location
      # of "slow_lib.x". So, as long as we rewire the _already imported_
      # slow_lib modules in sys.modules to _fsproxy_slow_lib, when we
      # get here this will find the right thing.
      # The above exposition is for lazily imported submodules (e.g.
      # avoiding circular imports by putting an import at function
      # level). For everything that is eagerly imported when we do
      # "import slow_lib" this import line is trivial because we
      # immediately pull the correct result out of sys.modules.
      slow_mod = importlib.import_module(
          rename_root_module(
              mod_name,
              self.slow_lib,
              self._module_cache_prefix + self.slow_lib,
          )
      )
      try:
          fast_mod = importlib.import_module(
              rename_root_module(mod_name, self.slow_lib, self.fast_lib)
          )
      except Exception:
          fast_mod = None
  
      # The version that will be used if called within a denylist
      # package
      real_attributes = {}
      # The version that will be used outside denylist packages
      for key in slow_mod.__dir__():
          with warnings.catch_warnings():
              warnings.simplefilter("ignore", FutureWarning)
              slow_attr = getattr(slow_mod, key)
          fast_attr = getattr(fast_mod, key, _Unusable())
          real_attributes[key] = slow_attr
          try:
              wrapped_attr = self._wrap_attribute(
                  slow_attr, fast_attr, key
              )
              self._wrapped_objs[slow_attr] = wrapped_attr
          except TypeError:
              # slow_attr is not hashable
              pass
  
      # Our module has (basically) no static attributes and instead
      # always delivers them dynamically where the behaviour is
      # dependent on the calling module.
      setattr(
          mod,
          "__getattr__",
          functools.partial(
              self.getattr_real_or_wrapped,
              real=real_attributes,
              wrapped_objs=self._wrapped_objs,
              loader=self,
          ),
      )
  
      # ...but, we want to pretend like we expose the same attributes
      # as the equivalent slow module
      setattr(mod, "__dir__", slow_mod.__dir__)
  
      # We set __path__ to the real path so that importers like
      # jinja2.PackageLoader("slow_mod") work correctly.
      if getattr(slow_mod, "__path__", False):
          assert mod.__spec__
          mod.__path__ = slow_mod.__path__
          mod.__spec__.submodule_search_locations = [*slow_mod.__path__]
      return self._postprocess_module(mod, slow_mod, fast_mod)
  
imports: from __future__ import annotations
  import contextlib
  import functools
  import importlib
  import importlib.abc
  import importlib.machinery
  import os
  import pathlib
  import sys
  import threading
  import warnings
  from abc import abstractmethod
  from importlib._bootstrap import _ImportLockContext
  from types import ModuleType
  from typing import Any, ContextManager, Dict, List, NamedTuple
  from typing_extensions import Self
  from .fast_slow_proxy import _FunctionProxy, _is_function_or_method, _Unusable, get_final_type_map, get_intermediate_type_map, get_registered_functions
label_desc: Use image node_id 2 for calling the ModuleAccelerator obj's underlying member method code with example usage: obj._populate_module(mod) and returns: self