Breakwater

Sandboxes / 1082@61967cca

perf: fast path for simple versions (intermediate commit 61967cca)

pypa/packaging#1082 · merged 2026-02-11 · base 59f183fe90 → head 61967cca27 · ran on Sandboxes

BLOCK

At least one behaviour change looks like an unintended regression. A valid input family runs 2.86× the instructions of the old code.

Known regressions in this PR

Counterexamples · 5 groups of 6 classes: 4 likely bug, 2 needs a human

P2

Exception behaviour changed

known regression: inner-whitespaceknown regression: unicode-digits
inputVersion("1 .2")
baseraises InvalidVersion
headreturns normally
Likely bugvotes: 3 likely-bug

The fast path accepts spaces in the version string (e.g., '1 .2') because `strip()` removes leading/trailing spaces and `int()` ignores spaces around digits, whereas the regex rejects spaces. This is an unintended relaxation of the version syntax.

if _NON_SIMPLE_VERSION_INDICATORS.isdisjoint(version):
self._release = tuple(map(int, version.strip().split('.')))

Found by: Ultra's planned example, hostile mutation · also caught by: Mutations of the PR's own test strings, Nemotron plan only

ran onToken Factory Sandboxes · image 62d98fe8-9c1e-42e6-b250-ab6f630d8680

Regression test verified passes on base, fails on head
def test_1082_61967cca_p2_outcome_2():
    """Breakwater P2: base behaviour pinned (found by differential testing; label: likely-bug)."""
    import pytest
    from packaging.version import InvalidVersion, Version
    with pytest.raises(InvalidVersion) as excinfo:
        Version('1 .2')
    assert type(excinfo.value) is InvalidVersion  # exact type: a subclass would be a behaviour change
Reproduce
uv run breakwater probe --repo https://github.com/pypa/packaging --base 59f183fe90da --head 61967cca278d --target packaging.version:Version --backend contree --input "1 .2"
1 near-duplicate class same behaviour, inputs with extra traits
  • Version("١ .2") base raises InvalidVersion · head returns normallyunicode-digitsinner-whitespace test verified (also under another group)
P2

Exception behaviour changed

known regression: unicode-digitsknown regression: inner-whitespace
inputVersion("٠")
baseraises InvalidVersion
headreturns normally
Likely bugvotes: 3 likely-bug

The fast path accepts Unicode digits (e.g., Arabic-Indic '٠') because `int()` supports them, while the original regex only matches ASCII `[0-9]`. This expands accepted input beyond PEP 440 without documentation or tests.

_NON_SIMPLE_VERSION_INDICATORS = frozenset('!+-ABCDEHILOPRSTVW_abcdehiloprstvw')
if _NON_SIMPLE_VERSION_INDICATORS.isdisjoint(version):

Found by: Nemotron strategy search, Ultra's planned example, hostile mutation, search sample · also caught by: Nemotron plan only

ran onToken Factory Sandboxes · image 62d98fe8-9c1e-42e6-b250-ab6f630d8680

Regression test verified passes on base, fails on head
def test_1082_61967cca_p2_outcome_0():
    """Breakwater P2: base behaviour pinned (found by differential testing; label: likely-bug)."""
    import pytest
    from packaging.version import InvalidVersion, Version
    with pytest.raises(InvalidVersion) as excinfo:
        Version('٠')
    assert type(excinfo.value) is InvalidVersion  # exact type: a subclass would be a behaviour change
Reproduce
uv run breakwater probe --repo https://github.com/pypa/packaging --base 59f183fe90da --head 61967cca278d --target packaging.version:Version --backend contree --input "٠"
1 near-duplicate class same behaviour, inputs with extra traits
  • Version("١ .2") base raises InvalidVersion · head returns normallyunicode-digitsinner-whitespace test verified (also under another group)
P2

Exception behaviour changed

inputVersion(["..0"])
baseraises TypeError
headraises AttributeError

Neither exception type subclasses the other.

Likely bugvotes: 3 likely-bug

For non-string input (a list), the fast path bypasses the regex and calls `.strip()` on the list, raising `AttributeError` instead of the original `TypeError`. The PR does not intend to change error types for invalid input types.

if _NON_SIMPLE_VERSION_INDICATORS.isdisjoint(version):
self._release = tuple(map(int, version.strip().split('.')))

Found by: Nemotron strategy search · no baseline found it

ran onToken Factory Sandboxes · image 62d98fe8-9c1e-42e6-b250-ab6f630d8680

Regression test verified passes on base, errors on head
def test_1082_61967cca_p2_outcome_1():
    """Breakwater P2: base behaviour pinned (found by differential testing; label: likely-bug)."""
    import pytest
    from packaging.version import Version
    with pytest.raises(TypeError) as excinfo:
        Version(['..0'])
    assert type(excinfo.value) is TypeError  # exact type: a subclass would be a behaviour change
P2

Exception behaviour changed

