@@ -100,6 +100,13 @@ You can also get a :ref:`distribution's version number <version>`, list its
100
100
:ref: `requirements `.
101
101
102
102
103
+ .. exception :: PackageNotFoundError
104
+
105
+ Subclass of :class: `ModuleNotFoundError ` raised by several functions in this
106
+ module when queried for a distribution package which is not installed in the
107
+ current Python environment.
108
+
109
+
103
110
Functional API
104
111
==============
105
112
@@ -111,31 +118,53 @@ This package provides the following functionality via its public API.
111
118
Entry points
112
119
------------
113
120
114
- The ``entry_points() `` function returns a collection of entry points.
115
- Entry points are represented by ``EntryPoint `` instances;
116
- each ``EntryPoint `` has a ``.name ``, ``.group ``, and ``.value `` attributes and
117
- a ``.load() `` method to resolve the value. There are also ``.module ``,
118
- ``.attr ``, and ``.extras `` attributes for getting the components of the
119
- ``.value `` attribute.
121
+ .. function :: entry_points(**select_params)
122
+
123
+ Returns a :class: `EntryPoints ` instance describing entry points for the
124
+ current environment. Any given keyword parameters are passed to the
125
+ :meth: `!~EntryPoints.select ` method for comparison to the attributes of
126
+ the individual entry point definitions.
127
+
128
+ Note: it is not currently possible to query for entry points based on
129
+ their :attr: `!EntryPoint.dist ` attribute (as different :class: `!Distribution `
130
+ instances do not currently compare equal, even if they have the same attributes)
131
+
132
+ .. class :: EntryPoints
133
+
134
+ Details of a collection of installed entry points.
135
+
136
+ Also provides a ``.groups `` attribute that reports all identifed entry
137
+ point groups, and a ``.names `` attribute that reports all identified entry
138
+ point names.
139
+
140
+ .. class :: EntryPoint
141
+
142
+ Details of an installed entry point.
143
+
144
+ Each :class: `!EntryPoint ` instance has ``.name ``, ``.group ``, and ``.value ``
145
+ attributes and a ``.load() `` method to resolve the value. There are also
146
+ ``.module ``, ``.attr ``, and ``.extras `` attributes for getting the
147
+ components of the ``.value `` attribute, and ``.dist `` for obtaining
148
+ information regarding the distribution package that provides the entry point.
120
149
121
150
Query all entry points::
122
151
123
152
>>> eps = entry_points() # doctest: +SKIP
124
153
125
- The `` entry_points() `` function returns an `` EntryPoints ` ` object,
126
- a collection of all `` EntryPoint ` ` objects with ``names `` and ``groups ``
154
+ The :func: ` ! entry_points` function returns a :class: ` ! EntryPoints ` object,
155
+ a collection of all :class: ` ! EntryPoint ` objects with ``names `` and ``groups ``
127
156
attributes for convenience::
128
157
129
158
>>> sorted(eps.groups) # doctest: +SKIP
130
159
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
131
160
132
- `` EntryPoints `` has a `` select ` ` method to select entry points
161
+ :class: ` ! EntryPoints ` has a :meth: ` !~EntryPoints. select ` method to select entry points
133
162
matching specific properties. Select entry points in the
134
163
``console_scripts `` group::
135
164
136
165
>>> scripts = eps.select(group='console_scripts') # doctest: +SKIP
137
166
138
- Equivalently, since `` entry_points ` ` passes keyword arguments
167
+ Equivalently, since :func: ` ! entry_points ` passes keyword arguments
139
168
through to select::
140
169
141
170
>>> scripts = entry_points(group='console_scripts') # doctest: +SKIP
@@ -187,31 +216,41 @@ for compatibility options.
187
216
Distribution metadata
188
217
---------------------
189
218
190
- Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_ includes some metadata,
191
- which you can extract using the
192
- ``metadata() `` function::
219
+ .. function :: metadata(distribution_name)
220
+
221
+ Return the distribution metadata corresponding to the named
222
+ distribution package as a :class: `PackageMetadata ` instance.
223
+
224
+ Raises :exc: `PackageNotFoundError ` if the named distribution
225
+ package is not installed in the current Python environment.
226
+
227
+ .. class :: PackageMetadata
228
+
229
+ A concrete implementation of the
230
+ `PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata >`_.
231
+
232
+ In addition to providing the defined protocol methods and attributes, subscripting
233
+ the instance is equivalent to calling the :meth: `!~PackageMetadata.get ` method.
234
+
235
+ Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
236
+ includes some metadata, which you can extract using the :func: `!metadata ` function::
193
237
194
238
>>> wheel_metadata = metadata('wheel') # doctest: +SKIP
195
239
196
- The keys of the returned data structure, a ``PackageMetadata ``,
197
- name the metadata keywords, and
240
+ The keys of the returned data structure name the metadata keywords, and
198
241
the values are returned unparsed from the distribution metadata::
199
242
200
243
>>> wheel_metadata['Requires-Python'] # doctest: +SKIP
201
244
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
202
245
203
- `` PackageMetadata `` also presents a `` json ` ` attribute that returns
246
+ :class: ` PackageMetadata ` also presents a :attr: ` !~PackageMetadata. json ` attribute that returns
204
247
all the metadata in a JSON-compatible form per :PEP: `566 `::
205
248
206
249
>>> wheel_metadata.json['requires_python']
207
250
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
208
251
209
- .. note ::
210
-
211
- The actual type of the object returned by ``metadata() `` is an
212
- implementation detail and should be accessed only through the interface
213
- described by the
214
- `PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata >`_.
252
+ The full set of available metadata is not described here.
253
+ See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
215
254
216
255
.. versionchanged :: 3.10
217
256
The ``Description `` is now included in the metadata when presented
@@ -225,7 +264,15 @@ all the metadata in a JSON-compatible form per :PEP:`566`::
225
264
Distribution versions
226
265
---------------------
227
266
228
- The ``version() `` function is the quickest way to get a
267
+ .. function :: version(distribution_name)
268
+
269
+ Return the installed distribution package version for the named
270
+ distribution package.
271
+
272
+ Raises :exc: `PackageNotFoundError ` if the named distribution
273
+ package is not installed in the current Python environment.
274
+
275
+ The :func: `!version ` function is the quickest way to get a
229
276
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_'s version
230
277
number, as a string::
231
278
@@ -238,12 +285,28 @@ number, as a string::
238
285
Distribution files
239
286
------------------
240
287
241
- You can also get the full set of files contained within a distribution. The
242
- ``files() `` function takes a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_ name
243
- and returns all of the
244
- files installed by this distribution. Each file object returned is a
245
- ``PackagePath ``, a :class: `pathlib.PurePath ` derived object with additional ``dist ``,
246
- ``size ``, and ``hash `` properties as indicated by the metadata. For example::
288
+ .. function :: files(distribution_name)
289
+
290
+ Return the full set of files contained within the named
291
+ distribution package.
292
+
293
+ Raises :exc: `PackageNotFoundError ` if the named distribution
294
+ package is not installed in the current Python environment.
295
+
296
+ Returns :const: `None ` if the distribution is found but the installation
297
+ database records reporting the files associated with the distribuion package
298
+ are missing.
299
+
300
+ .. class :: PackagePath
301
+
302
+ A :class: `pathlib.PurePath ` derived object with additional ``dist ``,
303
+ ``size ``, and ``hash `` properties corresponding to the distribution
304
+ package's installation metadata for that file.
305
+
306
+ The :func: `!files ` function takes a
307
+ `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
308
+ name and returns all of the files installed by this distribution. Each file is reported
309
+ as a :class: `PackagePath ` instance. For example::
247
310
248
311
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP
249
312
>>> util # doctest: +SKIP
@@ -266,16 +329,16 @@ Once you have the file, you can also read its contents::
266
329
return s.encode('utf-8')
267
330
return s
268
331
269
- You can also use the `` locate `` method to get a the absolute path to the
270
- file::
332
+ You can also use the :meth: ` !~PackagePath. locate ` method to get the absolute
333
+ path to the file::
271
334
272
335
>>> util.locate() # doctest: +SKIP
273
336
PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
274
337
275
338
In the case where the metadata file listing files
276
- (RECORD or SOURCES.txt) is missing, `` files() ` ` will
277
- return `` None ` `. The caller may wish to wrap calls to
278
- `` files() ` ` in `always_iterable
339
+ (`` RECORD `` or `` SOURCES.txt `` ) is missing, :func: ` ! files ` will
340
+ return :const: ` None `. The caller may wish to wrap calls to
341
+ :func: ` ! files ` in `always_iterable
279
342
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable> `_
280
343
or otherwise guard against this condition if the target
281
344
distribution is not known to have the metadata present.
@@ -285,8 +348,16 @@ distribution is not known to have the metadata present.
285
348
Distribution requirements
286
349
-------------------------
287
350
351
+ .. function :: requires(distribution_name)
352
+
353
+ Return the declared dependency specifiers for the named
354
+ distribution package.
355
+
356
+ Raises :exc: `PackageNotFoundError ` if the named distribution
357
+ package is not installed in the current Python environment.
358
+
288
359
To get the full set of requirements for a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_,
289
- use the `` requires() ` `
360
+ use the :func: ` ! requires `
290
361
function::
291
362
292
363
>>> requires('wheel') # doctest: +SKIP
@@ -299,6 +370,16 @@ function::
299
370
Mapping import to distribution packages
300
371
---------------------------------------
301
372
373
+ .. function :: packages_distributions()
374
+
375
+ Return a mapping from the top level module and import package
376
+ names found via :attr: `sys.meta_path ` to the names of the distribution
377
+ packages (if any) that provide the corresponding files.
378
+
379
+ To allow for namespace packages (which may have members provided by
380
+ multiple distribution packages), each top level import name maps to a
381
+ list of distribution names rather than mapping directly to a single name.
382
+
302
383
A convenience method to resolve the `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
303
384
name (or names, in the case of a namespace package)
304
385
that provide each importable top-level
@@ -318,31 +399,50 @@ function is not reliable with such installs.
318
399
Distributions
319
400
=============
320
401
321
- While the above API is the most common and convenient usage, you can get all
322
- of that information from the ``Distribution `` class. A ``Distribution `` is an
323
- abstract object that represents the metadata for
324
- a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_. You can
325
- get the ``Distribution `` instance::
402
+ .. function :: distribution(distribution_name)
403
+
404
+ Return a :class: `Distribution ` instance describing the named
405
+ distribution package.
406
+
407
+ Raises :exc: `PackageNotFoundError ` if the named distribution
408
+ package is not installed in the current Python environment.
409
+
410
+ .. class :: Distribution
411
+
412
+ Details of an installed distribution package.
413
+
414
+ Note: different :class: `!Distribution ` instances do not currently compare
415
+ equal, even if they relate to the same installed distribution and
416
+ accordingly have the same attributes.
417
+
418
+ While the module level API described above is the most common and convenient usage,
419
+ you can get all of that information from the :class: `!Distribution ` class.
420
+ :class: `!Distribution ` is an abstract object that represents the metadata for
421
+ a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_.
422
+ You can get the concreate :class: `!Distribution ` subclass instance for an installed
423
+ distribution package by calling the :func: `distribution ` function::
326
424
327
425
>>> from importlib.metadata import distribution # doctest: +SKIP
328
426
>>> dist = distribution('wheel') # doctest: +SKIP
427
+ >>> type(dist) # doctest: +SKIP
428
+ <class 'importlib.metadata.PathDistribution'>
329
429
330
430
Thus, an alternative way to get the version number is through the
331
- `` Distribution ` ` instance::
431
+ :class: ` ! Distribution ` instance::
332
432
333
433
>>> dist.version # doctest: +SKIP
334
434
'0.32.3'
335
435
336
- There are all kinds of additional metadata available on the `` Distribution ` `
337
- instance ::
436
+ There are all kinds of additional metadata available on :class: ` ! Distribution `
437
+ instances ::
338
438
339
439
>>> dist.metadata['Requires-Python'] # doctest: +SKIP
340
440
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
341
441
>>> dist.metadata['License'] # doctest: +SKIP
342
442
'MIT'
343
443
344
444
The full set of available metadata is not described here.
345
- See the `Core metadata specifications <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
445
+ See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
346
446
347
447
348
448
Distribution Discovery
0 commit comments