Python Basics: Read Distribution Metadata Without Importing Code
A support tool may need a package version or declared entry points without executing the package. importlib.metadata reads installed distribution metadata. A temporary .dist-info fixture makes the result reproducible without downloading or installing anything.
Prepare a scratch directory
Tested on Linux with CPython 3.12.14. You need the named runtime, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. Run Python without -O so the assertions remain enabled. Any generated fixture files live inside an automatically cleaned temporary directory.
Keep using the same terminal. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-distribution-metadata.py:
from importlib.metadata import distributions
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
info = Path(directory) / "example_reporter-1.2.0.dist-info"
info.mkdir()
(info / "METADATA").write_text(
"Metadata-Version: 2.1\nName: example-reporter\nVersion: 1.2.0\n"
"Requires-Dist: example-helper>=2\n", encoding="utf-8")
(info / "entry_points.txt").write_text(
"[console_scripts]\nreport-demo = example_reporter.cli:main\n", encoding="utf-8")
found = list(distributions(path=[directory]))
assert len(found) == 1
dist = found[0]
assert dist.metadata["Name"] == "example-reporter"
assert dist.version == "1.2.0"
print("Distribution:", dist.metadata["Name"])
print("Version:", dist.version)
print("Declared requirement:", dist.requires[0])
points = list(dist.entry_points.select(group="console_scripts"))
assert len(points) == 1
assert points[0].value == "example_reporter.cli:main"
print("Entry point:", points[0].name, "->", points[0].value)
assert dist.files is None
print("File inventory unavailable:", dist.files is None)Run it:
python3 -B demonstrate-distribution-metadata.pyObserved output:
Distribution: example-reporter
Version: 1.2.0
Declared requirement: example-helper>=2
Entry point: report-demo -> example_reporter.cli:main
File inventory unavailable: TrueRead the result
The explicit path confines discovery to the fixture. Distribution names, versions, requirements, and entry-point declarations are metadata; reading them does not import example_reporter. The fixture intentionally omits an installed-file inventory, so files is None. That absence must not be confused with a verified empty installation.
Apply it carefully
A distribution name is not necessarily its import name. Declared dependencies are not proof that those dependencies are installed or compatible. Calling an entry point’s load() would import its target and execute import-time code; this inspection does not call it. The fixture illustrates metadata reading, not how to install a real distribution. In an actual environment, version("distribution-name") can raise PackageNotFoundError and should be handled explicitly.
The official reference describes the API and its options. The checks above cover the specific fixture, not every possible input or environment.
Clean up
Remove the source and then the empty practice directory:
rm -- demonstrate-distribution-metadata.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect the remaining files rather than deleting unknown contents.
Acknowledgements
This post was created with assistance from AI.