CodeSampleX

Exemplo

packaging 24.2: Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2

Amostra verificada para pypi packaging 24.2: Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2. O…

sha256:f19dcaeb076fa504e3311b3a1df2fe75cfd5dc594f854b9f3986ce8a6589402a

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-16
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
Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2
Pacotes
Símbolos
  • packaging.specifiers.Specifier
  • packaging.specifiers.SpecifierSet
Ambiente
python
Criado
2026-08-16T04:51:42Z

Contrato

  1. assert Specifier('>2.0a1').prereleases is True
  2. assert Specifier('<2.0a1').prereleases is True
  3. assert Specifier('>1.0.dev1').prereleases is True
  4. assert Specifier('<1.0.dev1').prereleases is True
  5. assert Specifier('>2.0a1').contains('3.0a2') is True
  6. assert Specifier('<2.0a1').contains('1.0a2') is True
  7. assert list(Specifier('>2.0a1').filter(['2.0a1', '3.0a2', '3.0'])) == ['3.0a2', '3.0']
  8. assert list(Specifier('<2.0a1').filter(['1.0a2', '1.0', '2.0a1'])) == ['1.0a2', '1.0']
  9. assert SpecifierSet('>2.0a1').prereleases is True
  10. assert SpecifierSet('<2.0a1').prereleases is True
  11. assert SpecifierSet('>2.0a1').contains('3.0a2') is True
  12. assert SpecifierSet('<2.0a1').contains('1.0a2') is True
  13. assert list(SpecifierSet('>2.0a1').filter(['2.0a1', '3.0a2', '3.0'])) == ['3.0a2', '3.0']
  14. assert list(SpecifierSet('<2.0a1').filter(['1.0a2', '1.0', '2.0a1'])) == ['1.0a2', '1.0']

Arquivos

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

Baixar o artefato de código-fonte (tar.gz)

Código-fonte

NOTES.md
# Packaging 24.2 Bugfix: Prerelease Detection for `>` and `<` Specifiers

## CSX Search Result
Calling `search_known_solution` returned a HIT on existing sample `sha256:2158f71f8f0182e574ebf8c6a651b8c00cc0e084fe82523db391f8d026016a3c` ("Evaluate prereleases, epochs, and local versions in SpecifierSet without falling into PEP 440 exclusion traps" on `pkg:pypi/packaging@24.1`). That sample tests general version-independent PEP 440 exclusion and epoch rules. This sample specifically targets and proves the patch release bugfix introduced in `packaging 24.2`.

## Target Release & Release Notes
- **Release**: `packaging==24.2` (released November 8, 2024)
- **Changelog / Release Notes**:
  - `Fix prerelease detection for > and < by @notatallshaw in https://github.com/pypa/packaging/pull/794`
  - Issue: https://github.com/pypa/packaging/issues/788

## Behaviour Before (`packaging <= 24.1`)
Under PEP 440 specification rules, if any clause in a version specifier explicitly includes a pre-release (for example `>2.0a1` or `<2.0a1`), pre-release matching MUST be auto-enabled by default (`spec.prereleases == True`).

In `packaging 24.1` and earlier, `Specifier.prereleases` only inspected a hardcoded list of operators:
```python
if operator in ["==", ">=", "<=", "~=", "==="]:
    ...
```
Because `>` and `<` were omitted from this check:
- `Specifier(">2.0a1").prereleases` evaluated to `False`.
- `Specifier("<2.0a1").prereleases` evaluated to `False`.
- `Specifier(">2.0a1").contains("3.0a2")` returned `False` because prospective pre-releases were filtered out when `prereleases` defaulted to `False`.
- `Specifier("<2.0a1").contains("1.0a2")` returned `False`.
- `list(Specifier(">2.0a1").filter(["2.0a1", "3.0a2", "3.0"]))` returned `["3.0"]`, dropping valid candidate `3.0a2`.
- `list(Specifier("<2.0a1").filter(["1.0a2", "1.0", "2.0a1"]))` returned `["1.0"]`, dropping valid candidate `1.0a2`.
- `SpecifierSet(">2.0a1").prereleases` returned `False` and `SpecifierSet(">2.0a1").contains("3.0a2")` returned `False`.

