Skip to content

_PRERELEASE_MARKERS is unreachable dead code behind the anchored release regex #568

Description

@SUaDtL

_PRERELEASE_MARKERS = ("-beta", "-rc", "-alpha") in core/pysrc/_releaselib.py cannot be reached through the public last_tag_select API as shipped.

_release_re compiles ^<prefix>(\d+)\.(\d+)\.(\d+)$. The $ anchor rejects every suffixed tag, so no tag can both match the regex and carry a marker in its prefix-stripped version portion. Probed:

tag prefix regex matches marker in version
v1.0.0-beta v no yes
v1.0.0-rc.1 v no yes
v1.0.0 v yes no
web-beta-v1.0.0 web-beta-v yes no

The two conditions are mutually exclusive. The marker check runs only on tags the regex already admitted, and those never carry a marker.

Why it was believed reachable

The module comment claimed it was "the explicit, legible second line of defense." That was true of an earlier form: the marker test used to run against the whole tag including the prefix, which made it reachable — and wrong. A prefix like web-beta-v matched the anchored regex, then got killed by the marker check, so a consumer using that prefix lost their entire release series and received the never-released sentinel. That defect was fixed in #563's mechanism split by scoping the marker test to the prefix-stripped version. The fix was correct, and it also rendered the check unreachable.

So this is fallout from a real fix, not an original defect.

Current state

The comment has been corrected to state plainly that the check is unreachable, why, and that its presence must not be read as evidence that suffixed tags are filtered twice. A test (CorePrereleaseMarkersSecondLineOfDefenseTest) monkeypatches an unanchored matcher so the behavior is proven if reached rather than asserted — the check is no longer untested dead code, just unreachable dead code.

The open question

Three options, none obviously right:

  1. Delete it and rely solely on the anchor. Simplest and most honest; removes a guard that would matter if the anchor were ever relaxed.
  2. Keep it as-is with the corrected comment. Zero risk, but ships dead code to every consumer, and the next reader has to re-derive why it exists.
  3. Relax the anchor so it becomes load-bearing — e.g. admit MAJOR.MINOR.PATCH with an arbitrary suffix and let the marker check do the filtering. This changes behavior: it would newly admit tags like v1.0.0+build.5 or v1.0.0.1, which the anchor currently rejects wholesale. Needs its own analysis of what a consumer's tag namespace can legitimately contain.

Option 3 is the only one that makes the code mean what the original comment said, and it is also the only one with a behavioral blast radius. Worth deciding deliberately rather than by deletion.

Note on scope

Touching this means editing a byte-vendored mechanism module — the change must go through core/pysrc/ and be regenerated with tools/sync-core.py into all three governance plugins.

Found during the #563 adversarial review; a mutation replacing _PRERELEASE_MARKERS with () survived both test suites, which is what exposed it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsev:lowTribunal/triage: low severity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions