3 import and importlib notes
Alex Willmer edited this page 2024-08-29 09:34:34 +01:00
class module:
    __name__        # Full qualified name. Required.
    __loader__      # Loader object used to load the module. Required. Deprecated.
    __package__     # If the module is a package, same as __name__.
                    # Otherwise name of parent package, or empty string for
                    # top-level module. Optional.
    __spec__        # ModuleSpec object. Required (except sometimes for __main__).
    __path__        # Search path for modules inside package. Required iif a package.
                    # Presence of __path__ indicates a package.
                    # Iterable type other than list indicates a namespace package (PEP 420)
    __file__        # Path of the file (if any) the module was loaded from. Optional.
    __cached__      # Path of cached bytecode (if any) for the module. Optional.

class importlib._bootstrap.BuiltinImporter
    def is_package(cls, fullname) -> False:
        "built-in modules are never packages."


class importlib.abc.MetaPathFinder:
    def find_spec(fullname, path, target=None)
        Should return None if this finder can't handle the module.
        Raise ModuleNotFoundError to halt any further search for the module.
    def invalidate_caches()  # Optional

class importlib.abc.Loader:
    def create_module(spec)
        Return a created module object, or None if the spec should create it.
        Raise ImportError if anything prevents creation of the module object.
    def exec_module(spec)
        Execute the module. Don't return anything.

class importlib.abc.PathEntryFinder:
    def find_spec(fullname, target=None)
    def invalidate_caches()  # Optional


importlib.machinery.ModuleSpec:  # Python 3.4+
    name            # __name__
    loader          # __loader__
    origin          # __file__
                    # None has been seen in the wild (#1042),
                    # it may indicate a namespace package.
    submodule_search_locations
                    # __path__
                    # None indicates a non-package.
                    # List (even empty) indicates a package.
                    # A custom iterable indicates a namespace package.
    loader_state
    cached          # __cached__
    parent          # __package__
                    # Same as name, if the module is a package.
                    # Otherwise name of parent package,
                    # or empty string if a top-level module.
    has_location    # True if origin refers to a loadable location

importlib.find_loader(name, path=None)  # Python 3.3-3.11

importlib.util._find_spec(name, path, target=None)
importlib.util.find_spec(name, package=None)  # Python 3.4+
importlib.util.spec_from_file_location(nmae, location=None, * loader=None,
                                       submodule_search_locations=...)

_imp module is implemented in https://github.com/python/cpython/blob/3.11/Python/import.c


imp.find_module -> (Optional[fobj], Optional[path], (suffix, mode, type_))  # Python 2.x - 3.11
import.new_module() types.ModuleType()
Python 2.x bytes or unicode bytes
Python 3.x unicode unicode
ansible_mitogen.module_finder.Module:
    name    Unqualified name of the module.
    path    Filesystem path of the module.
    kind    One of the constants in `imp`, as returned in `imp.find_module()`
    parent  `ansible_mitogen.module_finder.Module` of parent package (if any).

pkgutil.ModuleInfo(module_finder, name, ispkg)  # namedtuple, Python 3.6+
pkgutil.find_loader(full_name)          # Deprecated 3.12, removal 3.14
pkgutil.get_importer(path_item)
pkgutil.get_loader(module_or_name)      # Deprecated 3.12, removal 3.14

sys.builtin_module_names: tuple         # Python 2.2+, atleast
sys.stdlib_module_names: frozenset      # Python 3.10, includes platform specific 
                                        # even if not correct platform
https://pypi.org/project/stdlibs/


Module name must be a valid Python identifier
    Python 2: r'[A-Za-z_][A-Za-z0-9_]*'
    Python 3: https://docs.python.org/3/reference/lexical_analysis.html#identifiers


Python 2.7:
    sys.meta_path == []
    sys.path_hooks == [<type 'zipimport.zipimporter'>]

Python 3.11:
    sys.meta_path == [
        <_distutils_hack.DistutilsMetaFinder object at 0x100874e90>,
        <class '_frozen_importlib.BuiltinImporter'>,
        <class '_frozen_importlib.FrozenImporter'>,
        <class '_frozen_importlib_external.PathFinder'>,
    ]
    sys.path_hooks == [
        <class 'zipimport.zipimporter'>,
        <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x1007e8900>.
    ]

Sources

Issues