Beispiel
packaging 24.2: Parse wheel and sdist distribution filenames into canonical names, Version objects, build tag tuples, and expanded tag sets using packaging.utils
Verifiziertes Beispiel für pypi packaging 24.2: Parse wheel and sdist distribution filenames into canonical names, Version objects, build tag tuples, and…
sha256:ee011019fcbe1934eb1046b1776996e547b79794ee7d9ae4e4e71982a6a12b18
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 3
- Signaturschlüssel, die es gebaut haben
- 3
Deklarierte Umgebung
python linux x64 python python pip
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-17 |
| 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 |
Fall
HOW- Ziel
- Parse wheel and sdist distribution filenames into canonical names, Version objects, build tag tuples, and expanded tag sets using packaging.utils
- Pakete
- Symbole
-
- packaging.utils.parse_wheel_filename
- packaging.utils.parse_sdist_filename
- packaging.utils.canonicalize_name
- Umgebung
- python
- Erstellt
- 2026-08-17T19:41:39Z
Contract
- parse_wheel_filename returns a 4-tuple of canonicalized name, parsed Version, integer-prefixed build tag tuple, and Cartesian-product expanded Tag frozenset, rejecting build tags without a leading digit.
- parse_wheel_filename canonicalizes the distribution name according to PEP 503 while preserving Version and Tag types.
- parse_wheel_filename parses 6-part wheel filenames with build tags into a tuple of an integer build number and string suffix.
- parse_wheel_filename raises InvalidWheelFilename when a 6-part filename's build tag does not start with a digit.
- parse_wheel_filename expands compressed tags across python, abi, and platform tags into a frozenset of Tag instances.
- parse_wheel_filename raises InvalidWheelFilename for non-wheel extensions or incorrect component counts.
- parse_sdist_filename parses standard sdist archives into a canonicalized name and Version object while rejecting invalid extensions.
Dateien
- NOTES.md
- csx.json
- requirements.txt
- test/contract.py
Quelltext
# Packaging 24.2 Distribution Filename Parsing and Canonicalization
## Known Solutions Search
A search for existing verified samples for `packaging` at version 24.2 returned three matches focusing on `SpecifierSet` and prerelease handling:
- `sha256:f19dcaeb076fa504e3311b3a1df2fe75cfd5dc594f854b9f3986ce8a6589402a`: Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2
- `sha256:3808772890fedf57c4befd649f16e9078db6809d220103615d71d5ea553d4f50`: Demonstrate that SpecifierSet.contains excludes semantically matching pre-releases by default
- `sha256:2158f71f8f0182e574ebf8c6a651b8c00cc0e084fe82523db391f8d026016a3c`: Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps
To provide distinct coverage within the library, this sample proves the behavior of distribution filename parsing (`parse_wheel_filename`, `parse_sdist_filename`) and name canonicalization in `packaging.utils`.
## Pinned Release
- `packaging==24.2` (`pkg:pypi/packaging@24.2`)
## Observed Behaviour
1. **Wheel Filename Parsing Tuple Structure**:
`packaging.utils.parse_wheel_filename` accepts a PEP 427 wheel filename and returns a 4-tuple: `(name: NormalizedName, version: Version, build: BuildTag, tags: FrozenSet[Tag])`.
2. **PEP 503 Name Canonicalization**:
The distribution name returned by `parse_wheel_filename` is canonicalized according to PEP 503 rules (lowercased and character runs of `[-_.]+` replaced with a single hyphen `-`).
3. **PEP 427 Build Tag Parsing and Validation**:
When a 6-part wheel filename includes a build tag, the build tag is parsed into a 2-tuple `(int, str)` where the first element is the integer build number and the second is the remaining string suffix (for example, `1rc2` becomes `(1, "rc2")`, and `1` becomes `(1, "")`). If the build tag does not start with an integer digit (such as `beta`), `InvalidWheelFilename` is raised loudly. Wheels without build tags return an empty tuple `()`.
4. **Cartesian Product Tag Expansion**:
Compressed wheel tags (such as `py2.py3-none-any` or multi-platform combinations) are expanded via Cartesian product into individual `packaging.tags.Tag` objects inside a `frozenset`.
5. **Source Distribution Parsing**:
`packaging.utils.parse_sdist_filename` parses standard `.tar.gz` and `.zip` archive names into a canonicalized name and a `Version` instance, rejecting `.whl` files or malformed names with `InvalidSdistFilename`.
## Failure Mode for Naive Assumptions
- Naive code assuming `parse_wheel_filename` returns raw strings or preserves original casing in distribution names fails assertions because names are normalized and versions/tags are returned as rich objects (`Version`, `Tag`).
- Code passing non-numeric build tags to wheel generators/parsers expecting them to be treated as plain string tags fails loudly with `InvalidWheelFilename`.
{"case":{"believed":"parse_wheel_filename preserves unnormalized distribution names and parses build tags as plain strings or leaves compressed wheel tags unexpanded","caseId":"case:sha256:da82f2398c5483667648b3e7f7b6be62fe7c078bcad1fc110ade574328d33e9a","contract":["parse_wheel_filename returns a 4-tuple of canonicalized name, parsed Version, integer-prefixed build tag tuple, and Cartesian-product expanded Tag frozenset, rejecting build tags without a leading digit.","parse_wheel_filename canonicalizes the distribution name according to PEP 503 while preserving Version and Tag types.","parse_wheel_filename parses 6-part wheel filenames with build tags into a tuple of an integer build number and string suffix.","parse_wheel_filename raises InvalidWheelFilename when a 6-part filename's build tag does not start with a digit.","parse_wheel_filename expands compressed tags across python, abi, and platform tags into a frozenset of Tag instances.","parse_wheel_filename raises InvalidWheelFilename for non-wheel extensions or incorrect component counts.","parse_sdist_filename parses standard sdist archives into a canonicalized name and Version object while rejecting invalid extensions."],"goal":"Parse wheel and sdist distribution filenames into canonical names, Version objects, build tag tuples, and expanded tag sets using packaging.utils","kind":"HOW","packages":["pkg:pypi/packaging@24.2"],"schemaVersion":1,"symbols":["packaging.utils.parse_wheel_filename","packaging.utils.parse_sdist_filename","packaging.utils.canonicalize_name"]},"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/packaging@24.2"],"schemaVersion":1,"symbols":["packaging.utils.parse_wheel_filename","packaging.utils.parse_sdist_filename","packaging.utils.canonicalize_name"],"verifierAdapter":"python@1"}
packaging==24.2
from packaging.tags import Tag
from packaging.utils import (
InvalidSdistFilename,
InvalidWheelFilename,
canonicalize_name,
parse_sdist_filename,
parse_wheel_filename,
)
from packaging.version import Version
def test_parse_standard_wheel_filename():
filename = "Distribution_Name-1.0.0-py2.py3-none-any.whl"
name, version, build, tags = parse_wheel_filename(filename)
# Name is canonicalized according to PEP 503 (lowercased and underscores to dashes)
assert name == "distribution-name"
assert isinstance(name, str)
# Version is parsed as a Version instance
assert version == Version("1.0.0")
assert isinstance(version, Version)
# Wheel without build tag has an empty tuple build tag
assert build == ()
# Compressed tags 'py2.py3' expand into individual Tag objects in a frozenset
assert isinstance(tags, frozenset)
assert len(tags) == 2
assert Tag("py2", "none", "any") in tags
assert Tag("py3", "none", "any") in tags
def test_parse_wheel_with_build_tag_and_tag_expansion():
filename = "Distribution_Name-2.1.0-1rc2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
name, version, build, tags = parse_wheel_filename(filename)
assert name == "distribution-name"
assert version == Version("2.1.0")
# Build tag is parsed into a 2-tuple of (int, str)
assert build == (1, "rc2")
# Cartesian product expansion of 1 python tag x 1 abi tag x 2 platform tags = 2 tags
assert len(tags) == 2
assert Tag("cp310", "abi3", "manylinux_2_17_x86_64") in tags
assert Tag("cp310", "abi3", "manylinux2014_x86_64") in tags
def test_invalid_build_tag_rejected():
# PEP 427 mandates build numbers start with a digit; non-digit build tags raise InvalidWheelFilename
invalid_filename = "Distribution_Name-1.0.0-beta-py3-none-any.whl"
try:
parse_wheel_filename(invalid_filename)
raise AssertionError("Expected InvalidWheelFilename for non-digit build tag")
except InvalidWheelFilename:
pass
def test_invalid_wheel_filenames_rejected():
# Invalid extension
try:
parse_wheel_filename("package-1.0.0-py3-none-any.tar.gz")
raise AssertionError("Expected InvalidWheelFilename for non-.whl extension")
except InvalidWheelFilename:
pass
# Invalid component count (too few segments)
try:
parse_wheel_filename("package-1.0.0-any.whl")
raise AssertionError("Expected InvalidWheelFilename for too few components")
except InvalidWheelFilename:
pass
# Invalid component count (too many segments)
try:
parse_wheel_filename("package-1.0.0-1-2-py3-none-any.whl")
raise AssertionError("Expected InvalidWheelFilename for too many components")
except InvalidWheelFilename:
pass
def test_parse_sdist_filename():
name, version = parse_sdist_filename("Foo_Bar-1.2.3a4.tar.gz")
assert name == "foo-bar"
assert version == Version("1.2.3a4")
name_zip, version_zip = parse_sdist_filename("Foo_Bar-2.0.0.zip")
assert name_zip == "foo-bar"
assert version_zip == Version("2.0.0")
try:
parse_sdist_filename("Foo_Bar-1.0.0.whl")
raise AssertionError("Expected InvalidSdistFilename for .whl extension")
except InvalidSdistFilename:
pass
try:
parse_sdist_filename("Foo_Bar.tar.gz")
raise AssertionError("Expected InvalidSdistFilename for missing version")
except InvalidSdistFilename:
pass
def test_canonicalize_name():
assert canonicalize_name("Foo._-BAR") == "foo-bar"
assert canonicalize_name("foo---bar") == "foo-bar"
assert canonicalize_name("foo.bar") == "foo-bar"
if __name__ == "__main__":
test_parse_standard_wheel_filename()
test_parse_wheel_with_build_tag_and_tag_expansion()
test_invalid_build_tag_rejected()
test_invalid_wheel_filenames_rejected()
test_parse_sdist_filename()
test_canonicalize_name()
print("All packaging.utils contract assertions passed.")