From 430987f98a8fe96ae2c0385748ac8fd874b2c564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns=20=F0=9F=87=B5=F0=9F=87=B8?= Date: Thu, 12 Sep 2024 03:43:59 +0100 Subject: [PATCH] PEP 739: Update based on discussion feedback (#3954) --- peps/pep-0739.rst | 140 +++++++++++++----- peps/pep-0739/example.json | 24 +-- .../pep-0739/python-build-info-v1.schema.json | 56 +++---- 3 files changed, 141 insertions(+), 79 deletions(-) diff --git a/peps/pep-0739.rst b/peps/pep-0739.rst index b7e5516e0..aa99c6334 100644 --- a/peps/pep-0739.rst +++ b/peps/pep-0739.rst @@ -7,7 +7,7 @@ Status: Draft Type: Standards Track Topic: Packaging Created: 19-Dec-2023 -Python-Version: 3.13 +Python-Version: 3.14 Abstract @@ -30,16 +30,38 @@ This is helpful for use-cases such as cross-compilation, Python launchers, etc. Scope ===== -This PEP only defines a format. Python implementations may choose to include a -build details file as part of their distribution, but they are not required to, -and the specifics of how that may happen are out of scope for this PEP. +This PEP defines a format for the description file, and a standard location for +where to place it. -Specification -============= +Location +======== -The specification is defined by the JSON Schema definition provided below, which -is rendered in an human-readable format here. +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 @@ -70,8 +92,11 @@ is rendered in an human-readable format here. * - Type - ``string`` (constant — ``1``) * - Description - - Schema version. This is a constant value and MUST be ``1``. - Future iterations of this schema MUST update this value. + - 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** @@ -103,6 +128,8 @@ is rendered in an human-readable format here. - ``string`` * - Description - System platform string. + + This field SHOULD be equivalent to ``sysconfig.get_platform()``. * - Examples - - ``linux-x86_64`` - etc. @@ -139,8 +166,11 @@ is rendered in an human-readable format here. * - 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.13``, etc. + - ``3.14``, etc. * - Required - **True** @@ -156,8 +186,10 @@ is rendered in an human-readable format here. - Object containing details related to Python implementation. This section SHOULD be equivalent to - :py:data:`sys.implementation`, but only the ``name`` and - ``version`` keys are actually required to be present. + :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 @@ -264,8 +296,8 @@ is rendered in an human-readable format here. * - Description - Object containing details Python interpreter. - If the Python installation does not provide an interpreter, this - section will be missing. + This section MUST be present if the Python installation provides + an interpreter binary, otherwise this section will be missing. * - Required - **False** * - Additional properties @@ -281,7 +313,7 @@ is rendered in an human-readable format here. - ``string`` * - Description - The path to the Python interprer. Either an absolute path, or a - relative path to the path defined in the ``base`` key. + relative path to the path defined in the ``base_prefix`` key. * - Examples - - ``/usr/bin/python`` - ``bin/python`` @@ -319,7 +351,7 @@ is rendered in an human-readable format here. The flags MUST be defined in the order they appear on the extension suffix. * - Examples - - ``['d', 't']``, etc. + - ``['t', 'd']``, etc. * - Required - **True** @@ -334,8 +366,11 @@ is rendered in an human-readable format here. * - 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-313-x86_64-linux-gnu.so`` + - - ``.cpython-314-x86_64-linux-gnu.so`` - etc. * - Required - **True** @@ -350,6 +385,10 @@ is rendered in an human-readable format here. - ``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 @@ -365,6 +404,16 @@ is rendered in an human-readable format here. - ``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. @@ -384,8 +433,8 @@ is rendered in an human-readable format here. * - Description - Object containing details related to the ``libpython`` library. - If the Python installation does not provide a ``libpython`` - library, this section will be missing. + This section MUST by present if Python installation provides a + ``libpython`` library, otherwise this section will be missing. * - Required - **False** * - Additional properties @@ -400,15 +449,16 @@ is rendered in an human-readable format here. * - Type - ``string`` * - Description - - The path to the dynamic ``libpython`` library. + - The path to the dynamic ``libpython`` library. Either an + absolute path, or a relative path to the path defined in the + ``base_prefix`` key. - Either an absolute path, or a relative path to the path defined - in the ``base`` key.. If the Python installation does not - provide a dynamic ``libpython`` library, this entry will be + This field MUST be present if the Python installation provides a + dynamic ``libpython`` library, otherwise this entry will be missing. * - Examples - - - ``/usr/lib/libpython3.13.so.1.0`` - - ``lib/libpython3.13.so.1.0`` + - - ``/usr/lib/libpython3.14.so.1.0`` + - ``lib/libpython3.14.so.1.0`` - etc. * - Required - **False** @@ -422,15 +472,16 @@ is rendered in an human-readable format here. * - Type - ``string`` * - Description - - The path to the static ``libpython`` library. + - The path to the static ``libpython`` library. Either an absolute + path, or a relative path to the path defined in the + ``base_prefix`` key. - Either an absolute path, or a relative path to the path defined - in the ``base`` key.. If the Python installation does not - provide a static ``libpython`` library, this entry will be + This field MUST be present if the Python installation provides a + static ``libpython`` library, otherwise this entry will be missing. * - Examples - - - ``/usr/lib/python3.13/config-3.13-x86_64-linux-gnu/libpython3.13.a`` - - ``lib/python3.13/config-3.13-x86_64-linux-gnu/libpython3.13.a`` + - - ``/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** @@ -446,6 +497,10 @@ is rendered in an human-readable format here. * - 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** @@ -461,8 +516,8 @@ is rendered in an human-readable format here. - Object containing details related to the Python C API, if available. - If the Python implementation does not provide a C API, this - section will be missing. + This section MUST be present if the Python implementation + provides a C API, otherwise this section will be missing. * - Required - **False** * - Additional properties @@ -478,10 +533,10 @@ is rendered in an human-readable format here. - ``string`` * - Description - The path to the C API headers. Either an absolute path, or a - relative path to the path defined in the ``base`` key.. + relative path to the path defined in the ``base_prefix`` key. * - Examples - - - ``/usr/include/python3.13`` - - ``include/python3.13`` + - - ``/usr/include/python3.14`` + - ``include/python3.14`` - etc. * - Required - **True** @@ -496,8 +551,12 @@ is rendered in an human-readable format here. - ``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`` - key.. + 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`` @@ -518,6 +577,7 @@ is rendered in an human-readable format here. 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 @@ -552,7 +612,7 @@ 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 author that information regarding the Python environment should be +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. diff --git a/peps/pep-0739/example.json b/peps/pep-0739/example.json index 13830e913..1a3f7783c 100644 --- a/peps/pep-0739/example.json +++ b/peps/pep-0739/example.json @@ -3,27 +3,27 @@ "base_prefix": "/usr", "platform": "linux-x86_64", "language": { - "version": "3.13" + "version": "3.14" }, "implementation": { "name": "cpython", "version": { "major": 3, - "minor": 13, - "micro": 1, - "releaselevel": "final", + "minor": 14, + "micro": 0, + "releaselevel": "alpha", "serial": 0 }, - "hexversion": 51184112, - "cache_tag": "cpython-313", + "hexversion": 51249312, + "cache_tag": "cpython-314", "_multiarch": "x86_64-linux-gnu" }, "interpreter": { "path": "/usr/bin/python" }, "abi": { - "flags": ["d", "t"], - "extension_suffix": ".cpython-313-x86_64-linux-gnu.so", + "flags": ["t", "d"], + "extension_suffix": ".cpython-314-x86_64-linux-gnu.so", "stable_abi_suffix": ".abi3.so" }, "suffixes": { @@ -31,15 +31,15 @@ "bytecode": [".pyc"], "optimized_bytecode": [".pyc"], "debug_bytecode": [".pyc"], - "extensions": [".cpython-313-x86_64-linux-gnu.so", ".abi3.so", ".so"] + "extensions": [".cpython-314-x86_64-linux-gnu.so", ".abi3.so", ".so"] }, "libpython": { - "dynamic": "/usr/lib/libpython3.13.so.1.0", - "static": "/usr/lib/python3.13/config-3.13-x86_64-linux-gnu/libpython3.13.a", + "dynamic": "/usr/lib/libpython3.14.so.1.0", + "static": "/usr/lib/python3.14/config-3.14-x86_64-linux-gnu/libpython3.14.a", "link_to_libpython": true }, "c_api": { - "headers": "/usr/include/python3.13", + "headers": "/usr/include/python3.14", "pkgconfig_path": "/usr/lib/pkgconfig" } } diff --git a/peps/pep-0739/python-build-info-v1.schema.json b/peps/pep-0739/python-build-info-v1.schema.json index 8d8d3497a..b2944798c 100644 --- a/peps/pep-0739/python-build-info-v1.schema.json +++ b/peps/pep-0739/python-build-info-v1.schema.json @@ -13,7 +13,7 @@ "properties": { "schema_version": { "type": "string", - "description": "Schema version. This is a constant value and MUST be ``1``. Future iterations of this schema MUST update this value.", + "description": "Schema version.\n\nThis is a constant value and MUST be ``1``, when using the schema described here. Future iterations of this schema MUST update this value.", "const": "1" }, "base_prefix": { @@ -26,7 +26,7 @@ }, "platform": { "type": "string", - "description": "System platform string.", + "description": "System platform string.\n\nThis field SHOULD be equivalent to ``sysconfig.get_platform()``.", "examples": [ "linux-x86_64" ] @@ -41,17 +41,19 @@ "properties": { "version": { "type": "string", - "description": "String representation the Python language version — a version string consisting only of the *major* and *minor* components.", - "examples": ["3.13"] + "description": "String representation the Python language version — a version string consisting only of the *major* and *minor* components.\n\nThis field SHOULD be equivalent to ``sysconfig.get_python_version()``.", + "examples": ["3.14"] } } }, "implementation": { "type": "object", - "description": "Object containing details related to Python implementation.\n\nThis section SHOULD be equivalent to :py:data:`sys.implementation`, but only the ``name`` and ``version`` keys are actually required to be present.", + "description": "Object containing details related to Python implementation.\n\nThis 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": [ "name", - "version" + "version", + "hexversion", + "cache_tag" ], "additionalProperties": true, "properties": { @@ -104,7 +106,7 @@ }, "interpreter": { "type": "object", - "description": "Object containing details Python interpreter.\n\nIf the Python installation does not provide an interpreter, this section will be missing.", + "description": "Object containing details Python interpreter.\n\nThis section MUST be present if the Python installation provides an interpreter binary, otherwise this section will be missing.", "required": [ "path" ], @@ -112,7 +114,7 @@ "properties": { "path": { "type": "string", - "description": "The path to the Python interprer. Either an absolute path, or a relative path to the path defined in the ``base`` key.", + "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" @@ -134,19 +136,19 @@ "description": "Build configuration flags, used to calculate the extension suffix.\n\nThe flags MUST be defined in the order they appear on the extension suffix.", "additionalProperties": true, "examples": [ - ["d", "t"] + ["t", "d"] ] }, "extension_suffix": { "type": "string", - "description": "Suffix used for extensions built against the current implementation version.", + "description": "Suffix used for extensions built against the current implementation version.\n\nThis field MUST be present if the Python implementation supports extensions, otherwise this entry will be missing.", "examples": [ - ".cpython-313-x86_64-linux-gnu.so" + ".cpython-314-x86_64-linux-gnu.so" ] }, "stable_abi_suffix": { "type": "string", - "description": "Suffix used for extensions built against the stable ABI.", + "description": "Suffix used for extensions built against the stable ABI.\n\nThis field MUST be present if the Python implementation has a stable ABI extension suffix, otherwise this entry will be missing.", "examples": [ ".abi3.so" ] @@ -155,7 +157,7 @@ }, "suffixes": { "type": "object", - "description": "Valid module suffixes grouped by type.", + "description": "Valid module suffixes grouped by type.\n\nThis 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"], @@ -168,34 +170,34 @@ }, "libpython": { "type": "object", - "description": "Object containing details related to the ``libpython`` library.\n\nIf the Python installation does not provide a ``libpython`` library, this section will be missing.", + "description": "Object containing details related to the ``libpython`` library.\n\nThis section MUST by present if Python installation provides a ``libpython`` library, otherwise this section will be missing.", "additionalProperties": false, "properties": { "dynamic": { "type": "string", - "description": "The path to the dynamic ``libpython`` library.\n\nEither an absolute path, or a relative path to the path defined in the ``base`` key.. If the Python installation does not provide a dynamic ``libpython`` library, this entry will be missing.", + "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.\n\nThis field MUST be present if the Python installation provides a dynamic ``libpython`` library, otherwise this entry will be missing.", "examples": [ - "/usr/lib/libpython3.13.so.1.0", - "lib/libpython3.13.so.1.0" + "/usr/lib/libpython3.14.so.1.0", + "lib/libpython3.14.so.1.0" ] }, "static": { "type": "string", - "description": "The path to the static ``libpython`` library.\n\nEither an absolute path, or a relative path to the path defined in the ``base`` key.. If the Python installation does not provide a static ``libpython`` library, this entry will be missing.", + "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.\n\nThis field MUST be present if the Python installation provides a static ``libpython`` library, otherwise this entry will be missing.", "examples": [ - "/usr/lib/python3.13/config-3.13-x86_64-linux-gnu/libpython3.13.a", - "lib/python3.13/config-3.13-x86_64-linux-gnu/libpython3.13.a" + "/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" ] }, "link_to_libpython": { "type": "boolean", - "description": "Should extensions built against a dynamic ``libpython`` link to it?" + "description": "Should extensions built against a dynamic ``libpython`` link to it?\n\nThis field MUST be present if the Python installation provides a dynamic ``libpython`` library, otherwise this entry will be missing." } } }, "c_api": { "type": "object", - "description": "Object containing details related to the Python C API, if available.\n\nIf the Python implementation does not provide a C API, this section will be missing.", + "description": "Object containing details related to the Python C API, if available.\n\nThis section MUST be present if the Python implementation provides a C API, otherwise this section will be missing.", "required": [ "headers" ], @@ -203,15 +205,15 @@ "properties": { "headers": { "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`` key..", + "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.13", - "include/python3.13" + "/usr/include/python3.14", + "include/python3.14" ] }, "pkgconfig_path": { "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`` key..", + "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.\n\nThis 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" @@ -221,7 +223,7 @@ }, "arbitrary_data": { "type": "object", - "description": "Object containing extra arbitrary data.\n\nThis is meant to be used as an escape-hatch, to include any relevant data that is not covered by this specification.", + "description": "Object containing extra arbitrary data.\n\nThis 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.", "additionalProperties": true } }