@@ -153,7 +153,6 @@ numbering scheme that readily conveys the approximate age of a release, but
153
153
doesn't otherwise commit to a particular release cadence within the year.
154
154
155
155
156
-
157
156
Local version identifiers
158
157
=========================
159
158
@@ -172,6 +171,54 @@ since the latest release, setuptools-scm generates a version like
172
171
"0.5.dev1+gd00980f", or if the repository has untracked changes, like
173
172
"0.5.dev1+gd00980f.d20231217".
174
173
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'
175
222
176
223
--------------------------------------------------------------------------------
177
224
@@ -184,6 +231,15 @@ since the latest release, setuptools-scm generates a version like
184
231
Brett Cannon <semver-brett-cannon_> `_. For a humoristic take, read about
185
232
ZeroVer _.
186
233
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.
187
243
188
244
189
245
.. _zerover : https://0ver.org
0 commit comments