[New-bugs-announce] [issue47060] importlib.metadata.version can return None

David Robertson report at bugs.python.org
Fri Mar 18 14:11:51 EDT 2022


New submission from David Robertson <david.m.robertson1 at 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 <report at bugs.python.org>
<https://bugs.python.org/issue47060>
_______________________________________


More information about the New-bugs-announce mailing list