Read metadata from Python packages, providing third-party access to importlib.metadata functionality
npx @tessl/cli install tessl/pypi-importlib-metadata@8.7.0A library providing third-party access to the functionality of importlib.metadata, allowing Python applications to read metadata from installed packages. It serves as a backport and enhancement of the standard library's importlib.metadata module, offering compatibility across different Python versions and additional features.
The library enables developers to discover package metadata, entry points, files, and dependencies programmatically, making it essential for tools that need to introspect installed packages. It supports both modern package formats (dist-info) and legacy formats (egg-info), provides efficient path searching and caching mechanisms, and offers a comprehensive API for package discovery and metadata extraction.
pip install importlib_metadataimport importlib_metadataCommon imports for specific functionality:
from importlib_metadata import (
Distribution,
PackageNotFoundError,
distribution,
distributions,
entry_points,
files,
metadata,
packages_distributions,
requires,
version
)import importlib_metadata
# Get version of an installed package
pkg_version = importlib_metadata.version('requests')
print(f"requests version: {pkg_version}")
# Get distribution object for a package
dist = importlib_metadata.distribution('requests')
print(f"Package name: {dist.name}")
print(f"Version: {dist.version}")
# Get package metadata
meta = importlib_metadata.metadata('requests')
print(f"Summary: {meta['Summary']}")
print(f"Author: {meta['Author']}")
# Get entry points from all packages
eps = importlib_metadata.entry_points()
console_scripts = eps.select(group='console_scripts')
for ep in console_scripts:
print(f"Script: {ep.name} -> {ep.value}")
# Get files in a package
package_files = importlib_metadata.files('requests')
if package_files:
for file_path in package_files[:5]: # Show first 5 files
print(f"File: {file_path}")
# Get package dependencies
deps = importlib_metadata.requires('requests')
if deps:
for dep in deps:
print(f"Dependency: {dep}")The importlib_metadata library follows a layered architecture:
This design allows the library to work across different package installation methods, Python versions, and package formats while maintaining performance through caching and lazy loading.
Primary API functions for accessing package information including version lookup, distribution objects, metadata access, entry points, files, and dependencies.
def distribution(distribution_name: str) -> Distribution: ...
def distributions(**kwargs) -> Iterable[Distribution]: ...
def metadata(distribution_name: str) -> PackageMetadata | None: ...
def version(distribution_name: str) -> str: ...
def entry_points(**params) -> EntryPoints: ...
def files(distribution_name: str) -> list[PackagePath] | None: ...
def requires(distribution_name: str) -> list[str] | None: ...
def packages_distributions() -> Mapping[str, list[str]]: ...
``` { .api }
[Core Functions](./core-functions.md)
### Distribution Classes
Distribution classes provide object-oriented access to package metadata, including abstract base classes and concrete implementations for different package formats.
```python { .api }
class Distribution(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read_text(self, filename) -> str | None: ...
@abc.abstractmethod
def locate_file(self, path: str | os.PathLike[str]) -> SimplePath: ...
@classmethod
def from_name(cls, name: str) -> Distribution: ...
@classmethod
def discover(cls, *, context=None, **kwargs) -> Iterable[Distribution]: ...
@property
def metadata(self) -> PackageMetadata | None: ...
@property
def name(self) -> str: ...
@property
def version(self) -> str: ...Comprehensive entry point discovery and management, including entry point objects, collections, and selection mechanisms for package-defined executable scripts and plugins.
class EntryPoint:
name: str
value: str
group: str
dist: Distribution | None
def load(self) -> Any: ...
def matches(self, **params) -> bool: ...
class EntryPoints(tuple):
def select(self, **params) -> EntryPoints: ...
def __getitem__(self, name: str) -> EntryPoint: ...
@property
def names(self) -> set[str]: ...
@property
def groups(self) -> set[str]: ...File path handling and package file enumeration, including path objects, file hashing, and file access methods for package contents.
class PackagePath(pathlib.PurePosixPath):
hash: FileHash | None
size: int
dist: Distribution
def read_text(self, encoding: str = 'utf-8') -> str: ...
def read_binary(self) -> bytes: ...
def locate(self) -> SimplePath: ...
class FileHash:
mode: str
value: strCore type definitions used throughout the API:
class PackageNotFoundError(ModuleNotFoundError):
"""Exception raised when package metadata cannot be found."""
@property
def name(self) -> str: ...
# Protocol interfaces
class PackageMetadata(Protocol):
"""
Protocol for accessing package metadata as a mapping-like object.
This protocol defines the interface for metadata objects returned by
Distribution.metadata, providing dictionary-like access to package
metadata fields as defined by Python packaging standards.
"""
def __len__(self) -> int:
"""Return the number of metadata fields."""
def __contains__(self, item: str) -> bool:
"""Check if a metadata field exists."""
def __getitem__(self, key: str) -> str:
"""Get a metadata field value. Raises KeyError if not found."""
def __iter__(self) -> Iterator[str]:
"""Iterate over metadata field names."""
def get(self, name: str, failobj=None) -> str | None:
"""Get a metadata field value, returning failobj if not found."""
def get_all(self, name: str, failobj=None) -> list[Any] | None:
"""Get all values for a metadata field (for multi-valued fields)."""
@property
def json(self) -> dict[str, str | list[str]]:
"""Return metadata as a JSON-serializable dictionary."""
class SimplePath(Protocol):
"""
A minimal subset of pathlib.Path required by Distribution.
This protocol defines the interface that path objects must implement
to work with the importlib_metadata system. It provides the essential
path operations needed for accessing package files and metadata.
"""
def joinpath(self, other: str | os.PathLike[str]) -> SimplePath:
"""
Join this path with another path component.
Parameters:
- other: Path component to join
Returns:
SimplePath: New path with component joined
"""
def __truediv__(self, other: str | os.PathLike[str]) -> SimplePath:
"""
Path division operator (/) for joining paths.
Parameters:
- other: Path component to join
Returns:
SimplePath: New path with component joined
"""
@property
def parent(self) -> SimplePath:
"""
Return the parent directory of this path.
Returns:
SimplePath: Parent directory path
"""
def read_text(self, encoding=None) -> str:
"""
Read the file as text.
Parameters:
- encoding: Text encoding (optional, defaults to locale encoding)
Returns:
str: File contents as text
Raises:
FileNotFoundError: If file doesn't exist
UnicodeDecodeError: If file cannot be decoded as text
"""
def read_bytes(self) -> bytes:
"""
Read the file as binary data.
Returns:
bytes: File contents as bytes
Raises:
FileNotFoundError: If file doesn't exist
"""
def exists(self) -> bool:
"""
Check if the path exists.
Returns:
bool: True if path exists, False otherwise
"""