Skip to content

importing importlib_metadata monkeypatches stdlib importlib breaking apis #300

Closed
@asottile

Description

@asottile
Contributor
import importlib.metadata
print(importlib.metadata.distribution('setuptools').entry_points[0])
__import__('importlib_metadata')
print(importlib.metadata.distribution('setuptools').entry_points[0])
$ python3 t.py 
EntryPoint(name='alias', value='setuptools.command.alias:alias', group='distutils.commands')
Traceback (most recent call last):
  File "/tmp/y/venv/lib/python3.8/site-packages/importlib_metadata/__init__.py", line 224, in __getitem__
    return next(iter(self.select(name=name)))
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "t.py", line 4, in <module>
    print(importlib.metadata.distribution('setuptools').entry_points[0])
  File "/tmp/y/venv/lib/python3.8/site-packages/importlib_metadata/__init__.py", line 226, in __getitem__
    raise KeyError(name)
KeyError: 0

Activity

changed the title [-]importing `importlib-metadata` monkeypatches stdlib importlib breaking apis[/-] [+]importing `importlib_metadata` monkeypatches stdlib importlib breaking apis[/+] on Mar 31, 2021
jaraco

jaraco commented on Mar 31, 2021

@jaraco
Member

Looking at the only code that's run implicitly on import, it acknowledges that the monkeypatching is sketchy and references #91 as the motivation. There's quite a bit of detail there, but it explains the challenge that this library faces in attempting to provide backward and forward compatibility for multiple versions of Python. In that issue, we settled on any import of importlib_metadata as giving it primacy for PathDistributions over the stdlib version.

More importantly, however, is that what you're encountering is an API incompatibility introduced in importlib_metadata 3.6. You can recreate the error in any version of importlib_metadata>=3.6.

~ $ pip-run -q 'importlib_metadata<3.6' setuptools -- -c "import importlib_metadata as im; im.distribution('setuptools').entry_points[0]"
~ $ pip-run -q 'importlib_metadata<3.7' setuptools -- -c "import importlib_metadata as im; im.distribution('setuptools').entry_points[0]"
Traceback (most recent call last):
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-o4vgk6e2/importlib_metadata/__init__.py", line 170, in __getitem__
    return next(iter(self.select(name=name)))
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-o4vgk6e2/importlib_metadata/__init__.py", line 172, in __getitem__
    raise KeyError(name)
KeyError: 0

Basically what it boils down to is that access by index of a Distribution.entry_points was dropped, but that appears not to be a problem. At least, this is the first report of such a problem. The assumption has been, and the tests bear this out implicitly, that the consumer of Distribution.entry_points will be iterated over and not accessed by index.

So in one sense, the behavior you encountered is working as intended.

The question is, what are you trying to accomplish? Can I help you accomplish that in a way that's compatible with both? For example, the following works in all versions:

~ $ pip-run -q 'importlib_metadata<3.7' setuptools -- -c "import importlib_metadata as im; list(im.distribution('setuptools').entry_points)[0]"
jaraco

jaraco commented on May 30, 2021

@jaraco
Member

In bpo-44246, several users have indicated that maintaining compatibility for this interface would be important to them even if there are no users affected by it.

reopened this on May 30, 2021
jaraco

jaraco commented on May 30, 2021

@jaraco
Member

See miurahr/aqtinstall#221 for an affected user. Although that use-case is no longer affected.

jaraco

jaraco commented on May 30, 2021

@jaraco
Member

In the downstream report, @asottile also reports:

I also need .sort(key=...) for what it's worth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

        Participants

        @jaraco@asottile

        Issue actions

          importing `importlib_metadata` monkeypatches stdlib importlib breaking apis · Issue #300 · python/importlib_metadata