File imp.py of Package failed_python-visvis

# Minimal compatibility shim for the removed 'imp' module (Python 3.12+)
# Provides a small subset of the old imp API used by some packages (e.g. visvis)
# so code that still does "import imp" can keep working without modifying it.
#
# This shim intentionally implements only the functions typically used by
# dynamic importers:
#  - find_module(name, path=None)
#  - load_module(name, file, pathname, description)
#  - load_source(name, pathname)
#
# It uses importlib machinery under the hood.

import importlib.util
import importlib.machinery
import sys
import os
import types
from typing import Optional, Tuple, Any, Iterable

# A very small descriptor tuple to mimic legacy imp.find_module return.
# Historically imp.find_module returned (file, pathname, description)
# where description is a tuple (suffix, mode, type). We return a similar
# placeholder for compatibility.
def _make_description():
    return ('.py', 'rb', importlib.machinery.SOURCE)

def find_module(name: str, path: Optional[Iterable[str]] = None) -> Tuple[Any, str, Tuple[str,str,int]]:
    """
    Try to locate a module by name in the given path (or sys.path if None).
    Returns (open_fileobj, pathname, description_tuple) similar to imp.find_module.
    Raises ImportError if not found.
    """
    search_paths = list(path) if path is not None else list(sys.path)

    # If name is a dotted name, only take last part for file lookups
    base = name.rsplit('.', 1)[-1]

    for directory in search_paths:
        if not directory:
            directory = os.getcwd()
        # check for simple module file
        candidate = os.path.join(directory, base + ".py")
        if os.path.isfile(candidate):
            f = open(candidate, "rb")
            return f, candidate, _make_description()
        # check for package directory with __init__.py
        pkg_init = os.path.join(directory, base, "__init__.py")
        if os.path.isfile(pkg_init):
            f = open(pkg_init, "rb")
            return f, pkg_init, _make_description()

    raise ImportError(f"Module {name!r} not found in path")

def load_module(name: str, fileobj, pathname: str, description: Tuple[str,str,int]):
    """
    Load a module from the given pathname. This mimics imp.load_module behavior
    sufficiently for typical uses: it creates a module object, inserts it into
    sys.modules under `name`, and executes the source.
    """
    # Use SourceFileLoader to load the source file.
    loader = importlib.machinery.SourceFileLoader(name, pathname)
    spec = importlib.util.spec_from_loader(name, loader, origin=pathname)
    module = importlib.util.module_from_spec(spec)
    # Insert into sys.modules before execution, like old imp did.
    sys.modules[name] = module
    try:
        loader.exec_module(module)
    except Exception:
        # If execution fails, ensure we don't leave a broken module in sys.modules
        try:
            del sys.modules[name]
        except Exception:
            pass
        raise
    return module

def load_source(name: str, pathname: str):
    """
    Legacy convenience function imp.load_source(name, pathname).
    Load module directly from source file pathname.
    """
    loader = importlib.machinery.SourceFileLoader(name, pathname)
    spec = importlib.util.spec_from_loader(name, loader, origin=pathname)
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    try:
        loader.exec_module(module)
    except Exception:
        try:
            del sys.modules[name]
        except Exception:
            pass
        raise
    return module

# Provide a minimal get_tagged_suffixes / get_suffixes compatibility if asked.
def get_suffixes():
    # mimic imp.get_suffixes() returning list of (suffix, mode, type)
    return [('.py', 'rb', importlib.machinery.SOURCE)]

# simple API marker for code expecting imp.is_builtin
def is_builtin(name: str) -> bool:
    return name in sys.builtin_module_names

# Expose a small set of names that some legacy code may import from imp
__all__ = [
    "find_module",
    "load_module",
    "load_source",
    "get_suffixes",
    "is_builtin",
]
openSUSE Build Service is sponsored by