python-peps/peps/pep-0739.rst

740 lines
17 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.0.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.0``)
* - Description
- Schema version.
This is a string following the format ``<MAJOR>.<MINOR>``, where
``<MAJOR>`` and ``<MINOR>`` are unpaded numbers and represent
the **major** and **minor** components of the version. Versions
may be arithmetic compared by intrepreting the version string as
a decimal number.
For this specification version, this value is constant and MUST
be ``1.0``.
Future versions of this schema MUST use a higher version number.
Future versions of this schema MUST NOT use the same **major**
version component as other schema version unless its
specification is deemed backwards-compatible with them — it
can't change, or extend, any parts of the current specification
in such a way as the semantics of the interpreted data differ,
or that data valid under the new specification is invalid under
the older specification, with the exception of additional
properties (errors caused by ``additionalProperties``).
* - 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.0.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.