## Behaviour Now (`packaging >= 24.2`)
In `packaging 24.2` (PR #794), the operator check in `Specifier.prereleases` was updated:
```python
if operator in ["==", ">=", "<=", "~=", "===", ">", "<"]:
    ...
```
Now:
- `Specifier(">2.0a1").prereleases` evaluates to `True`.
- `Specifier("<2.0a1").prereleases` evaluates to `True`.
- `Specifier(">2.0a1").contains("3.0a2")` evaluates to `True`.
- `Specifier("<2.0a1").contains("1.0a2")` evaluates to `True`.
- `list(Specifier(">2.0a1").filter(["2.0a1", "3.0a2", "3.0"]))` preserves `["3.0a2", "3.0"]`.
- `list(Specifier("<2.0a1").filter(["1.0a2", "1.0", "2.0a1"]))` preserves `["1.0a2", "1.0"]`.
- `SpecifierSet(">2.0a1").prereleases` evaluates to `True` and `SpecifierSet(">2.0a1").contains("3.0a2")` evaluates to `True`.

## How the Broken Version Fails
In a dependency resolver or version selector, `packaging <= 24.1` fails **silently** at runtime: no exception is thrown, but valid matching pre-release packages are omitted from `.contains()` and `.filter()` results, producing empty candidate lists or falsely claiming unsatisfied requirements. Against this contract suite's assertions, `packaging <= 24.1` fails loudly with `AssertionError` on every single test case.
csx.json
{"case":{"caseId":"case:sha256:c733f419da533a73bbc07df2d37e27a4758e8348e15c790510f077d4e6a9ac98","contract":["assert Specifier('\u003e2.0a1').prereleases is True","assert Specifier('\u003c2.0a1').prereleases is True","assert Specifier('\u003e1.0.dev1').prereleases is True","assert Specifier('\u003c1.0.dev1').prereleases is True","assert Specifier('\u003e2.0a1').contains('3.0a2') is True","assert Specifier('\u003c2.0a1').contains('1.0a2') is True","assert list(Specifier('\u003e2.0a1').filter(['2.0a1', '3.0a2', '3.0'])) == ['3.0a2', '3.0']","assert list(Specifier('\u003c2.0a1').filter(['1.0a2', '1.0', '2.0a1'])) == ['1.0a2', '1.0']","assert SpecifierSet('\u003e2.0a1').prereleases is True","assert SpecifierSet('\u003c2.0a1').prereleases is True","assert SpecifierSet('\u003e2.0a1').contains('3.0a2') is True","assert SpecifierSet('\u003c2.0a1').contains('1.0a2') is True","assert list(SpecifierSet('\u003e2.0a1').filter(['2.0a1', '3.0a2', '3.0'])) == ['3.0a2', '3.0']","assert list(SpecifierSet('\u003c2.0a1').filter(['1.0a2', '1.0', '2.0a1'])) == ['1.0a2', '1.0']"],"goal":"Auto-enable prerelease matching for '\u003e' and '\u003c' specifiers containing prereleases fixed in packaging 24.2","kind":"HOW","packages":["pkg:pypi/packaging@24.2"],"schemaVersion":1,"symbols":["packaging.specifiers.Specifier","packaging.specifiers.SpecifierSet"]},"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.specifiers.Specifier","packaging.specifiers.SpecifierSet"],"verifierAdapter":"python@1"}
requirements.txt
packaging==24.2
src/__init__.py
"""Package initialization."""
src/specifier_check.py
"""Helper utilities for evaluating PEP 440 specifiers and prerelease detection."""

from typing import Iterable, List
from packaging.specifiers import Specifier, SpecifierSet


def allows_prereleases(spec_str: str) -> bool:
    """Check if the given specifier implicitly enables prerelease matching."""
    return Specifier(spec_str).prereleases is True


def contains_version(spec_str: str, version_str: str) -> bool:
    """Check if specifier matches version under default prerelease configuration."""
    return Specifier(spec_str).contains(version_str)


def filter_versions(spec_str: str, versions: Iterable[str]) -> List[str]:
    """Filter candidate version strings using the given specifier."""
    return list(Specifier(spec_str).filter(versions))


