mirror of
https://github.com/python/cpython.git
synced 2025-09-18 06:30:38 +00:00
bpo-43428: Improve documentation for importlib.metadata changes. (GH-24858)
* bpo-43428: Sync with importlib_metadata 3.7.3 (16ac3a95) * Add 'versionadded' for importlib.metadata.packages_distributions * Add section in what's new for Python 3.10 highlighting most salient changes and relevant backport.
This commit is contained in:
parent
5e29021a5e
commit
35d5068928
3 changed files with 73 additions and 3 deletions
|
@ -79,15 +79,43 @@ Entry points are represented by ``EntryPoint`` instances;
|
||||||
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
|
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
|
||||||
a ``.load()`` method to resolve the value. There are also ``.module``,
|
a ``.load()`` method to resolve the value. There are also ``.module``,
|
||||||
``.attr``, and ``.extras`` attributes for getting the components of the
|
``.attr``, and ``.extras`` attributes for getting the components of the
|
||||||
``.value`` attribute::
|
``.value`` attribute.
|
||||||
|
|
||||||
|
Query all entry points::
|
||||||
|
|
||||||
>>> eps = entry_points() # doctest: +SKIP
|
>>> eps = entry_points() # doctest: +SKIP
|
||||||
|
|
||||||
|
The ``entry_points()`` function returns an ``EntryPoints`` object,
|
||||||
|
a sequence of all ``EntryPoint`` objects with ``names`` and ``groups``
|
||||||
|
attributes for convenience::
|
||||||
|
|
||||||
>>> sorted(eps.groups) # doctest: +SKIP
|
>>> sorted(eps.groups) # doctest: +SKIP
|
||||||
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
|
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
|
||||||
|
|
||||||
|
``EntryPoints`` has a ``select`` method to select entry points
|
||||||
|
matching specific properties. Select entry points in the
|
||||||
|
``console_scripts`` group::
|
||||||
|
|
||||||
>>> scripts = eps.select(group='console_scripts') # doctest: +SKIP
|
>>> scripts = eps.select(group='console_scripts') # doctest: +SKIP
|
||||||
|
|
||||||
|
Equivalently, since ``entry_points`` passes keyword arguments
|
||||||
|
through to select::
|
||||||
|
|
||||||
|
>>> scripts = entry_points(group='console_scripts') # doctest: +SKIP
|
||||||
|
|
||||||
|
Pick out a specific script named "wheel" (found in the wheel project)::
|
||||||
|
|
||||||
>>> 'wheel' in scripts.names # doctest: +SKIP
|
>>> 'wheel' in scripts.names # doctest: +SKIP
|
||||||
True
|
True
|
||||||
>>> wheel = scripts['wheel'] # doctest: +SKIP
|
>>> wheel = scripts['wheel'] # doctest: +SKIP
|
||||||
|
|
||||||
|
Equivalently, query for that entry point during selection::
|
||||||
|
|
||||||
|
>>> (wheel,) = entry_points(group='console_scripts', name='wheel') # doctest: +SKIP
|
||||||
|
>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel') # doctest: +SKIP
|
||||||
|
|
||||||
|
Inspect the resolved entry point::
|
||||||
|
|
||||||
>>> wheel # doctest: +SKIP
|
>>> wheel # doctest: +SKIP
|
||||||
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
|
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
|
||||||
>>> wheel.module # doctest: +SKIP
|
>>> wheel.module # doctest: +SKIP
|
||||||
|
@ -106,6 +134,17 @@ group. Read `the setuptools docs
|
||||||
<https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins>`_
|
<https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins>`_
|
||||||
for more information on entry points, their definition, and usage.
|
for more information on entry points, their definition, and usage.
|
||||||
|
|
||||||
|
*Compatibility Note*
|
||||||
|
|
||||||
|
The "selectable" entry points were introduced in ``importlib_metadata``
|
||||||
|
3.6 and Python 3.10. Prior to those changes, ``entry_points`` accepted
|
||||||
|
no parameters and always returned a dictionary of entry points, keyed
|
||||||
|
by group. For compatibility, if no parameters are passed to entry_points,
|
||||||
|
a ``SelectableGroups`` object is returned, implementing that dict
|
||||||
|
interface. In the future, calling ``entry_points`` with no parameters
|
||||||
|
will return an ``EntryPoints`` object. Users should rely on the selection
|
||||||
|
interface to retrieve entry points by group.
|
||||||
|
|
||||||
|
|
||||||
.. _metadata:
|
.. _metadata:
|
||||||
|
|
||||||
|
@ -199,6 +238,8 @@ Python packages or modules::
|
||||||
>>> packages_distributions()
|
>>> packages_distributions()
|
||||||
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
|
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
|
||||||
|
|
||||||
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
|
|
||||||
Distributions
|
Distributions
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -690,6 +690,19 @@ Added the *root_dir* and *dir_fd* parameters in :func:`~glob.glob` and
|
||||||
:func:`~glob.iglob` which allow to specify the root directory for searching.
|
:func:`~glob.iglob` which allow to specify the root directory for searching.
|
||||||
(Contributed by Serhiy Storchaka in :issue:`38144`.)
|
(Contributed by Serhiy Storchaka in :issue:`38144`.)
|
||||||
|
|
||||||
|
importlib.metadata
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Feature parity with ``importlib_metadata`` 3.7.
|
||||||
|
|
||||||
|
:func:`importlib.metadata.entry_points` now provides a nicer experience
|
||||||
|
for selecting entry points by group and name through a new
|
||||||
|
:class:`importlib.metadata.EntryPoints` class.
|
||||||
|
|
||||||
|
Added :func:`importlib.metadata.packages_distributions` for resolving
|
||||||
|
top-level Python modules and packages to their
|
||||||
|
:class:`importlib.metadata.Distribution`.
|
||||||
|
|
||||||
inspect
|
inspect
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import abc
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
import email
|
import email
|
||||||
import inspect
|
|
||||||
import pathlib
|
import pathlib
|
||||||
import zipfile
|
import zipfile
|
||||||
import operator
|
import operator
|
||||||
|
@ -12,7 +11,7 @@ import warnings
|
||||||
import functools
|
import functools
|
||||||
import itertools
|
import itertools
|
||||||
import posixpath
|
import posixpath
|
||||||
import collections.abc
|
import collections
|
||||||
|
|
||||||
from ._itertools import unique_everseen
|
from ._itertools import unique_everseen
|
||||||
|
|
||||||
|
@ -33,6 +32,7 @@ __all__ = [
|
||||||
'entry_points',
|
'entry_points',
|
||||||
'files',
|
'files',
|
||||||
'metadata',
|
'metadata',
|
||||||
|
'packages_distributions',
|
||||||
'requires',
|
'requires',
|
||||||
'version',
|
'version',
|
||||||
]
|
]
|
||||||
|
@ -158,21 +158,33 @@ class EntryPoints(tuple):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __getitem__(self, name): # -> EntryPoint:
|
def __getitem__(self, name): # -> EntryPoint:
|
||||||
|
"""
|
||||||
|
Get the EntryPoint in self matching name.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return next(iter(self.select(name=name)))
|
return next(iter(self.select(name=name)))
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise KeyError(name)
|
raise KeyError(name)
|
||||||
|
|
||||||
def select(self, **params):
|
def select(self, **params):
|
||||||
|
"""
|
||||||
|
Select entry points from self that match the
|
||||||
|
given parameters (typically group and/or name).
|
||||||
|
"""
|
||||||
return EntryPoints(ep for ep in self if ep.matches(**params))
|
return EntryPoints(ep for ep in self if ep.matches(**params))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def names(self):
|
def names(self):
|
||||||
|
"""
|
||||||
|
Return the set of all names of all entry points.
|
||||||
|
"""
|
||||||
return set(ep.name for ep in self)
|
return set(ep.name for ep in self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def groups(self):
|
def groups(self):
|
||||||
"""
|
"""
|
||||||
|
Return the set of all groups of all entry points.
|
||||||
|
|
||||||
For coverage while SelectableGroups is present.
|
For coverage while SelectableGroups is present.
|
||||||
>>> EntryPoints().groups
|
>>> EntryPoints().groups
|
||||||
set()
|
set()
|
||||||
|
@ -185,6 +197,9 @@ class EntryPoints(tuple):
|
||||||
|
|
||||||
|
|
||||||
def flake8_bypass(func):
|
def flake8_bypass(func):
|
||||||
|
# defer inspect import as performance optimization.
|
||||||
|
import inspect
|
||||||
|
|
||||||
is_flake8 = any('flake8' in str(frame.filename) for frame in inspect.stack()[:5])
|
is_flake8 = any('flake8' in str(frame.filename) for frame in inspect.stack()[:5])
|
||||||
return func if not is_flake8 else lambda: None
|
return func if not is_flake8 else lambda: None
|
||||||
|
|
||||||
|
@ -813,6 +828,7 @@ def packages_distributions() -> Mapping[str, List[str]]:
|
||||||
Return a mapping of top-level packages to their
|
Return a mapping of top-level packages to their
|
||||||
distributions.
|
distributions.
|
||||||
|
|
||||||
|
>>> import collections.abc
|
||||||
>>> pkgs = packages_distributions()
|
>>> pkgs = packages_distributions()
|
||||||
>>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values())
|
>>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values())
|
||||||
True
|
True
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue