@@ -153,7 +153,6 @@ numbering scheme that readily conveys the approximate age of a release, but
153153doesn't otherwise commit to a particular release cadence within the year.
154154
155155
156-
157156Local version identifiers
158157=========================
159158
@@ -172,6 +171,54 @@ since the latest release, setuptools-scm generates a version like
172171"0.5.dev1+gd00980f", or if the repository has untracked changes, like
173172"0.5.dev1+gd00980f.d20231217".
174173
174+ .. _runtime-version-access :
175+
176+ Accessing version information at runtime
177+ ========================================
178+
179+ Version information for all :term: `distribution packages <Distribution Package> `
180+ that are locally available in the current environment can be obtained at runtime
181+ using the standard library's :func: `importlib.metadata.version ` function::
182+
183+ >>> importlib.metadata.version("cryptography")
184+ '41.0.7'
185+
186+ Many projects also choose to version their top level
187+ :term: `import packages <Import Package> ` by providing a package level
188+ ``__version__ `` attribute::
189+
190+ >>> import cryptography
191+ >>> cryptography.__version__
192+ '41.0.7'
193+
194+ This technique can be particularly valuable for CLI applications which want
195+ to ensure that version query invocations (such as ``pip -V ``) run as quickly
196+ as possible.
197+
198+ Package publishers wishing to ensure their reported distribution package and
199+ import package versions are consistent with each other can review the
200+ :ref: `single-source-version ` discussion for potential approaches to doing so.
201+
202+ As import packages and modules are not *required * to publish runtime
203+ version information in this way (see the withdrawn proposal in
204+ :pep: `PEP 396 <396 >`), the ``__version__ `` attribute should either only be
205+ queried with interfaces that are known to provide it (such as a project
206+ querying its own version or the version of one of its direct dependencies),
207+ or else the querying code should be designed to handle the case where the
208+ attribute is missing [#fallback-to-dist-version ]_.
209+
210+ Some projects may need to publish version information for external APIs
211+ that aren't the version of the module itself. Such projects should
212+ define their own project-specific ways of obtaining the relevant information
213+ at runtime. For example, the standard library's :mod: `ssl ` module offers
214+ multiple ways to access the underlying OpenSSL library version::
215+
216+ >>> ssl.OPENSSL_VERSION
217+ 'OpenSSL 3.2.2 4 Jun 2024'
218+ >>> ssl.OPENSSL_VERSION_INFO
219+ (3, 2, 0, 2, 0)
220+ >>> hex(ssl.OPENSSL_VERSION_NUMBER)
221+ '0x30200020'
175222
176223--------------------------------------------------------------------------------
177224
@@ -184,6 +231,15 @@ since the latest release, setuptools-scm generates a version like
184231 Brett Cannon <semver-brett-cannon_> `_. For a humoristic take, read about
185232 ZeroVer _.
186233
234+ .. [#fallback-to-dist-version ] A full list mapping the top level names available
235+ for import to the distribution packages that provide those import packages and
236+ modules may be obtained through the standard library's
237+ :func: `importlib.metadata.packages_distributions ` function. This means that
238+ even code that is attempting to infer a version to report for all importable
239+ top-level names has a means to fall back to reporting the distribution
240+ version information if no ``__version__ `` attribute is defined. Only standard
241+ library modules, and modules added via means other than Python package
242+ installation would fail to have version information reported in that case.
187243
188244
189245 .. _zerover : https://0ver.org
0 commit comments