@@ -100,6 +100,13 @@ You can also get a :ref:`distribution's version number <version>`, list its
100100:ref: `requirements `.
101101
102102
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+
103110Functional API
104111==============
105112
@@ -111,31 +118,53 @@ This package provides the following functionality via its public API.
111118Entry points
112119------------
113120
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.
120149
121150Query all entry points::
122151
123152 >>> eps = entry_points() # doctest: +SKIP
124153
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 ``
127156attributes for convenience::
128157
129158 >>> sorted(eps.groups) # doctest: +SKIP
130159 ['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
131160
132- `` EntryPoints `` has a `` select ` ` method to select entry points
161+ :class: ` ! EntryPoints ` has a :meth: ` !~EntryPoints. select ` method to select entry points
133162matching specific properties. Select entry points in the
134163``console_scripts `` group::
135164
136165 >>> scripts = eps.select(group='console_scripts') # doctest: +SKIP
137166
138- Equivalently, since `` entry_points ` ` passes keyword arguments
167+ Equivalently, since :func: ` ! entry_points ` passes keyword arguments
139168through to select::
140169
141170 >>> scripts = entry_points(group='console_scripts') # doctest: +SKIP
@@ -189,31 +218,41 @@ for more information on entry points, their definition, and usage.
189218Distribution metadata
190219---------------------
191220
192- Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_ includes some metadata,
193- which you can extract using the
194- ``metadata() `` function::
221+ .. function :: metadata(distribution_name)
222+
223+ Return the distribution metadata corresponding to the named
224+ distribution package as a :class: `PackageMetadata ` instance.
225+
226+ Raises :exc: `PackageNotFoundError ` if the named distribution
227+ package is not installed in the current Python environment.
228+
229+ .. class :: PackageMetadata
230+
231+ A concrete implementation of the
232+ `PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata >`_.
233+
234+ In addition to providing the defined protocol methods and attributes, subscripting
235+ the instance is equivalent to calling the :meth: `!~PackageMetadata.get ` method.
236+
237+ Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
238+ includes some metadata, which you can extract using the :func: `!metadata ` function::
195239
196240 >>> wheel_metadata = metadata('wheel') # doctest: +SKIP
197241
198- The keys of the returned data structure, a ``PackageMetadata ``,
199- name the metadata keywords, and
242+ The keys of the returned data structure name the metadata keywords, and
200243the values are returned unparsed from the distribution metadata::
201244
202245 >>> wheel_metadata['Requires-Python'] # doctest: +SKIP
203246 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
204247
205- `` PackageMetadata `` also presents a `` json ` ` attribute that returns
248+ :class: ` PackageMetadata ` also presents a :attr: ` !~PackageMetadata. json ` attribute that returns
206249all the metadata in a JSON-compatible form per :PEP: `566 `::
207250
208251 >>> wheel_metadata.json['requires_python']
209252 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
210253
211- .. note ::
212-
213- The actual type of the object returned by ``metadata() `` is an
214- implementation detail and should be accessed only through the interface
215- described by the
216- `PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata >`_.
254+ The full set of available metadata is not described here.
255+ See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
217256
218257.. versionchanged :: 3.10
219258 The ``Description `` is now included in the metadata when presented
@@ -227,7 +266,15 @@ all the metadata in a JSON-compatible form per :PEP:`566`::
227266Distribution versions
228267---------------------
229268
230- The ``version() `` function is the quickest way to get a
269+ .. function :: version(distribution_name)
270+
271+ Return the installed distribution package version for the named
272+ distribution package.
273+
274+ Raises :exc: `PackageNotFoundError ` if the named distribution
275+ package is not installed in the current Python environment.
276+
277+ The :func: `!version ` function is the quickest way to get a
231278`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_'s version
232279number, as a string::
233280
@@ -240,12 +287,28 @@ number, as a string::
240287Distribution files
241288------------------
242289
243- You can also get the full set of files contained within a distribution. The
244- ``files() `` function takes a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_ name
245- and returns all of the
246- files installed by this distribution. Each file object returned is a
247- ``PackagePath ``, a :class: `pathlib.PurePath ` derived object with additional ``dist ``,
248- ``size ``, and ``hash `` properties as indicated by the metadata. For example::
290+ .. function :: files(distribution_name)
291+
292+ Return the full set of files contained within the named
293+ distribution package.
294+
295+ Raises :exc: `PackageNotFoundError ` if the named distribution
296+ package is not installed in the current Python environment.
297+
298+ Returns :const: `None ` if the distribution is found but the installation
299+ database records reporting the files associated with the distribuion package
300+ are missing.
301+
302+ .. class :: PackagePath
303+
304+ A :class: `pathlib.PurePath ` derived object with additional ``dist ``,
305+ ``size ``, and ``hash `` properties corresponding to the distribution
306+ package's installation metadata for that file.
307+
308+ The :func: `!files ` function takes a
309+ `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
310+ name and returns all of the files installed by this distribution. Each file is reported
311+ as a :class: `PackagePath ` instance. For example::
249312
250313 >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP
251314 >>> util # doctest: +SKIP
@@ -268,16 +331,16 @@ Once you have the file, you can also read its contents::
268331 return s.encode('utf-8')
269332 return s
270333
271- You can also use the `` locate `` method to get a the absolute path to the
272- file::
334+ You can also use the :meth: ` !~PackagePath. locate ` method to get the absolute
335+ path to the file::
273336
274337 >>> util.locate() # doctest: +SKIP
275338 PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
276339
277340In the case where the metadata file listing files
278- (RECORD or SOURCES.txt) is missing, `` files() ` ` will
279- return `` None ` `. The caller may wish to wrap calls to
280- `` files() ` ` in `always_iterable
341+ (`` RECORD `` or `` SOURCES.txt `` ) is missing, :func: ` ! files ` will
342+ return :const: ` None `. The caller may wish to wrap calls to
343+ :func: ` ! files ` in `always_iterable
281344<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable> `_
282345or otherwise guard against this condition if the target
283346distribution is not known to have the metadata present.
@@ -287,8 +350,16 @@ distribution is not known to have the metadata present.
287350Distribution requirements
288351-------------------------
289352
353+ .. function :: requires(distribution_name)
354+
355+ Return the declared dependency specifiers for the named
356+ distribution package.
357+
358+ Raises :exc: `PackageNotFoundError ` if the named distribution
359+ package is not installed in the current Python environment.
360+
290361To get the full set of requirements for a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_,
291- use the `` requires() ` `
362+ use the :func: ` ! requires `
292363function::
293364
294365 >>> requires('wheel') # doctest: +SKIP
@@ -301,6 +372,16 @@ function::
301372Mapping import to distribution packages
302373---------------------------------------
303374
375+ .. function :: packages_distributions()
376+
377+ Return a mapping from the top level module and import package
378+ names found via :attr: `sys.meta_path ` to the names of the distribution
379+ packages (if any) that provide the corresponding files.
380+
381+ To allow for namespace packages (which may have members provided by
382+ multiple distribution packages), each top level import name maps to a
383+ list of distribution names rather than mapping directly to a single name.
384+
304385A convenience method to resolve the `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
305386name (or names, in the case of a namespace package)
306387that provide each importable top-level
@@ -320,23 +401,42 @@ function is not reliable with such installs.
320401Distributions
321402=============
322403
323- While the above API is the most common and convenient usage, you can get all
324- of that information from the ``Distribution `` class. A ``Distribution `` is an
325- abstract object that represents the metadata for
326- a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_. You can
327- get the ``Distribution `` instance::
404+ .. function :: distribution(distribution_name)
405+
406+ Return a :class: `Distribution ` instance describing the named
407+ distribution package.
408+
409+ Raises :exc: `PackageNotFoundError ` if the named distribution
410+ package is not installed in the current Python environment.
411+
412+ .. class :: Distribution
413+
414+ Details of an installed distribution package.
415+
416+ Note: different :class: `!Distribution ` instances do not currently compare
417+ equal, even if they relate to the same installed distribution and
418+ accordingly have the same attributes.
419+
420+ While the module level API described above is the most common and convenient usage,
421+ you can get all of that information from the :class: `!Distribution ` class.
422+ :class: `!Distribution ` is an abstract object that represents the metadata for
423+ a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_.
424+ You can get the concreate :class: `!Distribution ` subclass instance for an installed
425+ distribution package by calling the :func: `distribution ` function::
328426
329427 >>> from importlib.metadata import distribution # doctest: +SKIP
330428 >>> dist = distribution('wheel') # doctest: +SKIP
429+ >>> type(dist) # doctest: +SKIP
430+ <class 'importlib.metadata.PathDistribution'>
331431
332432Thus, an alternative way to get the version number is through the
333- `` Distribution ` ` instance::
433+ :class: ` ! Distribution ` instance::
334434
335435 >>> dist.version # doctest: +SKIP
336436 '0.32.3'
337437
338- There are all kinds of additional metadata available on the `` Distribution ` `
339- instance ::
438+ There are all kinds of additional metadata available on :class: ` ! Distribution `
439+ instances ::
340440
341441 >>> dist.metadata['Requires-Python'] # doctest: +SKIP
342442 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
@@ -350,7 +450,7 @@ metadata::
350450 'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl'
351451
352452The full set of available metadata is not described here.
353- See the `Core metadata specifications <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
453+ See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata >`_ for additional details.
354454
355455.. versionadded :: 3.13
356456 The ``.origin `` property was added.
0 commit comments