Regression: importlib.metadata.PathDistribution.requires raises AttributeError, name/version raises TypeError
Bug report
Bug description:
Python 3.14.2
>>> from importlib import metadata
>>> d = metadata.PathDistribution.at('/tmp')
>>> d.requires
>>> d.requires is None
True
Python 3.15.0a3
>>> from importlib import metadata
>>> d = metadata.PathDistribution.at('/tmp')
>>> d.requires
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
d.requires
File "/usr/lib64/python3.15/importlib/metadata/__init__.py", line 660, in requires
reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs()
~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib64/python3.15/importlib/metadata/__init__.py", line 664, in _read_dist_info_reqs
return self.metadata.get_all('Requires-Dist')
^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_all'
I believe this is a regression from 9b38c6698a3d6e7b37279dd9ae0d4d6430f9c612 where the metadata property changed the type from _meta.PackageMetadata to _meta.PackageMetadata | None but other properties (here the requires property) do not account for it being None.
This was discovered as a failure of tests of rpmlint in Fedora's continuous testing of Python pre-releases: https://bugzilla.redhat.com/show_bug.cgi?id=2424585
CPython versions tested on:
3.15
Operating systems tested on:
Linux
Upstream commit is https://github.com/python/importlib_metadata/commit/57f31d77e18fef11dfadfd44775f253971c36920 from https://github.com/python/importlib_metadata/pull/519 -- unfortunately, neither the commit nor the PR provide rationale for this change.
Similarly, before:
>>> d = metadata.PathDistribution.at('/tmp')
>>> d.name
>>> d.version
>>>
After:
>>> from importlib import metadata
>>> d = metadata.PathDistribution.at('/tmp')
>>> d.name
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
d.name
File "/usr/lib64/python3.15/importlib/metadata/__init__.py", line 542, in name
return md_none(self.metadata)['Name']
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
>>> d.version
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
d.version
File "/usr/lib64/python3.15/importlib/metadata/__init__.py", line 552, in version
return md_none(self.metadata)['Version']
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
Agreed the regression seems to stem from the change in PathDistribution.metadata to return None. It does correctly return None, but downstream properties like .name, .version, and .requires weren't updated to handle the NoneType return.
I’d be happy to patch this if it is indeed a regression.
cc @jaraco
What is the deal here? Do I need to report this to https://github.com/python/importlib_metadata/ ?
Note that, based on https://github.com/tox-dev/pipdeptree/issues/530 I think that .metadata being None is a regression of its own.
Hi, I'd like to work on this regression fix. I can see the issue is in PathDistribution where requires, name, and version methods don't handle self.metadata being None. I'll add proper None checks to all three methods.
I am not quite sure this is a proper fix. Considering self.metadata being None is a breaking change, I think the best way forward is to revert it.