The version() function of the importlib.metadata package returns an arbitrary version number when called with None. There's no documentation on what the return value means.
I would have expected one of the following instead:
raise an error saying that the distribution_name parameter cannot be None, or
I looks like the return value is the version of an arbitrary package installed in the Python virtual environment. Calling the function repeatedly seems to give the same value, but installing a new package can cause the return value to change.
System information
CPython versions tested on: 3.10.0
Operating system and architecture: Windows 10 Enterprise (64-bit operating system, x64-based processor)
I can't think of a valid meaning for distribution_name=None in this or any related API. In a fresh checkout of CPython main, you do get an exception, but probably not the right one. It should probably quick raise a ValueError.
Python 3.12.0a0 (heads/main:da39719483, May 26 2022, 09:01:35) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from importlib.metadata import version
>>> version(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 991, in version
return distribution(distribution_name).version
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 964, in distribution
return Distribution.from_name(distribution_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 561, in from_name
raise PackageNotFoundError(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
importlib.metadata.PackageNotFoundError: No package metadata was found for None
I'm unsure whether the input should produce a ValueError or a TypeError, but it also occurs to me that an empty string may also produce unexpected results.
Hmm. The way it's currently implemented, distribution_name is passed through as Context.name where None is defined to mean "all distributions", and Distribution._from_name is implemented to return the first matching distribution. I expect the only reason that Barry is getting the PackageNotFoundError is because he's running in an environment where there are literally no distributions, but if there were a single distribution installed, I'd expect him to get the version for that one.
I expect the only reason that Barry is getting the PackageNotFoundError is because he's running in an environment where there are literally no distributions, but if there were a single distribution installed, I'd expect him to get the version for that one.
Indeed, and all I need to do to see the difference is invoke Python from a ./python.exe -m venv. Then I get 22.0.4 (from Python 3.12), which is of course the version of the pip distribution in the venv.
Activity
warsaw commented on May 26, 2022
I can't think of a valid meaning for distribution_name=None in this or any related API. In a fresh checkout of CPython main, you do get an exception, but probably not the right one. It should probably quick raise a ValueError.
@jaraco
Python 3.12.0a0 (heads/main:da39719483, May 26 2022, 09:01:35) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from importlib.metadata import version >>> version(None) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 991, in version return distribution(distribution_name).version ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 964, in distribution return Distribution.from_name(distribution_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/barry/projects/python/cpython/Lib/importlib/metadata/__init__.py", line 561, in from_name raise PackageNotFoundError(name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ importlib.metadata.PackageNotFoundError: No package metadata was found for Nonejaraco commented on Jun 23, 2022
I'm unsure whether the input should produce a ValueError or a TypeError, but it also occurs to me that an empty string may also produce unexpected results.
$ pip-run -q importlib_metadata -- -c "import importlib_metadata as md; print(md.version(''))" 4.11.4 $ py -3.11 -c "import importlib.metadata as md; print(md.version(''))" 16.4.0jaraco commented on Jun 23, 2022
Hmm. The way it's currently implemented, distribution_name is passed through as Context.name where None is defined to mean "all distributions", and Distribution._from_name is implemented to return the first matching distribution. I expect the only reason that Barry is getting the PackageNotFoundError is because he's running in an environment where there are literally no distributions, but if there were a single distribution installed, I'd expect him to get the version for that one.
jaraco commented on Jun 23, 2022
I have a test capturing the failure and a potential fix in the aforementioned PR.
In Distribution.from_name, require a non-empty string. Fixes python/c…
In Distribution.from_name, require a non-empty string. Fixes python/c…
warsaw commented on Jun 25, 2022
Indeed, and all I need to do to see the difference is invoke Python from a ./python.exe -m venv. Then I get 22.0.4 (from Python 3.12), which is of course the version of the pip distribution in the venv.
gh-93259: Validate arg to ``Distribution.from_name``. (GH-94270)
Revert 30935 defer bpo45162 to 312 (#94285)
pypi-importlib_metadata: Autospec creation for update from version 4.…