PEP: 739 Title: Static description file for build details of Python installations Author: Filipe Laíns PEP-Delegate: Paul Moore Discussions-To: https://discuss.python.org/t/pep-739-static-description-file-for-build-details-of-python-installations/44572 Status: Draft Type: Standards Track Topic: Packaging Created: 19-Dec-2023 Python-Version: 3.14 Abstract ======== Introduce a standard format for a static description file with build details of Python installations. Rationale ========= When introspecting a Python installation, running code is often undesirable or impossible. Having a static description file makes various of Python build details available without having to run the interpreter. This is helpful for use-cases such as cross-compilation, Python launchers, etc. Scope ===== This PEP defines a format for the description file, and a standard location for where to place it. Location ======== When possible, Python installations should install the static description file inside the standard library directory, with the name ``build-details.json`` (Eg. ``/usr/lib/python3.14/build-details.json``). .. important:: Given that there may be technical challenges, Python implementations are not required to provide the file if not feasable. In such scenarios, they may choose to provide it in a different maner. .. attention:: Notwithstanding the standard location specified here, it does not prevent the file from **additionally** being provided in another location, and with a different name. In fact, the PEP authors expect future PEPs to define additional locations to install this file, for better discoverability. Format ====== The format specification is defined by the JSON Schema definition provided below, which is rendered in an human-readable format here. .. Rendered with https://gist.github.com/FFY00/eb02d9da2870aae547bc579b7e17a145 .. _spec-start: .. list-table:: :widths: 25 75 * - ``$schema`` - https://json-schema.org/draft/2020-12/schema * - ``$id`` - https://github.com/python/peps/blob/main/peps/pep-0739/python-build-info-v1.schema.json * - Title - Static description file for the build details of Python installations * - Type - ``object`` * - Additional properties - **Not allowed** ``schema_version`` ------------------ .. list-table:: :widths: 25 75 * - Type - ``string`` (constant — ``1``) * - Description - Schema version. This is a constant value and MUST be ``1``, when using the schema described here. Future iterations of this schema MUST update this value. * - Required - **True** ``base_prefix`` --------------- .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - Base prefix of the Python installation. Either an absolute path, or a relative path to directory where this file is contained. * - Examples - ``/usr``, ``../..``, etc. * - Required - **False** ``platform`` ------------ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - System platform string. This field SHOULD be equivalent to ``sysconfig.get_platform()``. * - Examples - - ``linux-x86_64`` - etc. * - Required - **True** ``language`` ------------ .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details related to the Python language specification. In addition to the required keys, implementations may choose to include extra keys with implementation-specific details. * - Required - **True** * - Additional properties - **Not allowed** ``language.version`` ~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - String representation the Python language version — a version string consisting only of the *major* and *minor* components. This field SHOULD be equivalent to ``sysconfig.get_python_version()``. * - Examples - ``3.14``, etc. * - Required - **True** ``implementation`` ------------------ .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details related to Python implementation. This section SHOULD be equivalent to :py:data:`sys.implementation`. It follows specification defined in PEP 421, meaning that on top of the required keys, implementation-specific keys can also exist, but must be prefixed with an underscore. * - Required - **True** * - Additional properties - **Allowed** ``implementation.name`` ~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - Lower-case name of the Python implementation. * - Examples - ``cpython``, ``pypy``, etc. * - Required - **True** ``implementation.version`` ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object in the format of :py:data:`sys.version_info`, containing the implementation version. * - Examples - - ``{'major': 3, 'minor': 13, 'micro': 1, 'releaselevel': 'final', 'serial': 0}`` - ``{'major': 7, 'minor': 3, 'micro': 16, 'releaselevel': 'final', 'serial': 0}`` - etc. * - Required - **True** * - Additional properties - **Not allowed** ``implementation.version.major`` ++++++++++++++++++++++++++++++++ .. list-table:: :widths: 25 75 * - Type - ``number`` * - Required - **True** ``implementation.version.minor`` ++++++++++++++++++++++++++++++++ .. list-table:: :widths: 25 75 * - Type - ``number`` * - Required - **True** ``implementation.version.micro`` ++++++++++++++++++++++++++++++++ .. list-table:: :widths: 25 75 * - Type - ``number`` * - Required - **True** ``implementation.version.releaselevel`` +++++++++++++++++++++++++++++++++++++++ .. list-table:: :widths: 25 75 * - Type - ``string`` (enum — ``alpha``, ``beta``, ``candidate``, ``final``) * - Required - **True** ``implementation.version.serial`` +++++++++++++++++++++++++++++++++ .. list-table:: :widths: 25 75 * - Type - ``number`` * - Required - **True** ``interpreter`` --------------- .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details Python interpreter. This section MUST be present if the Python installation provides an interpreter binary, otherwise this section will be missing. * - Required - **False** * - Additional properties - **Not allowed** ``interpreter.path`` ~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - The path to the Python interprer. Either an absolute path, or a relative path to the path defined in the ``base_prefix`` key. * - Examples - - ``/usr/bin/python`` - ``bin/python`` - etc. * - Required - **True** ``abi`` ------- .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details related to ABI. * - Required - **False** * - Additional properties - **Not allowed** ``abi.flags`` ~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``array`` * - Description - Build configuration flags, used to calculate the extension suffix. The flags MUST be defined in the order they appear on the extension suffix. * - Examples - ``['t', 'd']``, etc. * - Required - **True** ``abi.extension_suffix`` ~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - Suffix used for extensions built against the current implementation version. This field MUST be present if the Python implementation supports extensions, otherwise this entry will be missing. * - Examples - - ``.cpython-314-x86_64-linux-gnu.so`` - etc. * - Required - **True** ``abi.stable_abi_suffix`` ~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - Suffix used for extensions built against the stable ABI. This field MUST be present if the Python implementation has a stable ABI extension suffix, otherwise this entry will be missing. * - Examples - ``.abi3.so``, etc. * - Required - **False** ``suffixes`` ------------ .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Valid module suffixes grouped by type. This section SHOULD be equivalent to the ``importlib.machinery.*_SUFFIXES`` attributes, if the implementation provides such suffixes. However, if the Python implementation does not provide suffixes of the kind specified by any of the attributes, the equivalent sub-section is not required to be present. Additionally, if a Python implementation provides extension kinds other than the ones listed on ``importlib.machinery`` module, they MAY add a sub-section for them. * - Examples - - ``{'source': ['.py'], 'bytecode': ['.pyc'], 'optimized_bytecode': ['.pyc'], 'debug_bytecode': ['.pyc'], 'extensions': ['.cpython-313-x86_64-linux-gnu.so', '.abi3.so', '.so']}`` - etc. * - Required - **False** * - Additional properties - **Allowed** ``libpython`` ------------- .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details related to the ``libpython`` library. This section MUST by present if Python installation provides a ``libpython`` library, otherwise this section will be missing. * - Required - **False** * - Additional properties - **Not allowed** ``libpython.dynamic`` ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - The path to the dynamic ``libpython`` library. Either an absolute path, or a relative path to the path defined in the ``base_prefix`` key. This field MUST be present if the Python installation provides a dynamic ``libpython`` library, otherwise this entry will be missing. * - Examples - - ``/usr/lib/libpython3.14.so.1.0`` - ``lib/libpython3.14.so.1.0`` - etc. * - Required - **False** ``libpython.static`` ~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - The path to the static ``libpython`` library. Either an absolute path, or a relative path to the path defined in the ``base_prefix`` key. This field MUST be present if the Python installation provides a static ``libpython`` library, otherwise this entry will be missing. * - Examples - - ``/usr/lib/python3.14/config-3.14-x86_64-linux-gnu/libpython3.14.a`` - ``lib/python3.14/config-3.14-x86_64-linux-gnu/libpython3.14.a`` - etc. * - Required - **False** ``libpython.link_to_libpython`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``boolean`` * - Description - Should extensions built against a dynamic ``libpython`` link to it? This field MUST be present if the Python installation provides a dynamic ``libpython`` library, otherwise this entry will be missing. * - Required - **False** ``c_api`` --------- .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing details related to the Python C API, if available. This section MUST be present if the Python implementation provides a C API, otherwise this section will be missing. * - Required - **False** * - Additional properties - **Not allowed** ``c_api.headers`` ~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - The path to the C API headers. Either an absolute path, or a relative path to the path defined in the ``base_prefix`` key. * - Examples - - ``/usr/include/python3.14`` - ``include/python3.14`` - etc. * - Required - **True** ``c_api.pkgconfig_path`` ~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 25 75 * - Type - ``string`` * - Description - The path to the pkg-config definition files. Either an absolute path, or a relative path to the path defined in the ``base_prefix`` key. This field MUST be present if the Python implementation provides pkg-config definition files for the C API, otherwise this section will be missing. * - Examples - - ``/usr/lib/pkgconfig`` - ``lib/pkgconfig`` - etc. * - Required - **False** ``arbitrary_data`` ------------------ .. list-table:: :widths: 25 75 * - Type - ``object`` * - Description - Object containing extra arbitrary data. This is meant to be used as an escape-hatch, to include any relevant data that is not covered by this specification. Implamentations may choose what data to provide in this section. * - Required - **False** * - Additional properties - **Allowed** .. _spec-end: Example ======= .. literalinclude:: pep-0739/example.json :language: json :linenos: JSON Schema =========== .. literalinclude:: pep-0739/python-build-info-v1.schema.json :language: json :linenos: Rejected Ideas ============== Having a larger scope --------------------- One of the main requests in the discussion of this PEP was the inclusion of other kind of information, such as the ``site-packages`` path. It is the opinion of the PEP authors that information regarding the Python environment should be provided by a separate file, creating the a clear separation between the build details, which should be immutable across any interpreter instance, and details that can change, such as environment details. Copyright ========= This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.