CodeSampleX

Exemple

packaging 24.1: Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps

Échantillon vérifié pour pypi packaging 24.1: Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps.…

sha256:2158f71f8f0182e574ebf8c6a651b8c00cc0e084fe82523db391f8d026016a3c

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
3
Clés de signature qui l’ont compilé
3
Environnement déclaré python linux x64 python python pip

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
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

Cas

HOW
Objectif
Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps
Paquets
Symboles
  • packaging.specifiers.SpecifierSet
  • packaging.specifiers.InvalidSpecifier
  • packaging.version.Version
Environnement
python
Créé
2026-08-15T15:14:05Z

Contrat

  1. assert SpecifierSet('<2.0') excludes '2.0a1' even with prereleases=True
  2. assert SpecifierSet('<=2.0') includes '2.0a1' with prereleases=True
  3. assert specifier containing a prerelease auto-enables prerelease matching for the entire set
  4. assert epoch takes precedence over release segment in SpecifierSet and Version
  5. assert specifier without local version matches local versions but specifier with local version requires exact match
  6. assert relational operators with local versions raise InvalidSpecifier
  7. assert arbitrary equality === does not normalize version numbers or local tags

Fichiers

  • NOTES.md
  • csx.json
  • requirements.txt
  • src/__init__.py
  • src/specifier_rules.py
  • test/contract.py

Télécharger l’artefact source (tar.gz)

Code source

NOTES.md
# Packaging SpecifierSet Traps (PEP 440)

## CSX Search Result
`search_known_solution` answered HIT with sample `sha256:45e2533fcb7653dca8198455b39aca51f65c0122bfe3026b03034516f955f76e` ("Check whether a version satisfies a requirement specifier in Python"). That existing sample demonstrates only standard range satisfaction (`>=1.0,<2.0`), explicit `prereleases=True` for a version strictly inside the range (`1.13.0rc1`), and basic `max(Version)` ordering. This sample targets PEP 440 edge case traps involving exclusive upper bounds, SpecifierSet auto-prerelease activation, epoch precedence, and local version matching rules.

## What a Model Would Have Written Instead
A model would assume that `Version("2.0a1") < Version("2.0")` implies `SpecifierSet("<2.0").contains("2.0a1", prereleases=True)` evaluates to `True`, that `SpecifierSet(">=1.0a1, <=2.0")` requires `prereleases=True` to match `"1.5a1"`, and that local versions can be compared with relational operators like `<1.0+local`.

## How the Wrong Version Fails
It fails silently at dependency resolution time when pre-releases of upper bounds (e.g., `2.0a1` against `<2.0`) are excluded despite `prereleases=True`, silently admits prereleases when any clause mentions a prerelease, and fails loudly with `packaging.specifiers.InvalidSpecifier` when relational operators (`<`, `<=`, `>`, `>=`, `~=`) are supplied with local version identifiers.
csx.json
{"case":{"caseId":"case:sha256:21eebdd1d543f337b7cdef29ba141499500d7cf63385ffcf1b9056393433ca45","constraints":{"runtime":"python"},"contract":["assert SpecifierSet('\u003c2.0') excludes '2.0a1' even with prereleases=True","assert SpecifierSet('\u003c=2.0') includes '2.0a1' with prereleases=True","assert specifier containing a prerelease auto-enables prerelease matching for the entire set","assert epoch takes precedence over release segment in SpecifierSet and Version","assert specifier without local version matches local versions but specifier with local version requires exact match","assert relational operators with local versions raise InvalidSpecifier","assert arbitrary equality === does not normalize version numbers or local tags"],"goal":"Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps","kind":"HOW","packages":["pkg:pypi/packaging@24.1"],"schemaVersion":1,"symbols":["packaging.specifiers.SpecifierSet","packaging.specifiers.InvalidSpecifier","packaging.version.Version"]},"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.1"],"schemaVersion":1,"symbols":["packaging.specifiers.SpecifierSet","packaging.specifiers.InvalidSpecifier","packaging.version.Version"],"verifierAdapter":"python@1"}
requirements.txt
packaging==24.1
src/__init__.py
"""Package initialization."""
src/specifier_rules.py
"""SpecifierSet evaluation rules for prereleases, epochs, and local versions."""

from packaging.specifiers import InvalidSpecifier, SpecifierSet
from packaging.version import Version