known regression: inner-whitespaceknown regression: oversized-int-exception
inputVersion("100000000000000000000000000000000000000000…0000000 .2" (4,303 chars))
baseraises InvalidVersion
headreturns normally
Needs a humanvotes: 1 intended, 1 likely-bug, 1 needs-human (no majority)

The fast path accepts extremely long numbers that the regex rejects (likely due to regex engine limits). The PR is a perf refactor; no intent to change valid version set. PEP 440 doesn't forbid long numbers but the original behavior was to reject them.

Found by: hostile mutation · no baseline found it

ran onToken Factory Sandboxes · image 62d98fe8-9c1e-42e6-b250-ab6f630d8680

Regression test verified passes on base, fails on head
def test_1082_61967cca_p2_outcome_4():
    """Breakwater P2: base behaviour pinned (found by differential testing; label: needs-human)."""
    import pytest
    from packaging.version import InvalidVersion, Version
    with pytest.raises(InvalidVersion) as excinfo:
        Version('1' + '0' * 4299 + ' ' + '.' + '2')
    assert type(excinfo.value) is InvalidVersion  # exact type: a subclass would be a behaviour change
P2

Exception behaviour changed

known regression: oversized-int-exception
inputVersion("100000000000000000000000000000000000000000…000000.0.1" (4,305 chars))
baseraises ValueError
headraises InvalidVersion

Packaging.version.InvalidVersion is a subclass of builtins.ValueError.

Needs a humanvotes: 1 intended, 1 likely-bug, 1 needs-human (no majority)

Both error but with different exception types (ValueError vs InvalidVersion) for a very long number. The fast path catches ValueError and wraps in InvalidVersion; the base path lets ValueError propagate. The PR is a perf refactor; no intent to change exception types.

Found by: hostile mutation · also caught by: Mutations of the PR's own test strings

ran onToken Factory Sandboxes · image 62d98fe8-9c1e-42e6-b250-ab6f630d8680

Regression test verified passes on base, fails on head
def test_1082_61967cca_p2_outcome_5():
    """Breakwater P2: base behaviour pinned (found by differential testing; label: needs-human)."""
    import pytest
    from packaging.version import Version
    with pytest.raises(ValueError) as excinfo:
        Version('1' + '0' * 4300 + '.' + '0' + '.' + '1')
    assert type(excinfo.value) is ValueError  # exact type: a subclass would be a behaviour change

Regression tests

6 of 6 classes have a generated pytest that pins the old behaviour. Each passed on the base commit and failed on the head commit in the sandbox before it was offered.

Download test_1082_61967cca.py

Performance · Version

Worst family with mostly valid inputs: 2.86× the instructions of base (Leading zeros in first segment).

head slowerhead faster1×1.2×1.4×1.7×2×2.4×2.8×101001,00010,000input size (characters)R4.1R4.1: 1.05× at ~17 charsR4.1: 1.10× at ~35 charsR4.1: 1.46× at ~311 charsR4.1: 2.28× at ~4,295 charsR4.1: 2.86× at ~66,311 charsR4R4: 1.05× at ~14 charsR4: 1.08× at ~23 charsR4: 1.37× at ~161 charsR4: 2.17× at ~2,153 charsR4: 2.74× at ~33,161 charsF6F6: 1.03× at ~9 charsF6: 1.04× at ~13 charsF6: 1.08× at ~37 charsF6: 1.12× at ~133 charsF6: 1.14× at ~517 charsF6: 1.14× at ~2,053 charsF6: 1.14× at ~8,197 charsF4F4: 1.03× at ~9 charsF4: 1.04× at ~13 charsF4: 1.08× at ~37 charsF4: 1.12× at ~133 charsF4: 1.14× at ~517 charsF4: 1.14× at ~2,053 charsF4: 1.14× at ~8,197 chars
  • R4.1
  • R4
  • F6
  • F4
Head/base cachegrind instructions per call, by input size (log-log). Each line is one input family Nemotron proposed; points above 1× are where the "faster" code does more work.
FamilyInputsRatio range Slope base → headVerdict
R4.1Leading zeros in first segmentsuspected slowdown · expand:R41.05× – 2.86×0.56 → 0.69slower
R4Trailing numeric sub-label addedsuspected slowdown · archive1.05× – 2.74×0.57 → 0.70slower
F6valid versions with a long release segment and a pre‑release suffix only at the very endsuspected slowdown · plan1.03× – 1.14×0.80 → 0.82slower
F4pre‑release ‘a’suspected slowdown · plan1.03× – 1.14×0.80 → 0.82slower

Receipt

TargetBackendImageRun AuditAdjudication
packaging.version:VersionToken Factory Sandboxes62d98fe8-9c1e-42e6-b250-ab6f630d8680bt-1082-61967cca-3660e2$0.079$0.089

Nemotron cost on Nebius Token Factory. Backend: where the untrusted code ran. Token Factory Sandboxes (a microVM branched from a kept image, cited by its UUID). Every image is content-addressed (repo at each commit + harness), so every card re-runs from the image and seed 0. Raw data: audit, adjudication.