Claude Code for sysconfig: Python Build and Installation Paths — Claude Skills 360 Blog
Blog / AI / Claude Code for sysconfig: Python Build and Installation Paths
AI

Claude Code for sysconfig: Python Build and Installation Paths

Published: October 7, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s sysconfig module exposes the build-time configuration and installation directory layout for the running interpreter. import sysconfig. get_path: sysconfig.get_path("stdlib") → absolute path; schemes: "stdlib", "purelib", "platlib", "scripts", "data", "include", "platinclude". get_paths: sysconfig.get_paths() → dict of all paths for the default scheme. get_config_var: sysconfig.get_config_var("EXT_SUFFIX")".cpython-312-x86_64-linux-gnu.so" (extension suffix); "SOABI", "LDFLAGS", "CC", "py_version_short", "prefix". get_config_vars: sysconfig.get_config_vars() → full dict of all Makefile/pyconfig.h variables. get_python_version: sysconfig.get_python_version()"3.12". get_platform: sysconfig.get_platform()"linux-x86_64" (wheel platform tag). get_scheme_names: sysconfig.get_scheme_names() → list of scheme names ("posix_prefix", "nt", "venv", etc.). get_default_scheme: sysconfig.get_default_scheme() → name of active scheme. is_python_build: sysconfig.is_python_build() → True if running in-place from source tree. parse_config_h: sysconfig.parse_config_h(fileobj) → dict from a pyconfig.h-style file. Claude Code generates environment sniffers, extension build helpers, install path resolvers, and cross-platform wheel taggers.

CLAUDE.md for sysconfig

## sysconfig Stack
- Stdlib: import sysconfig
- Path:   sysconfig.get_path("stdlib")          # absolute install path
- All:    sysconfig.get_paths()                  # dict of all paths
- Var:    sysconfig.get_config_var("EXT_SUFFIX") # .cpython-312-...so
- Vars:   sysconfig.get_config_vars()            # all Makefile vars
- Ver:    sysconfig.get_python_version()         # "3.12"
- Plat:   sysconfig.get_platform()              # "linux-x86_64"

sysconfig Build Configuration Pipeline

# app/sysconfigutil.py — paths, vars, platform, extension, venv, cross-compile
from __future__ import annotations

import os
import sys
import sysconfig
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any


# ─────────────────────────────────────────────────────────────────────────────
# 1. Path resolution helpers
# ─────────────────────────────────────────────────────────────────────────────

# Standard path keys provided by every scheme
PATH_KEYS = ("stdlib", "purelib", "platlib", "scripts", "data", "include", "platinclude")


def get_path(key: str, scheme: str | None = None) -> Path:
    """
    Return an installation path as a Path object.

    key: "stdlib", "purelib", "platlib", "scripts", "data", "include", "platinclude"
    scheme: None = default scheme; or e.g. "posix_prefix", "nt", "venv"

    Example:
        scripts_dir = get_path("scripts")
        site_packages = get_path("purelib")
    """
    kw: dict[str, Any] = {}
    if scheme:
        kw["scheme"] = scheme
    return Path(sysconfig.get_path(key, **kw))


def get_all_paths(scheme: str | None = None) -> dict[str, Path]:
    """
    Return all installation paths for the given scheme (default = active scheme).

    Example:
        for name, path in get_all_paths().items():
            print(f"  {name:12s}: {path}")
    """
    kw: dict[str, Any] = {}
    if scheme:
        kw["scheme"] = scheme
    return {k: Path(v) for k, v in sysconfig.get_paths(**kw).items()}


def site_packages() -> Path:
    """Return the site-packages directory for the current interpreter."""
    return get_path("purelib")


def scripts_dir() -> Path:
    """Return the directory where console_scripts entry-point scripts are installed."""
    return get_path("scripts")


def stdlib_dir() -> Path:
    """Return the standard library directory."""
    return get_path("stdlib")


# ─────────────────────────────────────────────────────────────────────────────
# 2. Build configuration variables
# ─────────────────────────────────────────────────────────────────────────────

def get_var(name: str) -> Any:
    """
    Return a single build config variable, or None if not defined.

    Example:
        ext_suffix = get_var("EXT_SUFFIX")   # ".cpython-312-x86_64-linux-gnu.so"
        cc = get_var("CC")                   # "gcc"
    """
    return sysconfig.get_config_var(name)


def get_vars(prefix: str = "") -> dict[str, Any]:
    """
    Return all build config variables, optionally filtered by name prefix.

    Example:
        ld_vars = get_vars("LD")   # all LDFLAGS-like vars
    """
    all_vars = sysconfig.get_config_vars()
    if prefix:
        return {k: v for k, v in all_vars.items() if k.startswith(prefix)}
    return dict(all_vars)


def extension_suffix() -> str:
    """
    Return the file extension for compiled C extensions on this platform.

    Example:
        suf = extension_suffix()   # ".cpython-312-x86_64-linux-gnu.so"
    """
    return get_var("EXT_SUFFIX") or ".so"


def soabi() -> str | None:
    """Return the SOABI tag (e.g. 'cpython-312-x86_64-linux-gnu') or None."""
    return get_var("SOABI")


# ─────────────────────────────────────────────────────────────────────────────
# 3. Platform and version tags
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class PythonEnvironment:
    version:        str          # "3.12"
    platform:       str          # "linux-x86_64"
    scheme:         str          # "posix_prefix"
    prefix:         str          # sys.prefix
    exec_prefix:    str          # sys.exec_prefix
    in_venv:        bool
    is_build:       bool
    ext_suffix:     str
    soabi:          str | None
    paths:          dict[str, str] = field(default_factory=dict)

    def __str__(self) -> str:
        venv_tag = " [venv]" if self.in_venv else ""
        build_tag = " [build-dir]" if self.is_build else ""
        return (
            f"Python {self.version} on {self.platform}{venv_tag}{build_tag}\n"
            f"  scheme:      {self.scheme}\n"
            f"  prefix:      {self.prefix}\n"
            f"  ext_suffix:  {self.ext_suffix}\n"
            f"  site-pkgs:   {self.paths.get('purelib', '?')}"
        )


def describe_environment() -> PythonEnvironment:
    """
    Snapshot the full Python environment configuration.

    Example:
        env = describe_environment()
        print(env)
    """
    in_venv = (
        hasattr(sys, "real_prefix") or                    # virtualenv
        (sys.base_prefix != sys.prefix)                   # venv / conda
    )
    return PythonEnvironment(
        version=sysconfig.get_python_version(),
        platform=sysconfig.get_platform(),
        scheme=sysconfig.get_default_scheme(),
        prefix=sys.prefix,
        exec_prefix=sys.exec_prefix,
        in_venv=in_venv,
        is_build=sysconfig.is_python_build(),
        ext_suffix=extension_suffix(),
        soabi=soabi(),
        paths={k: str(v) for k, v in get_all_paths().items()},
    )


def wheel_tag() -> str:
    """
    Build a minimal wheel compatibility tag string for the current platform.
    Format: cpXY-cpXY-<platform> or py3-none-any for pure Python.

    Example:
        tag = wheel_tag()   # "cp312-cp312-linux_x86_64"
    """
    ver = sysconfig.get_python_version().replace(".", "")
    plat = sysconfig.get_platform().replace("-", "_").replace(".", "_")
    soabi_tag = soabi()
    if soabi_tag:
        return f"cp{ver}-{soabi_tag.replace('-', '_')}-{plat}"
    return f"py3-none-{plat}"


# ─────────────────────────────────────────────────────────────────────────────
# 4. Scheme browser
# ─────────────────────────────────────────────────────────────────────────────

def list_schemes() -> list[str]:
    """
    Return all known installation scheme names.

    Example:
        for scheme in list_schemes():
            print(scheme, get_path("purelib", scheme=scheme))
    """
    return sorted(sysconfig.get_scheme_names())


def compare_schemes(key: str = "purelib") -> dict[str, str]:
    """
    Compare the value of a path key across all schemes.

    Example:
        for scheme, path in compare_schemes("scripts").items():
            print(f"  {scheme:20s}: {path}")
    """
    result: dict[str, str] = {}
    for scheme in list_schemes():
        try:
            result[scheme] = str(get_path(key, scheme=scheme))
        except KeyError:
            pass
    return result


# ─────────────────────────────────────────────────────────────────────────────
# 5. Extension build helper
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class ExtensionBuildInfo:
    """
    Collects flags and paths needed to compile a C extension against this Python.
    """
    include_dirs:   list[str]
    library_dirs:   list[str]
    libraries:      list[str]
    extra_compile:  list[str]
    extra_link:     list[str]
    ext_suffix:     str

    def cflags(self) -> list[str]:
        flags = [f"-I{d}" for d in self.include_dirs]
        flags += self.extra_compile
        return flags

    def ldflags(self) -> list[str]:
        flags = [f"-L{d}" for d in self.library_dirs]
        flags += [f"-l{lib}" for lib in self.libraries]
        flags += self.extra_link
        return flags

    def __str__(self) -> str:
        return (
            f"ext_suffix:  {self.ext_suffix}\n"
            f"include:     {' '.join(self.include_dirs)}\n"
            f"cflags:      {' '.join(self.cflags())}\n"
            f"ldflags:     {' '.join(self.ldflags())}"
        )


def extension_build_info() -> ExtensionBuildInfo:
    """
    Return compiler/linker info for building a C extension against this Python.

    Example:
        info = extension_build_info()
        print(info)
        subprocess.run(["gcc", *info.cflags(), "-shared", "-fPIC",
                        "myext.c", "-o", f"myext{info.ext_suffix}"])
    """
    include_dir = get_var("INCLUDEPY") or ""
    platinclude = str(get_path("platinclude"))
    inc_dirs = list({d for d in [include_dir, platinclude] if d and Path(d).exists()})

    lib_dir = get_var("LIBDIR") or ""
    lib_dirs = [lib_dir] if lib_dir and Path(lib_dir).exists() else []

    ldflags_str = get_var("LDFLAGS") or ""
    cflags_str  = get_var("PY_CFLAGS") or ""

    return ExtensionBuildInfo(
        include_dirs=inc_dirs,
        library_dirs=lib_dirs,
        libraries=[],
        extra_compile=[f for f in cflags_str.split() if f],
        extra_link=[f for f in ldflags_str.split() if f],
        ext_suffix=extension_suffix(),
    )


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

if __name__ == "__main__":
    print("=== sysconfig demo ===")

    # ── get_path / get_all_paths ───────────────────────────────────────────────
    print("\n--- installation paths ---")
    for name, path in get_all_paths().items():
        print(f"  {name:12s}: {path}")

    # ── build variables ────────────────────────────────────────────────────────
    print("\n--- key build variables ---")
    for var in ["EXT_SUFFIX", "SOABI", "py_version_short", "CC", "prefix"]:
        print(f"  {var:20s}: {get_var(var)!r}")

    # ── describe_environment ───────────────────────────────────────────────────
    print("\n--- describe_environment ---")
    env = describe_environment()
    print(env)

    # ── wheel_tag ──────────────────────────────────────────────────────────────
    print(f"\n--- wheel_tag: {wheel_tag()!r} ---")

    # ── scheme comparison ──────────────────────────────────────────────────────
    print("\n--- purelib across schemes (sample) ---")
    schemes = compare_schemes("purelib")
    for scheme, path in list(schemes.items())[:4]:
        print(f"  {scheme:20s}: {path}")

    # ── extension build info ───────────────────────────────────────────────────
    print("\n--- extension_build_info ---")
    info = extension_build_info()
    print(info)

    # ── list_schemes ───────────────────────────────────────────────────────────
    print(f"\n--- available schemes: {list_schemes()} ---")

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

For the sys / site alternative — sys.prefix, sys.exec_prefix, sys.path, and sys.version_info expose runtime install locations and the module search path; site.getsitepackages() and site.getusersitepackages() return the site-packages directories directly — use sys and site when you need fast read-only access to the interpreter prefix and site-packages paths at runtime without querying the full build configuration; use sysconfig when you need precise, scheme-aware path resolution for packaging tools (setup.py, pip, build backends) or when you need build variables like EXT_SUFFIX, compiler flags, or the SOABI tag for C extension compilation. For the distutils.sysconfig alternative — distutils.sysconfig (deprecated since 3.10, removed in 3.12) was the original build configuration module and exposed similar variables via get_python_inc(), get_python_lib(), and get_config_var() — use sysconfig (the stdlib replacement) for all new code; the sysconfig module was designed as a clean, scheme-aware replacement and is the authoritative source for build-time variables and install paths in Python 3.2+. The Claude Skills 360 bundle includes sysconfig skill sets covering get_path()/get_all_paths()/site_packages()/scripts_dir()/stdlib_dir() path resolvers, get_var()/get_vars()/extension_suffix()/soabi() build variable readers, PythonEnvironment dataclass with describe_environment()/wheel_tag(), list_schemes()/compare_schemes() scheme browser, and ExtensionBuildInfo with extension_build_info() C extension compiler helper. Start with the free tier to try build configuration patterns and sysconfig 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