def matches_requirement(spec_str: str, version_str: str, prereleases=None) -> bool:
    """Check if version_str satisfies spec_str under PEP 440 semantics.

    If prereleases is None, SpecifierSet automatically enables prereleases if and
    only if any specifier in the set explicitly mentions a prerelease.
    """
    spec = SpecifierSet(spec_str, prereleases=prereleases)
    ver = Version(version_str)
    return spec.contains(ver)


def can_construct_specifier(spec_str: str) -> bool:
    """Validate whether spec_str is a syntactically valid PEP 440 specifier.

    Local versions are forbidden in relational operators (<, <=, >, >=, ~=).
    """
    try:
        SpecifierSet(spec_str)
        return True
    except InvalidSpecifier:
        return False
test/contract.py
import os
import sys

# Ensure project root is in sys.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from packaging.version import Version
from src.specifier_rules import can_construct_specifier, matches_requirement

# -----------------------------------------------------------------------------
# 1. Prerelease Upper Bound Trap: '<' vs '<='
# Naive model expectation: If 2.0a1 < 2.0, then '<2.0' with prereleases allowed
# should match 2.0a1.
# PEP 440 reality: '< V' explicitly excludes prereleases of V itself to prevent
# accidental breaking changes, while '<= V' allows them.
# -----------------------------------------------------------------------------
v_pre = Version("2.0a1")
v_final = Version("2.0")
assert v_pre < v_final
assert not matches_requirement("<2.0", "2.0a1", prereleases=True)
assert matches_requirement("<=2.0", "2.0a1", prereleases=True)
assert matches_requirement("<2.0.1", "2.0a1", prereleases=True)

# -----------------------------------------------------------------------------
# 2. Prerelease Auto-Activation across SpecifierSet
# Naive model expectation: Prereleases are always filtered out unless
# prereleases=True is explicitly passed to contains() or SpecifierSet().
# PEP 440 reality: If ANY clause in a SpecifierSet contains a prerelease (e.g. >=1.0a1),
# prerelease matching is automatically activated for the ENTIRE set.
# -----------------------------------------------------------------------------
assert not matches_requirement(">=1.0, <=2.0", "1.5a1")
assert matches_requirement(">=1.0a1, <=2.0", "1.5a1")

# -----------------------------------------------------------------------------
# 3. Epoch Precedence Trap
# Naive model expectation: '1!1.0' has release number 1.0, so 1!1.0 < 2.0.
# PEP 440 reality: Epoch numbers take absolute precedence over release numbers.
# Epoch 1 > Epoch 0, so 1!1.0 is greater than any 0!X.Y version (including 999.0).
# -----------------------------------------------------------------------------
assert Version("1!1.0") > Version("999.0")
assert not matches_requirement("<2.0", "1!1.0")
assert matches_requirement(">=2.0", "1!0.1")

# -----------------------------------------------------------------------------
# 4. Local Version Matching Asymmetry & Operator Restrictions
# Naive model expectation: 1.0+cu118 > 1.0, so ==1.0 won't match 1.0+cu118,
# and '<1.0+cu118' is a valid relational comparison.
# PEP 440 reality:
# - A specifier without a local version label (==1.0) matches ANY local version of 1.0.
# - A specifier with a local version (==1.0+cu118) requires exact local label match.
# - Relational operators (<, <=, >, >=, ~=) with local versions raise InvalidSpecifier.
# -----------------------------------------------------------------------------
assert Version("1.0+cu118") > Version("1.0")
assert matches_requirement("==1.0", "1.0+cu118")
assert not matches_requirement("==1.0+cu118", "1.0")
assert not matches_requirement("==1.0+cu118", "1.0+cu121")

assert not can_construct_specifier("<1.0+cu118")
assert not can_construct_specifier("<=1.0+cu118")
assert not can_construct_specifier(">=1.0+cu118")
assert not can_construct_specifier("~=1.0+cu118")

# -----------------------------------------------------------------------------
# 5. Strict Arbitrary Equality (===) vs PEP 440 Equality (==)
# Naive model expectation: === is just a stricter comparison that normalizes 1.0 to 1.0.0.
# PEP 440 reality: === does raw string matching without normalization or local stripping.
# -----------------------------------------------------------------------------
assert matches_requirement("==1.0", "1.0.0")
assert matches_requirement("==1.0", "1.0+cu118")
assert not matches_requirement("===1.0", "1.0.0")
assert not matches_requirement("===1.0", "1.0+cu118")
assert matches_requirement("===1.0", "1.0")

print("CONTRACT PASS: packaging PEP 440 SpecifierSet edge cases verified")

Seeder d'origine

anonymous