From 4adc49c7eebc5168ffba4af21d63e89ac4a0f059 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 21 Oct 2026 14:00:03 -0700 Subject: [PATCH] Report invalid distributions in diagnose instead of crashing. An empty metadata directory is still discovered as a distribution, but it cannot name itself, so the diagnostic died on the very condition it exists to surface. Describe such distributions by the location of their metadata instead. Co-Authored-By: Claude Opus 5 --- importlib_metadata/diagnose.py | 27 +++++++++++++++++++++++++-- newsfragments/548.bugfix.rst | 3 +++ tests/test_main.py | 19 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 newsfragments/548.bugfix.rst diff --git a/importlib_metadata/diagnose.py b/importlib_metadata/diagnose.py index e405471a..a29c0d62 100644 --- a/importlib_metadata/diagnose.py +++ b/importlib_metadata/diagnose.py @@ -1,6 +1,29 @@ import sys -from . import Distribution +from . import Distribution, MetadataNotFound + + +def _locate(dist: Distribution) -> str: + """ + Indicate where the distribution's metadata was found. + """ + return str(getattr(dist, '_path', dist)) + + +def describe(dist: Distribution) -> str: + """ + Describe the distribution by name, or by location when the + distribution is too invalid to name itself. + + >>> describe(Distribution.at('missing-1.0.dist-info')) + 'missing-1.0.dist-info (no metadata)' + """ + try: + return dist.name + except MetadataNotFound: + return f'{_locate(dist)} (no metadata)' + except KeyError: + return f'{_locate(dist)} (metadata without a name)' def inspect(path): @@ -9,7 +32,7 @@ def inspect(path): if not dists: return print("Found", len(dists), "packages:", end=' ') - print(', '.join(dist.name for dist in dists)) + print(', '.join(map(describe, dists))) def run(): diff --git a/newsfragments/548.bugfix.rst b/newsfragments/548.bugfix.rst new file mode 100644 index 00000000..42c6a729 --- /dev/null +++ b/newsfragments/548.bugfix.rst @@ -0,0 +1,3 @@ +``importlib_metadata.diagnose`` no longer crashes on a metadata directory +that has no metadata file or whose metadata declares no name. Such +distributions are now reported by their location. diff --git a/tests/test_main.py b/tests/test_main.py index 63f9c06a..bf3b49a6 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,4 +1,6 @@ +import contextlib import importlib +import io import pickle import re import unittest @@ -13,6 +15,7 @@ MetadataNotFound, PackageNotFoundError, _unique, + diagnose, distributions, entry_points, metadata, @@ -169,6 +172,22 @@ def test_missing_metadata(self): with self.assertRaises(MetadataNotFound): metadata('foo') + def test_diagnose_reports_invalid(self): + """ + The diagnostic should report invalid dists by location + rather than crashing on them. + + Ref python/importlib_metadata#548. + """ + fixtures.build_files(self.make_pkg('nameless-1.0'), self.site_dir) + fixtures.build_files(self.make_pkg('empty-1.0', files={}), self.site_dir) + out = io.StringIO() + with contextlib.redirect_stdout(out): + diagnose.inspect(str(self.site_dir)) + report = out.getvalue() + assert 'empty-1.0.dist-info (no metadata)' in report + assert 'nameless-1.0.dist-info (metadata without a name)' in report + class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): @staticmethod