Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

importing importlib_metadata monkeypatches stdlib importlib breaking apis #300

Closed
asottile opened this issue Mar 30, 2021 · 4 comments
Closed

Comments

@asottile
Copy link
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
@jaraco jaraco changed the title importing importlib-metadata monkeypatches stdlib importlib breaking apis importing importlib_metadata monkeypatches stdlib importlib breaking apis Mar 31, 2021
@jaraco
Copy link
Member

jaraco commented Mar 31, 2021

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 closed this as completed in 5ca9bc7 Apr 6, 2021
@jaraco
Copy link
Member

jaraco commented May 30, 2021

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.

@jaraco jaraco reopened this May 30, 2021
@jaraco
Copy link
Member

jaraco commented May 30, 2021

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

@jaraco
Copy link
Member

jaraco commented May 30, 2021

In the downstream report, @asottile also reports:

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

@jaraco jaraco closed this as completed in a8c70ee May 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants