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

Return type annotation for importlib.metadata.version is incorrect #7513

Closed
DMRobertson opened this issue Mar 18, 2022 · 6 comments
Closed

Comments

@DMRobertson
Copy link
Contributor

DMRobertson commented Mar 18, 2022

To my surprise, I discovered in matrix-org/synapse#12223 that it is possible for importlib.metadata.version("foo") to return None. However, the stub suggests version and Distribution.version will always return a string:

def version(self) -> str: ...

def version(distribution_name: str) -> str: ...

To prove that version sometimes returns None:

  1. Create a new virtual environment. I'm using CPython 3.10.2 as my interpreter.
  2. Within the venv, pip install bottle. (Any package will do; I choose bottle because it's small and doesn't have any dependencies).
  3. The version of bottle agrees with what you've just installed:
    $ python -c "import importlib.metadata as m; print(repr(m.version('bottle')))"
    '0.12.19'
  4. Here's the dirty bit: remove the metadata files for that package but keep the metadata directory.
    • Use pip show bottle to find the site-packages location
    • From there, remove all files in the bottle-VERSION-.dist-info directory: `rm /path/to/site-packages/bottle-VERSION.dist-info/*'.
  5. The version of bottle is now judged to be None:
    $ python -c "import importlib.metadata as m; print(repr(m.version('bottle')))"
    None

A few other notes:

  • For a package foo that's not installed, version("foo") raises a PackageNotFoundError.
  • I don't know if this ought to be considered a bug in the library rather than the annotations?
  • I haven't dug much into the internals of importlib.metadata but it looks like the version is retrieved by looking inside a metadata attribute on a Distribution. I think other lookups are vulnerable to a similar problem; the only example I could find is Distribution.name.
@DMRobertson
Copy link
Contributor Author

I'd be happy to PR an update to the annotations making version and name return str | None---but I'm not sure if that's the correct thing to do. Perhaps the implementation ought to be changed to raise an exception in this case, and this ought to be a bug against CPython and the backport importlib_metadata?

@JelleZijlstra
Copy link
Member

Not too familiar with importlib.metadata either, but this does sound like it's better treated as a bug in the implementation. The documentation is at https://docs.python.org/3.10/library/importlib.metadata.html#distribution-versions. It's not very precise but doesn't say anything about version() returning None in exotic cases.

@DMRobertson
Copy link
Contributor Author

The documentation is at https://docs.python.org/3.10/library/importlib.metadata.html#distribution-versions.

There's also the backport of this module, which (strangely?) has a more complete reference. https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.version doesn't suggest anything about None there.

this does sound like it's better treated as a bug in the implementation.

Thanks for confirming! I'll get filing issues elsewhere.

@JelleZijlstra
Copy link
Member

Thanks! If you're reporting a bug, I'd suggest the docs should also state that it throws PackageNotFoundError for a package that is not installed. :)

@AlexWaygood
Copy link
Member

There's also the backport of this module, which (strangely?) has a more complete reference. https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.version doesn't suggest anything about None there.

If I understand correctly, I believe changes are usually made to importlib_metadata first, and then "forward-ported" to CPython (don't ask me why). So this isn't that strange :)

@DMRobertson
Copy link
Contributor Author

For completeness: I've raised https://bugs.python.org/issue47060. It looks like python/importlib_metadata#371 might be related too.

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

3 participants