bpo-39022, bpo-38594: Sync with importlib_metadata 1.3 (GH-17568)
* bpo-39022, bpo-38594: Sync with importlib_metadata 1.3 including improved docs for custom finders and better serialization support in EntryPoints. * 📜🤖 Added by blurb_it. * Correct module reference
This commit is contained in:
parent
d0802d07d2
commit
b7a0109cd2
|
@ -216,9 +216,9 @@ system `finders`_. To find a distribution package's metadata,
|
||||||
``importlib.metadata`` queries the list of `meta path finders`_ on
|
``importlib.metadata`` queries the list of `meta path finders`_ on
|
||||||
`sys.meta_path`_.
|
`sys.meta_path`_.
|
||||||
|
|
||||||
By default ``importlib.metadata`` installs a finder for distribution packages
|
The default ``PathFinder`` for Python includes a hook that calls into
|
||||||
found on the file system. This finder doesn't actually find any *packages*,
|
``importlib.metadata.MetadataPathFinder`` for finding distributions
|
||||||
but it can find the packages' metadata.
|
loaded from typical file-system-based paths.
|
||||||
|
|
||||||
The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the
|
The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the
|
||||||
interface expected of finders by Python's import system.
|
interface expected of finders by Python's import system.
|
||||||
|
@ -239,9 +239,9 @@ properties indicating the path to search and names to match and may
|
||||||
supply other relevant context.
|
supply other relevant context.
|
||||||
|
|
||||||
What this means in practice is that to support finding distribution package
|
What this means in practice is that to support finding distribution package
|
||||||
metadata in locations other than the file system, you should derive from
|
metadata in locations other than the file system, subclass
|
||||||
``Distribution`` and implement the ``load_metadata()`` method. Then from
|
``Distribution`` and implement the abstract methods. Then from
|
||||||
your finder, return instances of this derived ``Distribution`` in the
|
a custom finder, return instances of this derived ``Distribution`` in the
|
||||||
``find_distributions()`` method.
|
``find_distributions()`` method.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,8 @@ class PackageNotFoundError(ModuleNotFoundError):
|
||||||
"""The package was not found."""
|
"""The package was not found."""
|
||||||
|
|
||||||
|
|
||||||
class EntryPoint(collections.namedtuple('EntryPointBase', 'name value group')):
|
class EntryPoint(
|
||||||
|
collections.namedtuple('EntryPointBase', 'name value group')):
|
||||||
"""An entry point as defined by Python packaging conventions.
|
"""An entry point as defined by Python packaging conventions.
|
||||||
|
|
||||||
See `the packaging docs on entry points
|
See `the packaging docs on entry points
|
||||||
|
@ -107,6 +108,12 @@ class EntryPoint(collections.namedtuple('EntryPointBase', 'name value group')):
|
||||||
"""
|
"""
|
||||||
return iter((self.name, self))
|
return iter((self.name, self))
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return (
|
||||||
|
self.__class__,
|
||||||
|
(self.name, self.value, self.group),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PackagePath(pathlib.PurePosixPath):
|
class PackagePath(pathlib.PurePosixPath):
|
||||||
"""A reference to a path in a package"""
|
"""A reference to a path in a package"""
|
||||||
|
@ -334,10 +341,21 @@ class DistributionFinder(MetaPathFinder):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Context:
|
class Context:
|
||||||
|
"""
|
||||||
|
Keyword arguments presented by the caller to
|
||||||
|
``distributions()`` or ``Distribution.discover()``
|
||||||
|
to narrow the scope of a search for distributions
|
||||||
|
in all DistributionFinders.
|
||||||
|
|
||||||
|
Each DistributionFinder may expect any parameters
|
||||||
|
and should attempt to honor the canonical
|
||||||
|
parameters defined below when appropriate.
|
||||||
|
"""
|
||||||
|
|
||||||
name = None
|
name = None
|
||||||
"""
|
"""
|
||||||
Specific name for which a distribution finder should match.
|
Specific name for which a distribution finder should match.
|
||||||
|
A name of ``None`` matches all distributions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
@ -347,6 +365,9 @@ class DistributionFinder(MetaPathFinder):
|
||||||
def path(self):
|
def path(self):
|
||||||
"""
|
"""
|
||||||
The path that a distribution finder should search.
|
The path that a distribution finder should search.
|
||||||
|
|
||||||
|
Typically refers to Python package paths and defaults
|
||||||
|
to ``sys.path``.
|
||||||
"""
|
"""
|
||||||
return vars(self).get('path', sys.path)
|
return vars(self).get('path', sys.path)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import json
|
||||||
|
import pickle
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
|
@ -181,3 +183,34 @@ class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
|
||||||
with self.add_sys_path(egg):
|
with self.add_sys_path(egg):
|
||||||
with self.assertRaises(PackageNotFoundError):
|
with self.assertRaises(PackageNotFoundError):
|
||||||
version('foo')
|
version('foo')
|
||||||
|
|
||||||
|
|
||||||
|
class TestEntryPoints(unittest.TestCase):
|
||||||
|
def __init__(self, *args):
|
||||||
|
super(TestEntryPoints, self).__init__(*args)
|
||||||
|
self.ep = importlib.metadata.EntryPoint('name', 'value', 'group')
|
||||||
|
|
||||||
|
def test_entry_point_pickleable(self):
|
||||||
|
revived = pickle.loads(pickle.dumps(self.ep))
|
||||||
|
assert revived == self.ep
|
||||||
|
|
||||||
|
def test_immutable(self):
|
||||||
|
"""EntryPoints should be immutable"""
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
self.ep.name = 'badactor'
|
||||||
|
|
||||||
|
def test_repr(self):
|
||||||
|
assert 'EntryPoint' in repr(self.ep)
|
||||||
|
assert 'name=' in repr(self.ep)
|
||||||
|
assert "'name'" in repr(self.ep)
|
||||||
|
|
||||||
|
def test_hashable(self):
|
||||||
|
"""EntryPoints should be hashable"""
|
||||||
|
hash(self.ep)
|
||||||
|
|
||||||
|
def test_json_dump(self):
|
||||||
|
"""
|
||||||
|
json should not expect to be able to dump an EntryPoint
|
||||||
|
"""
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
json.dumps(self.ep)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Update importliib.metadata to include improvements from importlib_metadata 1.3 including better serialization of EntryPoints and improved documentation for custom finders.
|
Loading…
Reference in New Issue