725 lines
16 KiB
ReStructuredText
725 lines
16 KiB
ReStructuredText
PEP: 739
|
|
Title: Static description file for build details of Python installations
|
|
Author: Filipe Laíns <lains@riseup.net>
|
|
PEP-Delegate: Paul Moore <p.f.moore@gmail.com>
|
|
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**
|
|
|
|
``language.version_info``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``object``
|
|
* - Description
|
|
- Object in the format of :py:data:`sys.version_info`.
|
|
|
|
This section SHOULD be equivalent to
|
|
:py:data:`sys.version_info`.
|
|
* - Examples
|
|
- - ``{'major': 3, 'minor': 14, 'micro': 1, 'releaselevel': 'final', 'serial': 0}``
|
|
- etc.
|
|
* - Required
|
|
- **False**
|
|
* - Additional properties
|
|
- **Not allowed**
|
|
|
|
``language.version_info.major``
|
|
+++++++++++++++++++++++++++++++
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``number``
|
|
* - Required
|
|
- **True**
|
|
|
|
``language.version_info.minor``
|
|
+++++++++++++++++++++++++++++++
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``number``
|
|
* - Required
|
|
- **True**
|
|
|
|
``language.version_info.micro``
|
|
+++++++++++++++++++++++++++++++
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``number``
|
|
* - Required
|
|
- **True**
|
|
|
|
``language.version_info.releaselevel``
|
|
++++++++++++++++++++++++++++++++++++++
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``string`` (enum — ``alpha``, ``beta``, ``candidate``, ``final``)
|
|
* - Required
|
|
- **True**
|
|
|
|
``language.version_info.serial``
|
|
++++++++++++++++++++++++++++++++
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``number``
|
|
* - 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': 14, '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.dynamic_stableabi``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. list-table::
|
|
:widths: 25 75
|
|
|
|
* - Type
|
|
- ``string``
|
|
* - Description
|
|
- The path to the dynamic ``libpython`` library for the stable
|
|
ABI. 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.so``
|
|
- ``lib/libpython3.so``
|
|
- 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.
|