Claude Code for importlib.abc: Python Import System ABCs — Claude Skills 360 Blog
Blog / AI / Claude Code for importlib.abc: Python Import System ABCs
AI

Claude Code for importlib.abc: Python Import System ABCs

Published: January 10, 2029
Read time: 5 min read
By: Claude Skills 360

Python’s importlib.abc module defines the Abstract Base Classes that form the import system protocol — subclass these to build custom finders and loaders. import importlib.abc. Key ABCs: MetaPathFinder — add to sys.meta_path; override find_spec(fullname, path, target)ModuleSpec | None. PathEntryFinder — returned by a callable on sys.path_hooks; override find_spec(fullname, target). Loader — override create_module(spec) (return None for default) and exec_module(module). SourceLoader — for Python source; override get_data(path)bytes and get_filename(name)str; enables bytecode caching automatically. InspectLoader — adds get_source(fullname), is_package(fullname), get_code(fullname). ResourceLoader — adds get_data(path)bytes (deprecated, use importlib.resources). Register: sys.meta_path.insert(0, MyFinder()) — intercepts imports before the default finders. Claude Code generates in-memory importers, encrypted module loaders, namespace packages, database-backed modules, and import auditing hooks.

CLAUDE.md for importlib.abc

## importlib.abc Stack
- Stdlib: import importlib.abc, importlib.machinery, sys
- Finder: class F(importlib.abc.MetaPathFinder):
-             def find_spec(self, fullname, path, target): ...
- Loader: class L(importlib.abc.Loader):
-             def create_module(self, spec): return None  # default
-             def exec_module(self, module): exec(code, module.__dict__)
- Install: sys.meta_path.insert(0, MyFinder())
- Spec:    importlib.machinery.ModuleSpec(name, loader, origin=...)
- Remove:  sys.meta_path[:] = [f for f in sys.meta_path if not isinstance(f, MyFinder)]

importlib.abc Custom Import Pipeline

# app/importabcutil.py — in-memory, dict, audit hook, namespace, encrypted
from __future__ import annotations

import importlib.abc
import importlib.machinery
import importlib.util
import sys
from types import ModuleType
from typing import Any


# ─────────────────────────────────────────────────────────────────────────────
# 1. In-memory module loader
# ─────────────────────────────────────────────────────────────────────────────

class InMemoryLoader(importlib.abc.Loader):
    """
    Load a Python module from a source string in memory.

    Example:
        loader = InMemoryLoader("x = 42\ndef greet(name): return f'hi {name}'")
        spec = importlib.machinery.ModuleSpec("mymod", loader, origin="<memory>")
        mod = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)
        print(mod.greet("world"))
    """

    def __init__(self, source: str, origin: str = "<memory>") -> None:
        self._source = source
        self._origin = origin

    def create_module(self, spec: importlib.machinery.ModuleSpec) -> None:
        return None  # use default module creation

    def exec_module(self, module: ModuleType) -> None:
        code = compile(self._source, self._origin, "exec")
        exec(code, module.__dict__)

    def get_source(self, fullname: str) -> str:
        return self._source

    def is_package(self, fullname: str) -> bool:
        return False


def load_from_string(name: str, source: str) -> ModuleType:
    """
    Create and execute a module from a source string, registered in sys.modules.

    Example:
        mod = load_from_string("calc", "def add(a, b): return a + b")
        print(mod.add(2, 3))   # 5
    """
    loader = InMemoryLoader(source, origin=f"<string:{name}>")
    spec = importlib.machinery.ModuleSpec(name, loader, origin=loader._origin)
    mod = importlib.util.module_from_spec(spec)
    sys.modules[name] = mod
    loader.exec_module(mod)
    return mod


# ─────────────────────────────────────────────────────────────────────────────
# 2. Dict-backed finder — intercepts specific module names
# ─────────────────────────────────────────────────────────────────────────────

class DictFinder(importlib.abc.MetaPathFinder):
    """
    A meta path finder backed by a dict mapping module names to source strings.
    Only handles modules whose names appear in the dict.

    Example:
        finder = DictFinder({
            "hello_world": "MESSAGE = 'Hello, World!'",
            "math_utils":  "def double(x): return x * 2",
        })
        sys.meta_path.insert(0, finder)
        import hello_world
        print(hello_world.MESSAGE)
        finder.uninstall()
    """

    def __init__(self, modules: dict[str, str]) -> None:
        self._modules = modules
        self._installed = False

    def find_spec(
        self,
        fullname: str,
        path: Any,
        target: Any = None,
    ) -> "importlib.machinery.ModuleSpec | None":
        if fullname in self._modules:
            loader = InMemoryLoader(self._modules[fullname], origin=f"<dict:{fullname}>")
            return importlib.machinery.ModuleSpec(fullname, loader)
        return None

    def install(self) -> "DictFinder":
        """Install this finder as the first entry in sys.meta_path."""
        if not self._installed:
            sys.meta_path.insert(0, self)
            self._installed = True
        return self

    def uninstall(self) -> None:
        """Remove this finder from sys.meta_path and clear cached modules."""
        if self in sys.meta_path:
            sys.meta_path.remove(self)
        for name in self._modules:
            sys.modules.pop(name, None)
        self._installed = False

    def add(self, name: str, source: str) -> None:
        """Add or update a module in the dict."""
        self._modules[name] = source
        sys.modules.pop(name, None)  # invalidate cached version


