New submission from David Robertson <david.m.roberts...@gmail.com>:

Originally written up at the typeshed repo: 
https://github.com/python/typeshed/issues/7513. The conclusion was that this is 
a bug in the implementation rather than an incorrect annotation.

To my surprise, I discovered in 
https://github.com/matrix-org/synapse/issues/12223 that it is possible for 
`importlib.metadata.version(...)` to return `None`. To reproduce this:

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. Check importlib reports the `version` of `bottle`:
   ```python
   >>> import importlib.metadata as m
   >>> 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
   >>> import importlib.metadata as m
   >>> m.version("bottle") is None
   True
   ```
   `pip show bottle` now determines that `bottle` isn't installed:
   ```shell
   $ pip show bottle
   WARNING: Package(s) not found: bottle
   ```

As well as importlib.metadata.version, importlib.metadata.Distribution.version 
and importlib.metadata.Distribution.name return None in this situation.

I couldn't see any suggestion in the stdlib docs 
(https://docs.python.org/3.10/library/importlib.metadata.html#distribution-versions)
 that this was possible. (Aside: it'd be great if the docs mention that 
PackageNotFoundError is raised if a package is not installed.)

No-one in their right mind should do step 4 willingly, but I have seen it 
happen in the wild (https://github.com/matrix-org/synapse/issues/12223). We 
suspected a botched backup or similar was to blame.

I'm not familiar with all the machinery of Python package management, but I 
think I'd expect there to be a PackageNotFoundError raised in this situation? 
(I can imagine a package that doesn't declare its version, where `version()` 
returning `None` might make sense; but that feels odd.) Is the behaviour as 
intended?

It looks like this might be related to 
https://github.com/python/importlib_metadata/issues/371?

----------
components: Library (Lib)
messages: 415516
nosy: David Robertson
priority: normal
severity: normal
status: open
title: importlib.metadata.version can return None
type: behavior
versions: Python 3.10

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue47060>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to