Exemplo
importlib-metadata 9.0.0: Resolve installed package versions when distribution names differ from top-level import names without PackageNotFoundError
Amostra verificada para pypi importlib-metadata 9.0.0: Resolve installed package versions when distribution names differ from top-level import names without…
sha256:beb8b3121c3cddc83a0038650f092bd1609123c82e31e1209dc60f07e688d56f
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 3
- Chaves de assinatura que o compilaram
- 3
Ambiente declarado
python linux x64 python python pip
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-15 |
| python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-18 |
| python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104… |
2026-09-08 |
Caso
HOW- Objetivo
- Resolve installed package versions when distribution names differ from top-level import names without PackageNotFoundError
- Pacotes
- Símbolos
-
- importlib_metadata.version
- importlib_metadata.PackageNotFoundError
- importlib_metadata.packages_distributions
- importlib_metadata.distribution
- Ambiente
- python
- Criado
- 2026-08-16T06:31:23Z
Contrato
- assert version() queries distribution name and raises PackageNotFoundError when given top-level import package name
- assert PackageNotFoundError inherits from ModuleNotFoundError and ImportError but not KeyError
- assert distribution name normalization under PEP 503 equates hyphens, underscores, dots, and case variants
- assert packages_distributions() maps import package names to list of distribution names
- assert passing module object or non-string to version() raises TypeError
Arquivos
- NOTES.md
- csx.json
- requirements.txt
- src/__init__.py
- src/resolver.py
- test/contract.py
Código-fonte
# importlib-metadata Distribution Name vs Import Name Traps
## CSX Search Result
`search_known_solution` answered MISS (no existing samples found for `importlib-metadata` distribution-vs-import package name resolution; returned unrelated alternatives).
## What a Model Would Have Written Instead
A model would assume that `importlib_metadata.version(name)` accepts the top-level Python import package name (such as `version("yaml")`, `version("PIL")`, `version("sklearn")`) or imported module objects (`version(mod)`), expecting it to return the version directly or return `None`/`KeyError` if absent.
## How the Wrong Version Fails
It fails loudly at runtime with `importlib_metadata.PackageNotFoundError` whenever the top-level import name differs from the installed distribution name (even when the module is imported and functioning), and fails with `TypeError` if passed a module object instead of a string.
{"case":{"caseId":"case:sha256:eefb19e24a51e90936bad25255107c269b62ef1ee7ee776eb6006475252aac08","constraints":{"runtime":"python"},"contract":["assert version() queries distribution name and raises PackageNotFoundError when given top-level import package name","assert PackageNotFoundError inherits from ModuleNotFoundError and ImportError but not KeyError","assert distribution name normalization under PEP 503 equates hyphens, underscores, dots, and case variants","assert packages_distributions() maps import package names to list of distribution names","assert passing module object or non-string to version() raises TypeError"],"goal":"Resolve installed package versions when distribution names differ from top-level import names without PackageNotFoundError","kind":"HOW","packages":["pkg:pypi/importlib-metadata@9.0.0","pkg:pypi/zipp@4.1.0"],"schemaVersion":1,"symbols":["importlib_metadata.version","importlib_metadata.PackageNotFoundError","importlib_metadata.packages_distributions","importlib_metadata.distribution"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/importlib-metadata@9.0.0","pkg:pypi/zipp@4.1.0"],"schemaVersion":1,"symbols":["importlib_metadata.version","importlib_metadata.PackageNotFoundError","importlib_metadata.packages_distributions","importlib_metadata.distribution"],"verifierAdapter":"python@1"}
importlib-metadata==9.0.0
zipp==4.1.0
"""Package initialization."""
"""Distribution and import package metadata version resolver utilities."""
from typing import List, Optional, Tuple, Union
import importlib_metadata
def resolve_distribution_version(distribution_name: str) -> str:
"""Retrieve the version for an installed distribution name.
Distribution names are normalized (case-insensitive, hyphens/underscores/dots
are equivalent under PEP 503). Raises PackageNotFoundError if not installed.
"""
return importlib_metadata.version(distribution_name)
def resolve_import_package_version(import_name: str) -> List[Tuple[str, str]]:
"""Resolve distribution versions for a top-level Python import package name.
Top-level import package names (e.g. 'yaml', 'PIL', 'sklearn') differ from
their distribution names ('PyYAML', 'Pillow', 'scikit-learn').
Directly calling version(import_name) raises PackageNotFoundError.
This function queries packages_distributions() to find the distribution name(s),
then retrieves their versions.
"""
pkg_to_dists = importlib_metadata.packages_distributions()
dist_names = pkg_to_dists.get(import_name, [])
results: List[Tuple[str, str]] = []
for dist_name in dist_names:
ver = importlib_metadata.version(dist_name)
results.append((dist_name, ver))
return results
def safe_get_version(target: Union[str, object]) -> Optional[str]:
"""Safely obtain package version given either a distribution name or an import name.
Returns the resolved version string, or None if no distribution metadata is found.
Raises TypeError if target is not a string.
"""
if not isinstance(target, str):
raise TypeError(f"Expected str, got {type(target).__name__}")
try:
return importlib_metadata.version(target)
except importlib_metadata.PackageNotFoundError:
# Fall back to looking up import name in packages_distributions
pkg_to_dists = importlib_metadata.packages_distributions()
dist_names = pkg_to_dists.get(target)
if dist_names:
return importlib_metadata.version(dist_names[0])
return None
import os
import shutil
import sys
import tempfile
# Ensure project root is in sys.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import importlib_metadata
from src.resolver import (
resolve_distribution_version,
resolve_import_package_version,
safe_get_version,
)
def create_fixture_distribution(
base_dir: str, dist_name: str, version: str, top_level_modules: list
) -> None:
"""Create a minimal .dist-info fixture directory on sys.path."""
safe_name = dist_name.replace("-", "_")
dist_info_dir = os.path.join(base_dir, f"{safe_name}-{version}.dist-info")
os.makedirs(dist_info_dir, exist_ok=True)
with open(os.path.join(dist_info_dir, "METADATA"), "w", encoding="utf-8") as f:
f.write(f"Metadata-Version: 2.1\nName: {dist_name}\nVersion: {version}\n")
with open(os.path.join(dist_info_dir, "top_level.txt"), "w", encoding="utf-8") as f:
for mod in top_level_modules:
f.write(f"{mod}\n")
# Set up an isolated temporary directory with custom distribution fixtures
temp_dir = tempfile.mkdtemp()
try:
# Fixture 1: Distribution name 'Custom-Toolkit' provides import package 'toolkit_core'
create_fixture_distribution(temp_dir, "Custom-Toolkit", "3.2.1", ["toolkit_core"])
# Fixture 2: Namespace package 'shared_ns' provided by two distributions
create_fixture_distribution(temp_dir, "Plugin-Alpha", "1.0.0", ["shared_ns"])
create_fixture_distribution(temp_dir, "Plugin-Beta", "2.0.0", ["shared_ns"])
sys.path.insert(0, temp_dir)
# -----------------------------------------------------------------------------
# 1. Distribution Name vs Import Name Trap
# Naive model expectation: version("toolkit_core") returns "3.2.1" because
# toolkit_core is the imported module name.
# importlib-metadata reality: version() accepts ONLY distribution names. Passing
# the top-level import name raises PackageNotFoundError.
# -----------------------------------------------------------------------------
assert resolve_distribution_version("Custom-Toolkit") == "3.2.1"
raised_package_not_found = False
try:
importlib_metadata.version("toolkit_core")
except importlib_metadata.PackageNotFoundError:
raised_package_not_found = True
assert raised_package_not_found, (
"Calling version() with top-level import name must raise PackageNotFoundError"
)
# -----------------------------------------------------------------------------
# 2. Exception Hierarchy Trap
# Naive model expectation: Mismatches raise KeyError (like dict lookup) or
# ValueError.
# importlib-metadata reality: PackageNotFoundError inherits from ModuleNotFoundError
# and ImportError, but NOT KeyError.
# -----------------------------------------------------------------------------
assert issubclass(importlib_metadata.PackageNotFoundError, ModuleNotFoundError)
assert issubclass(importlib_metadata.PackageNotFoundError, ImportError)
assert not issubclass(importlib_metadata.PackageNotFoundError, KeyError)
# -----------------------------------------------------------------------------
# 3. PEP 503 / PEP 566 Distribution Name Normalization
# Naive model expectation: Lookup is strict case-sensitive string matching where
# hyphens and underscores are incompatible.
# importlib-metadata reality: All punctuation (-, _, .) and case variants of
# a distribution name normalize to the same distribution.
# -----------------------------------------------------------------------------
assert resolve_distribution_version("custom-toolkit") == "3.2.1"
assert resolve_distribution_version("CUSTOM_TOOLKIT") == "3.2.1"
assert resolve_distribution_version("custom.toolkit") == "3.2.1"
# Real installed distribution normalization check
assert resolve_distribution_version("importlib-metadata") == "9.0.0"
assert resolve_distribution_version("importlib_metadata") == "9.0.0"
assert resolve_distribution_version("IMPORTLIB-METADATA") == "9.0.0"
# -----------------------------------------------------------------------------
# 4. Resolving Import Names via packages_distributions()
# Naive model expectation: packages_distributions() returns a 1:1 dict[str, str].
# importlib-metadata reality: It returns dict[str, list[str]] because multiple
# distributions can provide the same top-level package or namespace.
# -----------------------------------------------------------------------------
resolved_single = resolve_import_package_version("toolkit_core")
assert resolved_single == [("Custom-Toolkit", "3.2.1")]
resolved_multi = resolve_import_package_version("shared_ns")
assert len(resolved_multi) == 2
assert ("Plugin-Alpha", "1.0.0") in resolved_multi
assert ("Plugin-Beta", "2.0.0") in resolved_multi
# safe_get_version resolves both distribution names and import package names
assert safe_get_version("Custom-Toolkit") == "3.2.1"
assert safe_get_version("toolkit_core") == "3.2.1"
assert safe_get_version("nonexistent_pkg") is None
# -----------------------------------------------------------------------------
# 5. Non-String / Module Object Input Trap
# Naive model expectation: Passing an imported module object (e.g. version(mod))
# reads mod.__version__.
# importlib-metadata reality: version() accepts only string names; passing a module
# or non-string raises TypeError.
# -----------------------------------------------------------------------------
raised_type_error = False
try:
importlib_metadata.version(importlib_metadata)
except TypeError:
raised_type_error = True
assert raised_type_error, "Passing module object to version() must raise TypeError"
raised_type_error_int = False
try:
safe_get_version(12345)
except TypeError:
raised_type_error_int = True
assert raised_type_error_int, "Passing non-string must raise TypeError"
print("CONTRACT PASS: importlib-metadata distribution vs import name resolution verified")
finally:
if temp_dir in sys.path:
sys.path.remove(temp_dir)
shutil.rmtree(temp_dir, ignore_errors=True)