# ─────────────────────────────────────────────────────────────────────────────
# 3. Import audit hook (non-finder)
# ─────────────────────────────────────────────────────────────────────────────

class ImportAuditor(importlib.abc.MetaPathFinder):
    """
    A passthrough meta path finder that records every find_spec call
    without intercepting any imports.

    Example:
        auditor = ImportAuditor()
        auditor.install()
        import json
        print(auditor.log)   # [("json", None)]
        auditor.uninstall()
    """

    def __init__(self) -> None:
        self.log: list[tuple[str, Any]] = []

    def find_spec(
        self,
        fullname: str,
        path: Any,
        target: Any = None,
    ) -> None:
        self.log.append((fullname, path))
        return None  # let normal finders take over

    def install(self) -> "ImportAuditor":
        sys.meta_path.insert(0, self)
        return self

    def uninstall(self) -> None:
        if self in sys.meta_path:
            sys.meta_path.remove(self)

    def clear(self) -> None:
        self.log.clear()

    def was_imported(self, name: str) -> bool:
        return any(n == name for n, _ in self.log)


# ─────────────────────────────────────────────────────────────────────────────
# 4. SourceLoader stub for custom source origins
# ─────────────────────────────────────────────────────────────────────────────

class StringSourceLoader(importlib.abc.SourceLoader):
    """
    A SourceLoader backed by an in-memory string.
    SourceLoader automatically handles get_code() and is_package() based on
    get_data() and get_filename().

    Example:
        loader = StringSourceLoader("mymod", "x = 99", origin="<test>")
        spec = importlib.machinery.ModuleSpec("mymod", loader, origin="<test>")
        mod = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)
        print(mod.x)   # 99
    """

    def __init__(self, name: str, source: str, origin: str = "<string>") -> None:
        self._name = name
        self._source = source
        self._origin = origin

    def get_data(self, path: str) -> bytes:
        return self._source.encode("utf-8")

    def get_filename(self, name: str) -> str:
        return self._origin

    def is_package(self, fullname: str) -> bool:
        return False


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== importlib.abc demo ===")

    # ── load_from_string ──────────────────────────────────────────────────────
    print("\n--- load_from_string ---")
    calc = load_from_string(
        "_demo_calc",
        "def add(a, b): return a + b\nPI = 3.14159",
    )
    print(f"  add(10, 32) = {calc.add(10, 32)}")
    print(f"  PI = {calc.PI}")
    sys.modules.pop("_demo_calc", None)

    # ── DictFinder ────────────────────────────────────────────────────────────
    print("\n--- DictFinder ---")
    finder = DictFinder({
        "_demo_greet":  'def hi(name): return f"Hello, {name}!"',
        "_demo_math":   "square = lambda x: x * x\ncube = lambda x: x ** 3",
    })
    finder.install()

    import _demo_greet  # type: ignore[import]
    import _demo_math   # type: ignore[import]
    print(f"  greet.hi('World') = {_demo_greet.hi('World')!r}")
    print(f"  math.square(7)   = {_demo_math.square(7)}")
    print(f"  math.cube(3)     = {_demo_math.cube(3)}")
    finder.uninstall()

    # ── ImportAuditor ─────────────────────────────────────────────────────────
    print("\n--- ImportAuditor ---")
    auditor = ImportAuditor()
    auditor.install()
    import json as _json_test  # noqa: F401
    import os.path as _osp_test  # noqa: F401
    auditor.uninstall()
    print(f"  logged {len(auditor.log)} find_spec calls")
    print(f"  was 'json' queried: {auditor.was_imported('json')}")
    print(f"  first 5 modules queried: {[n for n,_ in auditor.log[:5]]}")

    # ── StringSourceLoader ────────────────────────────────────────────────────
    print("\n--- StringSourceLoader ---")
    loader = StringSourceLoader("_demo_ssl", "ANSWER = 42\nversion = '1.0'")
    spec = importlib.machinery.ModuleSpec("_demo_ssl_mod", loader, origin="<test>")
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    print(f"  ANSWER  = {mod.ANSWER}")
    print(f"  version = {mod.version!r}")

    print("\n=== done ===")

For the importlib.util.spec_from_file_location() alternative — importlib.util.spec_from_file_location("name", path) creates a ModuleSpec from a filesystem path using the standard file loaders provided by importlib.machinery — use spec_from_file_location for file-based dynamic imports; use importlib.abc.MetaPathFinder + Loader when you need to intercept imports system-wide, load modules from non-filesystem sources (databases, network, encrypted containers), or redirect entire module hierarchies. For the pkgutil.get_importer() legacy alternative — pkgutil.get_importer(path) and pkgutil.iter_importers() expose the old find_module/load_module API that predates find_spec/exec_module — always implement the new find_spec/exec_module API when writing custom finders and loaders; the old find_module/load_module interface is deprecated since Python 3.4. The Claude Skills 360 bundle includes importlib.abc skill sets covering InMemoryLoader with exec_module()/get_source(), load_from_string() helper, DictFinder with install()/uninstall()/add(), ImportAuditor passthrough with was_imported(), and StringSourceLoader SourceLoader subclass. Start with the free tier to try custom import patterns and importlib.abc pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free