From 7728f8732d544034c831183240826f7fd790128f Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 17:38:18 +1000 Subject: [PATCH 01/15] Add notes on runtime version access Also redirects the obsolete single-source version guide to the updated single-source version discussion. --- source/discussions/single-source-version.rst | 32 ++-- source/discussions/versioning.rst | 44 ++++- source/guides/section-build-and-publish.rst | 1 - .../single-sourcing-package-version.rst | 175 +----------------- source/guides/writing-pyproject-toml.rst | 4 +- 5 files changed, 70 insertions(+), 186 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 9bcab6291..7cc3a3c5a 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -1,31 +1,39 @@ -.. _`Single sourcing the version discussion`: +.. _single-source-version: =================================== Single-sourcing the Project Version =================================== :Page Status: Complete -:Last Reviewed: 2024-08-24 +:Last Reviewed: 2024-10-02 -One of the challenges in building packages is that the version string can be required in multiple places. +Many Python :ref:`distribution packages ` publish a single +Python :ref:`import package ` where it is desired that the runtime +``__version__`` attribute on the import package report the same version specifier +as :func:`importlib.metadata.version` reports for the distribution package +(as described in :ref:`runtime-version-access`). -* It needs to be specified when building the package (e.g. in :file:`pyproject.toml`) - This will make it available in the installed package’s metadata, from where it will be accessible at runtime using ``importlib.metadata.version("distribution_name")``. +It is also frequently desired that this version information be derived from a version +control system *tag* (such as ``v1.2.3``) rather than being manually updated in the +source code. -* A package may set a module attribute (e.g., ``__version__``) to provide an alternative means of runtime access to the version of the imported package. If this is done, the value of the attribute and that used by the build system to set the distribution's version should be kept in sync in :ref:`the build systems's recommended way `. +To ensure that version numbers do not get out of sync, it may be sufficient to add +an automated test case that ensure ``package.__version__`` and +``importlib.metadata.version("package")`` report the same value. -* If the code is in in a version control system (VCS), e.g. Git, the version may appear in a *tag* such as ``v1.2.3``. - -To ensure that version numbers do not get out of sync, it is recommended that there is a single source of truth for the version number. +Alternatively, a project's chosen build system mar offer a way to define a single +source of truth for the version number. In general, the options are: 1) If the code is in a version control system (VCS), e.g. Git, then the version can be extracted from the VCS. -2) The version can be hard-coded into the :file:`pyproject.toml` file -- and the build system can copy it into other locations it may be required. - -3) The version string can be hard-coded into the source code -- either in a special purpose file, such as :file:`_version.txt`, or as a attribute in a module, such as :file:`__init__.py`, and the build system can extract it at build time. +2) The version can be hard-coded into the :file:`pyproject.toml` file -- and the build system can copy it + into other locations it may be required. +3) The version string can be hard-coded into the source code -- either in a special purpose file, + such as :file:`_version.txt`, or as an attribute in a module, such as :file:`__init__.py`, and the build + system can extract it at build time. Consult your build system's documentation for their recommended method. diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 49fbbf0de..530db323a 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -153,7 +153,6 @@ numbering scheme that readily conveys the approximate age of a release, but doesn't otherwise commit to a particular release cadence within the year. - Local version identifiers ========================= @@ -172,6 +171,49 @@ since the latest release, setuptools-scm generates a version like "0.5.dev1+gd00980f", or if the repository has untracked changes, like "0.5.dev1+gd00980f.d20231217". +.. _runtime-version-access: + +Accessing version information at runtime +======================================== + +Version information for all :ref:`distribution packages ` +that are locally available in the current environment can be obtained at runtime +using the standard library's :func:`importlib.metadata.version` function:: + + >>> importlib.metadata.version("pip") + '23.3.2' + +Many libraries also choose to version their top level +:ref:`import packages ` by providing a package level +``__version__`` attribute:: + + >>> import pip + >>> pip.__version__ + '23.3.2' + +Import packages are *not* required to be versioned independently of their +distibution package version information (see the rejected proposal in +:pep:`PEP 396 <396>`), so this approach to retrieving runtime version +information should only be used with libraries that are known to provide it. + +Library publishers wishing to ensure their reported distribution package and +import package versions are consistent with each other can review the +:ref:`single-source-version` discussion for potential approaches to doing so. + +Some libraries may need to publish version information for external APIs +that don't meet the requirements for Python distribution package +:ref:`version specifiers `. Such libraries should +define their own library-specific ways of obtaining the relevant information +at runtime. For example, the standard library's :mod:`ssl` module offers +multiple ways to access the underlying OpenSSL library version:: + + >>> ssl.OPENSSL_VERSION + 'OpenSSL 3.2.2 4 Jun 2024' + >>> ssl.OPENSSL_VERSION_INFO + (3, 2, 0, 2, 0) + >>> ssl.OPENSSL_VERSION_NUMBER + 807403552 + -------------------------------------------------------------------------------- diff --git a/source/guides/section-build-and-publish.rst b/source/guides/section-build-and-publish.rst index 8e0c9ab3b..eb10c389f 100644 --- a/source/guides/section-build-and-publish.rst +++ b/source/guides/section-build-and-publish.rst @@ -7,7 +7,6 @@ Building and Publishing writing-pyproject-toml distributing-packages-using-setuptools - single-sourcing-package-version dropping-older-python-versions packaging-binary-extensions packaging-namespace-packages diff --git a/source/guides/single-sourcing-package-version.rst b/source/guides/single-sourcing-package-version.rst index 5c8af21e0..52fd5011a 100644 --- a/source/guides/single-sourcing-package-version.rst +++ b/source/guides/single-sourcing-package-version.rst @@ -1,173 +1,8 @@ -.. _`Single sourcing the version`: +:orphan: -=================================== -Single-sourcing the package version -=================================== +.. meta:: + :http-equiv=refresh: 0; url=../discussions/single-source-version/ -.. todo:: Update this page for build backends other than setuptools. +Redirecting stale single-source package version link... -There are many techniques to maintain a single source of truth for the version -number of your project: - -#. Read the file in :file:`setup.py` and get the version. Example (from `pip setup.py - `_):: - - import codecs - import os.path - - def read(rel_path): - here = os.path.abspath(os.path.dirname(__file__)) - with codecs.open(os.path.join(here, rel_path), 'r') as fp: - return fp.read() - - def get_version(rel_path): - for line in read(rel_path).splitlines(): - if line.startswith('__version__'): - delim = '"' if '"' in line else "'" - return line.split(delim)[1] - else: - raise RuntimeError("Unable to find version string.") - - setup( - ... - version=get_version("package/__init__.py") - ... - ) - - .. note:: - - As of the release of setuptools 46.4.0, one can accomplish the same - thing by instead placing the following in the project's - :file:`setup.cfg` file (replacing "package" with the import name of the - package): - - .. code-block:: ini - - [metadata] - version = attr: package.__version__ - - As of the release of setuptools 61.0.0, one can specify the - version dynamically in the project's :file:`pyproject.toml` file. - - .. code-block:: toml - - [project] - name = "package" - dynamic = ["version"] - - [tool.setuptools.dynamic] - version = {attr = "package.__version__"} - - Please be aware that declarative config indicators, including the - ``attr:`` directive, are not supported in parameters to - :file:`setup.py`. - -#. Use an external build tool that either manages updating both locations, or - offers an API that both locations can use. - - Few tools you could use, in no particular order, and not necessarily complete: - `bump2version `_, - `changes `_, - `commitizen `_, - `zest.releaser `_. - - -#. Set the value to a ``__version__`` global variable in a dedicated module in - your project (e.g. :file:`version.py`), then have :file:`setup.py` read and - ``exec`` the value into a variable. - - :: - - version = {} - with open("...sample/version.py") as fp: - exec(fp.read(), version) - # later on we use: version['__version__'] - - Example using this technique: `warehouse `_. - -#. Place the value in a simple ``VERSION`` text file and have both - :file:`setup.py` and the project code read it. - - :: - - with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file: - version = version_file.read().strip() - - An advantage with this technique is that it's not specific to Python. Any - tool can read the version. - - .. warning:: - - With this approach you must make sure that the ``VERSION`` file is included in - all your source and binary distributions (e.g. add ``include VERSION`` to your - :file:`MANIFEST.in`). - -#. Set the value in :file:`setup.py`, and have the project code use the - ``importlib.metadata`` API to fetch the value at runtime. - (``importlib.metadata`` was introduced in Python 3.8 and is available to - older versions as the ``importlib-metadata`` project.) An installed - project's version can be fetched with the API as follows:: - - import sys - - if sys.version_info >= (3, 8): - from importlib import metadata - else: - import importlib_metadata as metadata - - assert metadata.version('pip') == '1.2.0' - - Be aware that the ``importlib.metadata`` API only knows about what's in the - installation metadata, which is not necessarily the code that's currently - imported. - - If a project uses this method to fetch its version at runtime, then its - ``install_requires`` value needs to be edited to install - ``importlib-metadata`` on pre-3.8 versions of Python like so:: - - setup( - ... - install_requires=[ - ... - 'importlib-metadata >= 1.0 ; python_version < "3.8"', - ... - ], - ... - ) - - An older (and less efficient) alternative to ``importlib.metadata`` is the - ``pkg_resources`` API provided by ``setuptools``:: - - import pkg_resources - assert pkg_resources.get_distribution('pip').version == '1.2.0' - - If a project uses ``pkg_resources`` to fetch its own version at runtime, - then ``setuptools`` must be added to the project's ``install_requires`` - list. - - Example using this technique: `setuptools `_. - - -#. Set the value to ``__version__`` in ``sample/__init__.py`` and import - ``sample`` in :file:`setup.py`. - - :: - - import sample - setup( - ... - version=sample.__version__ - ... - ) - - .. warning:: - - Although this technique is common, beware that it will fail if - ``sample/__init__.py`` imports packages from ``install_requires`` - dependencies, which will very likely not be installed yet when - :file:`setup.py` is run. - - -#. Keep the version number in the tags of a version control system (Git, Mercurial, etc) - instead of in the code, and automatically extract it from there using - `setuptools_scm `_. +If the page doesn't automatically refresh, click :ref:`here `. diff --git a/source/guides/writing-pyproject-toml.rst b/source/guides/writing-pyproject-toml.rst index d11b8a87c..144cc3525 100644 --- a/source/guides/writing-pyproject-toml.rst +++ b/source/guides/writing-pyproject-toml.rst @@ -163,8 +163,8 @@ This field is required, although it is often marked as dynamic using dynamic = ["version"] This allows use cases such as filling the version from a ``__version__`` -attribute or a Git tag. Consult :ref:`Single sourcing the version` for more -details. +attribute or a Git tag. Consult the :ref:`single-source-version` +discussion for more details. Dependencies and requirements From c51c08de197d124df821fc5dd893fc89618274b0 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 17:50:04 +1000 Subject: [PATCH 02/15] Fix typo --- source/discussions/versioning.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 530db323a..1fe0dcf4a 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -192,7 +192,7 @@ Many libraries also choose to version their top level '23.3.2' Import packages are *not* required to be versioned independently of their -distibution package version information (see the rejected proposal in +distribution package version information (see the rejected proposal in :pep:`PEP 396 <396>`), so this approach to retrieving runtime version information should only be used with libraries that are known to provide it. From be8b0d8114fa8f8cf538625d0c0649955830a350 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 17:51:52 +1000 Subject: [PATCH 03/15] Attempt to fix relative link --- source/guides/single-sourcing-package-version.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/guides/single-sourcing-package-version.rst b/source/guides/single-sourcing-package-version.rst index 52fd5011a..bed21285f 100644 --- a/source/guides/single-sourcing-package-version.rst +++ b/source/guides/single-sourcing-package-version.rst @@ -1,7 +1,7 @@ :orphan: .. meta:: - :http-equiv=refresh: 0; url=../discussions/single-source-version/ + :http-equiv=refresh: 0; url=../../discussions/single-source-version/ Redirecting stale single-source package version link... From ca1a74cd6add5b27c76172c016eaf7fb95fdf528 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 17:58:42 +1000 Subject: [PATCH 04/15] Reference glossary terms --- source/discussions/single-source-version.rst | 4 ++-- source/discussions/versioning.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 7cc3a3c5a..3c491a028 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -7,8 +7,8 @@ Single-sourcing the Project Version :Page Status: Complete :Last Reviewed: 2024-10-02 -Many Python :ref:`distribution packages ` publish a single -Python :ref:`import package ` where it is desired that the runtime +Many Python :term:`distribution packages ` publish a single +Python :term:`import package ` where it is desired that the runtime ``__version__`` attribute on the import package report the same version specifier as :func:`importlib.metadata.version` reports for the distribution package (as described in :ref:`runtime-version-access`). diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 1fe0dcf4a..c6a33ffdd 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -176,7 +176,7 @@ since the latest release, setuptools-scm generates a version like Accessing version information at runtime ======================================== -Version information for all :ref:`distribution packages ` +Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime using the standard library's :func:`importlib.metadata.version` function:: @@ -184,7 +184,7 @@ using the standard library's :func:`importlib.metadata.version` function:: '23.3.2' Many libraries also choose to version their top level -:ref:`import packages ` by providing a package level +:term:`import packages ` by providing a package level ``__version__`` attribute:: >>> import pip From 17c0ac028ffbabf15bd7c2975c2177a5b6e3889d Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 18:02:12 +1000 Subject: [PATCH 05/15] Handle missing stdlib function ref --- source/discussions/single-source-version.rst | 2 +- source/discussions/versioning.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 3c491a028..ab7daa1ce 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -10,7 +10,7 @@ Single-sourcing the Project Version Many Python :term:`distribution packages ` publish a single Python :term:`import package ` where it is desired that the runtime ``__version__`` attribute on the import package report the same version specifier -as :func:`importlib.metadata.version` reports for the distribution package +as ``importlib.metadata.version`` reports for the distribution package (as described in :ref:`runtime-version-access`). It is also frequently desired that this version information be derived from a version diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index c6a33ffdd..c5158d961 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -178,7 +178,7 @@ Accessing version information at runtime Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime -using the standard library's :func:`importlib.metadata.version` function:: +using the standard library's ``importlib.metadata.version`` function:: >>> importlib.metadata.version("pip") '23.3.2' From 0d76de300bbbd4533bd7d4b16491fcea09853cb9 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 21:39:25 +1000 Subject: [PATCH 06/15] Add co-author attribution wim glenn : From 306a92a1f42b1d3f38a3a9266ce7b7fb60618d5e Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Sun, 6 Oct 2024 22:04:28 +1000 Subject: [PATCH 07/15] Fix typos --- source/discussions/single-source-version.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index ab7daa1ce..362e765be 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -18,10 +18,10 @@ control system *tag* (such as ``v1.2.3``) rather than being manually updated in source code. To ensure that version numbers do not get out of sync, it may be sufficient to add -an automated test case that ensure ``package.__version__`` and +an automated test case that ensures ``package.__version__`` and ``importlib.metadata.version("package")`` report the same value. -Alternatively, a project's chosen build system mar offer a way to define a single +Alternatively, a project's chosen build system may offer a way to define a single source of truth for the version number. In general, the options are: From f8aa29b7885f1234e3317f6a3f95182ccd5dda85 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 16:34:20 +1000 Subject: [PATCH 08/15] Use more descriptive link text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éric --- source/guides/single-sourcing-package-version.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/guides/single-sourcing-package-version.rst b/source/guides/single-sourcing-package-version.rst index bed21285f..7ed3d87da 100644 --- a/source/guides/single-sourcing-package-version.rst +++ b/source/guides/single-sourcing-package-version.rst @@ -5,4 +5,4 @@ Redirecting stale single-source package version link... -If the page doesn't automatically refresh, click :ref:`here `. +If the page doesn't automatically refresh, see :ref:`single-source-version`. From 040025188351fb3cd1d833fad3819f8b22beabe5 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:23:35 +1000 Subject: [PATCH 09/15] Misc edits * address review comments * go back to semantic cross-references (the build will fail until the CPython PR and its backports land, but that's OK) --- source/discussions/single-source-version.rst | 21 ++++++--- source/discussions/versioning.rst | 46 +++++++++++++------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 362e765be..9fafa433b 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -10,33 +10,40 @@ Single-sourcing the Project Version Many Python :term:`distribution packages ` publish a single Python :term:`import package ` where it is desired that the runtime ``__version__`` attribute on the import package report the same version specifier -as ``importlib.metadata.version`` reports for the distribution package +as :func:`importlib.metadata.version` reports for the distribution package (as described in :ref:`runtime-version-access`). It is also frequently desired that this version information be derived from a version control system *tag* (such as ``v1.2.3``) rather than being manually updated in the source code. -To ensure that version numbers do not get out of sync, it may be sufficient to add -an automated test case that ensures ``package.__version__`` and -``importlib.metadata.version("package")`` report the same value. +Some projects may choose to simply live with the data entry duplication, and rely +on automated testing to ensure the different values do not diverge. Alternatively, a project's chosen build system may offer a way to define a single source of truth for the version number. In general, the options are: -1) If the code is in a version control system (VCS), e.g. Git, then the version can be extracted from the VCS. +1) If the code is in a version control system (VCS), such as Git, then the version can be extracted from the VCS. 2) The version can be hard-coded into the :file:`pyproject.toml` file -- and the build system can copy it into other locations it may be required. 3) The version string can be hard-coded into the source code -- either in a special purpose file, - such as :file:`_version.txt`, or as an attribute in a module, such as :file:`__init__.py`, and the build - system can extract it at build time. + such as :file:`_version.txt` (which must then be shipped as part of the project's source distribution + package), or as an attribute in a particular module, such as :file:`__init__.py`. The build + system can then extract it from the runtime location at build time. Consult your build system's documentation for their recommended method. +When the intention is that a distribution package and its associated import package +share the same version, it is recommended that the project include an automated test +case that ensures ``import_name.__version__`` and ``importlib.metadata.version("dist-name")`` +report the same value (note: for many projects, ``import_name`` and ``dist-name`` will +be the same name). + + .. _Build system version handling: Build System Version Handling diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index c5158d961..9ecba5d03 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -178,32 +178,38 @@ Accessing version information at runtime Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime -using the standard library's ``importlib.metadata.version`` function:: +using the standard library's :func:`importlib.metadata.version` function:: >>> importlib.metadata.version("pip") '23.3.2' -Many libraries also choose to version their top level +Many projects also choose to version their top level :term:`import packages ` by providing a package level ``__version__`` attribute:: - >>> import pip - >>> pip.__version__ - '23.3.2' + >>> import cryptography + >>> cryptography.__version__ + '41.0.7' -Import packages are *not* required to be versioned independently of their -distribution package version information (see the rejected proposal in -:pep:`PEP 396 <396>`), so this approach to retrieving runtime version -information should only be used with libraries that are known to provide it. +This technique can be particularly valuable for CLI applications which want +to ensure that version query invocations (such as ``pip -V``) run as quickly +as possible. -Library publishers wishing to ensure their reported distribution package and +Package publishers wishing to ensure their reported distribution package and import package versions are consistent with each other can review the :ref:`single-source-version` discussion for potential approaches to doing so. -Some libraries may need to publish version information for external APIs +However, as import packages and modules are not *required* to publish runtime +version information in this way (see the rejected proposal in +:pep:`PEP 396 <396>`), the ``__version__`` attribute should either only be +queried with interfaces that are known to provide it, or else the querying +code should be designed to handle the case where the attribute is missing +[#fallback-to-dist-version]_. + +Some projects may need to publish version information for external APIs that don't meet the requirements for Python distribution package -:ref:`version specifiers `. Such libraries should -define their own library-specific ways of obtaining the relevant information +:ref:`version specifiers `. Such projects should +define their own project-specific ways of obtaining the relevant information at runtime. For example, the standard library's :mod:`ssl` module offers multiple ways to access the underlying OpenSSL library version:: @@ -211,9 +217,8 @@ multiple ways to access the underlying OpenSSL library version:: 'OpenSSL 3.2.2 4 Jun 2024' >>> ssl.OPENSSL_VERSION_INFO (3, 2, 0, 2, 0) - >>> ssl.OPENSSL_VERSION_NUMBER - 807403552 - + >>> hex(ssl.OPENSSL_VERSION_NUMBER) + '0x30200020' -------------------------------------------------------------------------------- @@ -226,6 +231,15 @@ multiple ways to access the underlying OpenSSL library version:: Brett Cannon `_. For a humoristic take, read about ZeroVer_. +.. [#fallback-to-dist-version] A full list mapping the top level names available + for import to the distribution packages that provide those import packages and + modules may be obtained through the standard library's + :func:`importlib.metadata.packages_distributions` function. This means that + even code that is attempting to infer a version to report for all importable + top-level names has a means to fall back to reporting the distribution + version information if no ``__version__`` attribute is defined. Only standard + library modules, and modules added via means other than Python package + installation would fail to have version information reported in that case. .. _zerover: https://0ver.org From 151730958b1dc5828bfaa7005c2bad315f24453f Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:33:48 +1000 Subject: [PATCH 10/15] Date bump --- source/discussions/single-source-version.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 9fafa433b..c7dc8d1e1 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -5,7 +5,7 @@ Single-sourcing the Project Version =================================== :Page Status: Complete -:Last Reviewed: 2024-10-02 +:Last Reviewed: 2024-10-07 Many Python :term:`distribution packages ` publish a single Python :term:`import package ` where it is desired that the runtime From d8410cb273b80fd47848dab8ae6b0f9a9007a8a0 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:39:22 +1000 Subject: [PATCH 11/15] Additional cleanups --- source/discussions/versioning.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 9ecba5d03..8f318bae9 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -180,8 +180,8 @@ Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime using the standard library's :func:`importlib.metadata.version` function:: - >>> importlib.metadata.version("pip") - '23.3.2' + >>> importlib.metadata.version("cryptography") + '41.0.7' Many projects also choose to version their top level :term:`import packages ` by providing a package level @@ -199,12 +199,13 @@ Package publishers wishing to ensure their reported distribution package and import package versions are consistent with each other can review the :ref:`single-source-version` discussion for potential approaches to doing so. -However, as import packages and modules are not *required* to publish runtime +As import packages and modules are not *required* to publish runtime version information in this way (see the rejected proposal in :pep:`PEP 396 <396>`), the ``__version__`` attribute should either only be -queried with interfaces that are known to provide it, or else the querying -code should be designed to handle the case where the attribute is missing -[#fallback-to-dist-version]_. +queried with interfaces that are known to provide it (such as a project +querying its own version or the version of one of its direct dependencies), +or else the querying code should be designed to handle the case where the +attribute is missing [#fallback-to-dist-version]_. Some projects may need to publish version information for external APIs that don't meet the requirements for Python distribution package From 2f66077c9c2729b741623a35d5bc45bbe558add3 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:40:14 +1000 Subject: [PATCH 12/15] Delay turning on semantic cross-references --- source/discussions/single-source-version.rst | 2 +- source/discussions/versioning.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index c7dc8d1e1..9514d21fd 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -10,7 +10,7 @@ Single-sourcing the Project Version Many Python :term:`distribution packages ` publish a single Python :term:`import package ` where it is desired that the runtime ``__version__`` attribute on the import package report the same version specifier -as :func:`importlib.metadata.version` reports for the distribution package +as :func:`!importlib.metadata.version` reports for the distribution package (as described in :ref:`runtime-version-access`). It is also frequently desired that this version information be derived from a version diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 8f318bae9..414d19c3a 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -178,7 +178,7 @@ Accessing version information at runtime Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime -using the standard library's :func:`importlib.metadata.version` function:: +using the standard library's :func:`!importlib.metadata.version` function:: >>> importlib.metadata.version("cryptography") '41.0.7' From 0e71a8fa236f4711083dd253c0de19220fd6b95a Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:45:51 +1000 Subject: [PATCH 13/15] Redo co-author commit ready for squash merge Co-Authored-By: wim glenn From 47bb0e3e739ecf0ab4d41e6ac3e873fdb89469da Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Mon, 7 Oct 2024 18:50:13 +1000 Subject: [PATCH 14/15] Defer another semantic cross-reference --- source/discussions/versioning.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index 414d19c3a..dad28c9df 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -235,7 +235,7 @@ multiple ways to access the underlying OpenSSL library version:: .. [#fallback-to-dist-version] A full list mapping the top level names available for import to the distribution packages that provide those import packages and modules may be obtained through the standard library's - :func:`importlib.metadata.packages_distributions` function. This means that + :func:`!importlib.metadata.packages_distributions` function. This means that even code that is attempting to infer a version to report for all importable top-level names has a means to fall back to reporting the distribution version information if no ``__version__`` attribute is defined. Only standard From bbf6d6618ebebaf0b609c637a2e107f0a1556f4e Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Tue, 8 Oct 2024 17:44:15 +1000 Subject: [PATCH 15/15] Restore semantic links now the targets exist --- source/discussions/single-source-version.rst | 2 +- source/discussions/versioning.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/discussions/single-source-version.rst b/source/discussions/single-source-version.rst index 9514d21fd..c7dc8d1e1 100644 --- a/source/discussions/single-source-version.rst +++ b/source/discussions/single-source-version.rst @@ -10,7 +10,7 @@ Single-sourcing the Project Version Many Python :term:`distribution packages ` publish a single Python :term:`import package ` where it is desired that the runtime ``__version__`` attribute on the import package report the same version specifier -as :func:`!importlib.metadata.version` reports for the distribution package +as :func:`importlib.metadata.version` reports for the distribution package (as described in :ref:`runtime-version-access`). It is also frequently desired that this version information be derived from a version diff --git a/source/discussions/versioning.rst b/source/discussions/versioning.rst index dad28c9df..8f318bae9 100644 --- a/source/discussions/versioning.rst +++ b/source/discussions/versioning.rst @@ -178,7 +178,7 @@ Accessing version information at runtime Version information for all :term:`distribution packages ` that are locally available in the current environment can be obtained at runtime -using the standard library's :func:`!importlib.metadata.version` function:: +using the standard library's :func:`importlib.metadata.version` function:: >>> importlib.metadata.version("cryptography") '41.0.7' @@ -235,7 +235,7 @@ multiple ways to access the underlying OpenSSL library version:: .. [#fallback-to-dist-version] A full list mapping the top level names available for import to the distribution packages that provide those import packages and modules may be obtained through the standard library's - :func:`!importlib.metadata.packages_distributions` function. This means that + :func:`importlib.metadata.packages_distributions` function. This means that even code that is attempting to infer a version to report for all importable top-level names has a means to fall back to reporting the distribution version information if no ``__version__`` attribute is defined. Only standard