@@ -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
@@ -187,31 +216,41 @@ for compatibility options.
187216Distribution metadata
188217---------------------
189218
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::
193237
194238 >>> wheel_metadata = metadata('wheel') # doctest: +SKIP
195239
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
198241the values are returned unparsed from the distribution metadata::
199242
200243 >>> wheel_metadata['Requires-Python'] # doctest: +SKIP
201244 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
202245
203- `` PackageMetadata `` also presents a `` json ` ` attribute that returns
246+ :class: ` PackageMetadata ` also presents a :attr: ` !~PackageMetadata. json ` attribute that returns
204247all the metadata in a JSON-compatible form per :PEP: `566 `::
205248
206249 >>> wheel_metadata.json['requires_python']
207250 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
208251
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.
215254
216255.. versionchanged :: 3.10
217256 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`::
225264Distribution versions
226265---------------------
227266
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
229276`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_'s version
230277number, as a string::
231278
@@ -238,12 +285,28 @@ number, as a string::
238285Distribution files
239286------------------
240287
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::
247310
248311 >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP
249312 >>> util # doctest: +SKIP
@@ -266,16 +329,16 @@ Once you have the file, you can also read its contents::
266329 return s.encode('utf-8')
267330 return s
268331
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::
271334
272335 >>> util.locate() # doctest: +SKIP
273336 PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
274337
275338In 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
279342<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable> `_
280343or otherwise guard against this condition if the target
281344distribution is not known to have the metadata present.
@@ -285,8 +348,16 @@ distribution is not known to have the metadata present.
285348Distribution requirements
286349-------------------------
287350
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+
288359To 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 `
290361function::
291362
292363 >>> requires('wheel') # doctest: +SKIP
@@ -299,6 +370,16 @@ function::
299370Mapping import to distribution packages
300371---------------------------------------
301372
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+
302383A convenience method to resolve the `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package >`_
303384name (or names, in the case of a namespace package)
304385that provide each importable top-level
@@ -318,31 +399,50 @@ function is not reliable with such installs.
318399Distributions
319400=============
320401
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::
326424
327425 >>> from importlib.metadata import distribution # doctest: +SKIP
328426 >>> dist = distribution('wheel') # doctest: +SKIP
427+ >>> type(dist) # doctest: +SKIP
428+ <class 'importlib.metadata.PathDistribution'>
329429
330430Thus, an alternative way to get the version number is through the
331- `` Distribution ` ` instance::
431+ :class: ` ! Distribution ` instance::
332432
333433 >>> dist.version # doctest: +SKIP
334434 '0.32.3'
335435
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 ::
338438
339439 >>> dist.metadata['Requires-Python'] # doctest: +SKIP
340440 '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
341441 >>> dist.metadata['License'] # doctest: +SKIP
342442 'MIT'
343443
344444The 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.
346446
347447
348448Distribution Discovery
0 commit comments