def specifier_set_allows_prereleases(spec_str: str) -> bool:
    """Check if SpecifierSet implicitly enables prerelease matching."""
    return SpecifierSet(spec_str).prereleases is True


def specifier_set_contains(spec_str: str, version_str: str) -> bool:
    """Check if SpecifierSet matches version under default prerelease configuration."""
    return SpecifierSet(spec_str).contains(version_str)


def specifier_set_filter(spec_str: str, versions: Iterable[str]) -> List[str]:
    """Filter candidate version strings using SpecifierSet."""
    return list(SpecifierSet(spec_str).filter(versions))
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 src.specifier_check import (
    allows_prereleases,
    contains_version,
    filter_versions,
    specifier_set_allows_prereleases,
    specifier_set_contains,
    specifier_set_filter,
)

# -----------------------------------------------------------------------------
# packaging 24.2 Bugfix Verification:
# Fix prerelease detection for '>' and '<' (PR #794, Issue #788)
#
# PEP 440 specification rule:
# If a specifier includes an explicit pre-release in any clause (e.g. >2.0a1),
# pre-release matching is implicitly activated (prereleases is True).
#
# In packaging <= 24.1:
# Specifier.prereleases checked only ['==', '>=', '<=', '~=', '==='],
# omitting '>' and '<'. Thus Specifier('>2.0a1').prereleases returned False,
# which caused contains() and filter() to silently drop candidate prereleases.
#
# In packaging >= 24.2:
# Specifier.prereleases includes '>' and '<', properly enabling prerelease
# candidate matching by default.
# -----------------------------------------------------------------------------

# 1. Specifier.prereleases property must be True for '>' and '<' with prerelease bounds
assert allows_prereleases(">2.0a1") is True, "Specifier('>2.0a1').prereleases must be True"
assert allows_prereleases("<2.0a1") is True, "Specifier('<2.0a1').prereleases must be True"
assert allows_prereleases(">1.0.dev1") is True, "Specifier('>1.0.dev1').prereleases must be True"
assert allows_prereleases("<1.0.dev1") is True, "Specifier('<1.0.dev1').prereleases must be True"

# 2. Specifier.contains() must match candidate prereleases when bound contains a prerelease
assert contains_version(">2.0a1", "3.0a2") is True, "Specifier('>2.0a1').contains('3.0a2') must be True"
assert contains_version("<2.0a1", "1.0a2") is True, "Specifier('<2.0a1').contains('1.0a2') must be True"

# 3. Specifier.filter() must retain candidate prereleases when bound contains a prerelease
assert filter_versions(">2.0a1", ["2.0a1", "3.0a2", "3.0"]) == ["3.0a2", "3.0"], (
    "Specifier('>2.0a1').filter() must include '3.0a2'"
)
assert filter_versions("<2.0a1", ["1.0a2", "1.0", "2.0a1"]) == ["1.0a2", "1.0"], (
    "Specifier('<2.0a1').filter() must include '1.0a2'"
)

# 4. SpecifierSet auto-prerelease activation and evaluation for '>' and '<'
assert specifier_set_allows_prereleases(">2.0a1") is True, "SpecifierSet('>2.0a1').prereleases must be True"
assert specifier_set_allows_prereleases("<2.0a1") is True, "SpecifierSet('<2.0a1').prereleases must be True"
assert specifier_set_contains(">2.0a1", "3.0a2") is True, "SpecifierSet('>2.0a1').contains('3.0a2') must be True"
assert specifier_set_contains("<2.0a1", "1.0a2") is True, "SpecifierSet('<2.0a1').contains('1.0a2') must be True"
assert specifier_set_filter(">2.0a1", ["2.0a1", "3.0a2", "3.0"]) == ["3.0a2", "3.0"], (
    "SpecifierSet('>2.0a1').filter() must include '3.0a2'"
)
assert specifier_set_filter("<2.0a1", ["1.0a2", "1.0", "2.0a1"]) == ["1.0a2", "1.0"], (
    "SpecifierSet('<2.0a1').filter() must include '1.0a2'"
)

print("CONTRACT PASS: packaging 24.2 '>' and '<' prerelease detection verified")

Seeder de origem

anonymous