Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

API incompatibility withimportlib.metadata (or at least the API is not type-safe?) #486

Open
@abravalheri

Description

@abravalheri

When 3rd-partyMetaPathFinder are implemented usingimportlib.metadata, the return types inimportlib_metadata are not respected, which causes the API to behave in an unexpected way (with unexpected errors).

This is an example similar to the one identified inpypa/pyproject-hooks#195 (comment) andpypa/setuptools#4338:

mkdir -p /tmp/stash/private_path/_test-0.0.1.dist-infocat<<EOF > /tmp/stash/private_path/_test-0.0.1.dist-info/METADATAName: _testVersion: 0.0.1EOFcat<<EOF > /tmp/stash/private_path/_test-0.0.1.dist-info/entry_points.txt[_test.importlib_metadata]hello = worldEOFcat<<EOF > /tmp/stash/install_finder.pyimport sysfrom importlib.machinery import PathFinderfrom importlib.metadata import DistributionFinder, MetadataPathFinderclass _ExampleFinder:    def __init__(self, private_path):        self.private_path = private_path    def find_spec(self, fullname, _path, _target=None):        if "." in fullname:            # Rely on importlib to find nested modules based on parent's path            return None        # Ignore other items in _path or sys.path and use private_path instead:        return PathFinder.find_spec(fullname, path=self.private_path)    def find_distributions(self, context=None):        context = DistributionFinder.Context(path=self.private_path)        return MetadataPathFinder.find_distributions(context=context)sys.meta_path.insert(0, _ExampleFinder(["/tmp/stash/private_path"]))EOFcd /tmp/stash/python3.8 -m venv .venv.venv/bin/python -m pip install -U importlib-metadata.venv/bin/python
>>>importinstall_finder>>>fromimportlib_metadataimportdistribution>>>distribution("_test").entry_points.select(group="_test.importlib_metadata")Traceback (mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'list'objecthasnoattribute'select'

The expected behaviour as per API documentation would be:

>>>distribution("_test").entry_points.select(group="_test.importlib_metadata")EntryPoints((EntryPoint(name='hello',value='world',group='_test.importlib_metadata'),))

It seems that the origin of this problem is a little "lie" in the API definition:

Instead of

importlib_metadata.Distribution.discover(...) -> Iterable[importlib_metadata.Distribution]

what actually happens is:

importlib_metadata.Distribution.discover(...) -> Iterable[importlib_metadata.Distribution | importlib.metadata.Distribution]

and that propagates throughout the whole API.

I haven't tested, but there is potential for other internal errors too, if internallyimportlib_metadata is relying that the objects will have typeimportlib_metadata.Distribution to call newer APIs.

It is probably worthy to change the return type ofimportlib_metadata.Distribution.discover(...) toIterable[importlib_metadata.Distribution | importlib.metadata.Distribution] and then run the type checkers on the lowest Python supported (I suppose Python 3.8), to see if everything is OK.

It also means that consumers ofimportlib_metadata cannot rely on the newer APIs (unless they are sure that 3r-party packages installed in their environment are not usingimportlib.metadata).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp