Skip to content

New sysconfig API: Build information - Compilation #103482

Open

Description

@FFY00

Feature or enhancement

sysconfig should export all the information required to build extensions.

Pitch

The new API should try to expose the information in a compiler-agnostic way.

Information to expose

  • Python version
    • currently: sys.version_info
  • Interpreter version
    • currently: sys.implementation
  • Extension suffixes
    • definition: See PEP 3149
      • consideration: PEP 3149 only defines the names for POSIX
      • design: The API should identify the different extensions types (interpreter, stable abi, none)
    • currently: importlib.machinery.EXTENSION_SUFFIXES, sysconfig.get_config_var('EXT_SUFFIX'), sysconfig.get_config_var('SHLIB_SUFFIX')
  • Is a shared libpython available? What's its name? Location?
    • definition: Yes if built with --enable-shared
    • currently:
      • (available?) bool(sysconfig.get_config_var('LDLIBRARY'))
      • (name?) sysconfig.get_config_var('LDLIBRARY')
      • (location?) sysconfig.get_config_var('LIBDIR')
  • Is a static libpython available? What's its name? Location?
    • definition: Yes unless built with --without-static-libpython
    • currently:
      • (available?) bool(sysconfig.get_config_var('LIBRARY'))
      • (name?) sysconfig.get_config_var('LIBRARY')
      • (location?) sysconfig.get_config_var('LIBDIR')
  • Should extensions link against libpython?
  • Is it a debug build?
    • definition: Yes if built with --with-pydebug
    • currently: bool(sysconfig.get_config_var('Py_DEBUG'))
  • C flags needed when using the C API
    • definition:
      • -fwrapv (until Enable -fstrict-overflow #96821)
        • Currently, we have unsafe code, and for a lack of a better option we assume it made into C macros, so extensions that use the C API should use -fwrapv.
  • what else? please comment...
"definition" sections list the answer, if a question, or the value(s) of the item. "currently" sections list the current way of fetching the information.

This is list is a work in progress. Currently, we need to gather all the information that is required to build extensions. If you see anything that's missing, please comment!

Previous discussion

https://discuss.python.org/t/building-extensions-modules-in-a-post-distutils-world/23938
https://discuss.python.org/t/what-information-is-useful-to-know-statically-about-an-interpreter/25563
https://gregoryszorc.com/docs/python-build-standalone/20230116/distributions.html

New sysconfig API meta-issue: GH-103480

Activity

  1. zooba commented on May 2, 2023

    @zooba
    Member

    Explicitly capturing the platform (not just the pointer width) that the runtime is targeting would be great. This is probably an arbitrary string used by the build toolset, rather than something universal.

    Because Windows OS can emulate earlier architectures, and ARM64 and AMD64 have the same pointer width, the only way to know right now that you've got (in particular) an ARM64 build is to look at sys.winver. The running interpreter on an ARM64 processor could be x86 or AMD64, and the processor may be reported as one of these for emulation purposes, depending on how you ask.

    Capturing the target platform at compile time would be much better.

  2. katietz commented on May 12, 2023

    @katietz

    I would see such feature as very useful to be able to use host's python interpreter in crosstool scenario. I would be very useful to have a switch/configuration-file, which can be used to setup python-interpreter settings ( platform.* sys.platform and co) so it matches the cross-target. Actually I ran into this issue while looking into emscripten/pyodide, which suffers exactly by this right now

  3. mattip commented on Aug 3, 2023

    @mattip
    Contributor

    For extension suffixes, there should be a way to expose the limited API name as well. xref this discussion on meson build, which resorts to using

    from importlib.machinery import EXTENSION_SUFFIXES
    limited_api_suffix = EXTENSION_SUFFIXES[1]
    
  4. FFY00 commented on Aug 14, 2023

    @FFY00
    MemberAuthor

    For extension suffixes, there should be a way to expose the limited API name as well.

    Yes. All the entries in importlib.machinery.all_extensions() would be provided by name in the API.

  5. sepehr-rs commented on May 20, 2026

    @sepehr-rs
    Contributor

    Hi! I’m interested in contributing to this issue.
    To help inform the design of the new sysconfig compilation API, I’ve spent some time researching how downstream tools (like maturin, setuptools, packaging, and cibuildwheel) currently interact with sysconfig. I’ve gathered two types of data:

    1. Information required to build extensions
      I went through several packaging tools and cataloged the sysconfig variables they use. I also found a curated list in maturin/sysconfig which I’ve cleaned up and organized into a table with labels for platforms, installation schemes, Python versions, and implementations. The attached table has two sections: variables curated by maturin, and additional ones I found manually.
      Because the resulting table is quite huge (over 1300 variables), I have uploaded it as a spreadsheet rather than embedding it here:
      Link to the spreadsheet

    2. Workarounds that could inform the API design
      2.1 Homebrew detection (_framework_compat.py in setuptools)

    @functools.lru_cache
    def enabled():
        """
        Only enabled for Python 3.9 framework homebrew builds
        except ensurepip and venv.
        """
        PY39 = (3, 9) < sys.version_info < (3, 10)
        framework = sys.platform == 'darwin' and sys._framework
        homebrew = "Cellar" in sysconfig.get_config_var('projectbase')
        venv = sys.prefix != sys.base_prefix
        ensurepip = os.environ.get("ENSUREPIP_OPTIONS")
        return PY39 and framework and homebrew and not venv and not ensurepip

    The API could directly expose the installation source (e.g., Homebrew) as a dedicated attribute, so tools no longer need to parse projectbase strings.

    2.2 Bundled information requiring string parsing
    Some sysconfig variables bundle multiple pieces of information together, forcing tools to parse them. For example:

    1. packaging parses EXT_SUFFIX. to extract ABI tags when SOABI is unavailable
    2. cibuildwheel parses LDCXXSHARED or LDSHARED to strip out LDFLAGS

    I think the new API could expose these as separate, atomic values (e.g., a standalone ABI tag, and split LDCXXSHARED / LDFLAGS variables) to eliminate fragile string parsing.

    2.3 Non-integer VERSION variable
    The VERSION variable can apparently be non-integer in some cases, causing issues (see test_build_scripts.py in setuptools). I think the new API should guarantee that this is always an integer.

    2.4 _d.pyd check vs Py_DEBUG
    Both setuptools and packaging use "_d.pyd" in EXTENSION_SUFFIXES instead of get_config_var('Py_DEBUG'). I might be missing context here, but is this something the API could address? Does it suggest Py_DEBUG is unreliable on Windows?

    2.5 Relocatable paths and host vs target prefixes
    cibuildwheel needs relocatable paths and a way to distinguish host from target prefixes, especially in cross-compilation. The new API could handle this by introducing explicit host_prefix and target_prefix properties, and by exposing paths relative to a configurable base so that relocation becomes straightforward. I’m new to this area, so I’d be interested to hear if this approach aligns with what others have in mind.

    2.6 Forcing sysconfig re-initialization
    cibuildwheel has to force re-initialization of sysconfig variables after platform changes (see _cross_venv.py). I believe that the new API could consider adding a native solution for this.

    2.7 Cross-compilation detection
    Both maturin and cibuildwheel need to detect when they’re running in a cross-compilation environment. I think the new API could provide an explicit is_cross_compiling flag so tools don’t have to rely on heuristic checks.

    Would love to hear thoughts on any of these, especially from folks with more experience in this area.

  6. zooba commented on May 20, 2026

    @zooba
    Member

    2.4 _d.pyd check vs Py_DEBUG

    This has been fixed already on newer versions. Until older versions are no longer supported, most tools won't change their code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions