Breakwater

Backtest / #1116

perf: Overhaul _cmpkey to remove use of custom objects

pypa/packaging#1116 · merged 2026-03-11 · base baa9ea8c7f → head f2bbd4f578 · ran on Docker

BLOCK

At least one behaviour change looks like an unintended regression.

Known regressions in this PR

Counterexamples · 1 class: 1 likely bug

P4

Old pickles break

known regression: old-pickles-fail-to-load
inputVersion("0")
basepickled object loads and compares equal
headload: raises ModuleNotFoundError
Likely bugvotes: 3 likely-bug

The change is a performance‑focused refactor (new __slots__, cached _key_cache, faster comparison methods) and the only backward‑compatibility note is a comment about internal _Version usage, not about pickling. No test or changelog entry mentions preserving pickle compatibility, so the unpickling failure is an unintended regression.

# Backward compatibility for internals before 26.0. Do not use.
# This is a hot function, so not calling self.base_version

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

ran onlocal Docker · image bw-pair:ee5fda034cdd7462

Regression test verified passes on base, errors on head
def test_1116_p4_base_head_load_0():
    """Breakwater P4: base behaviour pinned (found by differential testing; label: likely-bug)."""
    import base64
    import pickle
    # pickled by the base version (lazy caches warmed first)
    old = pickle.loads(base64.b64decode('gASVygAAAAAAAACMEXBhY2thZ2luZy52ZXJzaW9ulIwHVmVyc2lvbpSTlCmBlE59lCiMBF9kZXaUTowGX2Vwb2NolEsAjApfa2V5X2NhY2hllChLACmMFXBhY2thZ2luZy5fc3RydWN0dXJlc5SMDEluZmluaXR5VHlwZZSTlCmBlGgIjBROZWdhdGl2ZUluZmluaXR5VHlwZZSTlCmBlGgLaA50lIwGX2xvY2FslE6MBV9wb3N0lE6MBF9wcmWUTowIX3JlbGVhc2WUSwCFlHWGlGIu'))
    assert old is not None  # loading must not raise
Reproduce
uv run breakwater probe --repo https://github.com/pypa/packaging --base baa9ea8c7fa7 --head f2bbd4f57864 --target packaging.version:Version --backend docker --input "0"

Regression tests

1 of 1 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_1116.py

Performance · Version

No realistic input family measured slower.

Measured in backtest packaging-v2 (same commits, run bt-1116-754b0a, image bw-pair:127ca274fc70935b). The semantic results above are from a later run; perf doesn't use the semantic planner, so it was not re-measured.

head slowerhead faster1×101001,000input size (characters)F1F1: 0.99× at ~7 charsF1: 0.99× at ~11 charsF1: 1.00× at ~35 charsF1: 1.00× at ~131 charsF1: 1.00× at ~515 charsF1: 1.00× at ~2,051 charsF1: 1.00× at ~8,195 chars
  • F1
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
F1pure numeric versions (only digits and dots, no epoch, pre‑release, post‑release, dev or local parts). The new fast‑path in ``Version.__init__`` detects the ``_SIMPLE_VERSION_INDICATORS`` set and parses the release tuple with a cheap ``split('.')`` + ``map(int, …)`` plus a pre‑computed ``_STABLE_SUFFIX`` key, avoiding the regex and the full ``_cmpkey`` tuple construction.claimed speedup · plan0.99× – 1.00×0.92 → 0.92neutral

Receipt

TargetBackendImageRun AuditAdjudication
packaging.version:Versionlocal Dockerbw-pair:ee5fda034cdd7462bt-1116-e64a53$0.089$0.030

Nemotron cost on Nebius Token Factory. Backend: where the untrusted code ran. local Docker (an image cited by its content-addressed tag). 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.