CodeSampleX

示例

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

已验证示例 — pypi packaging 24.2: Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2. contract 在 python…

sha256:f19dcaeb076fa504e3311b3a1df2fe75cfd5dc594f854b9f3986ce8a6589402a

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
3
构建过它的签名密钥
3
声明的环境 python linux x64 python python pip

验证运行环境

环境 契约 阶段 运行日期
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

案例

HOW
目标
Auto-enable prerelease matching for '>' and '<' specifiers containing prereleases fixed in packaging 24.2
包
符号
  • packaging.specifiers.Specifier
  • packaging.specifiers.SpecifierSet
环境
python
创建时间
2026-08-16T04:51:42Z

契约

  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']

文件

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

下载源代码构件 (tar.gz)

源代码

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")

原始种子者

anonymous