Skip to content

fix(hy3): tolerate malformed relay F3 legs and orphaned H1 DQ lines - #26

Open
fsalum wants to merge 3 commits into
SwimComm:masterfrom
fsalum:fix/relay-parse-robustness
Open

fix(hy3): tolerate malformed relay F3 legs and orphaned H1 DQ lines#26
fsalum wants to merge 3 commits into
SwimComm:masterfrom
fsalum:fix/relay-parse-robustness

Conversation

@fsalum

@fsalum fsalum commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

Two hy3 line parsers raise on real-world Meet Manager exports instead of degrading gracefully. Both now skip the unparseable record and continue, matching the tolerance the surrounding code already has for other malformed lines.

  • f3_parser — an F3 relay leg referencing a swimmer meet-id with no D1 roster record in the file raised KeyError. The unrostered leg is now skipped (the relay keeps its other legs), like the existing empty-swimmers / absent-leg-1 handling in the same function.
  • h1_parser — an H1 DQ-detail line whose last_entry carries no DQ slot raised AssertionError('There must be a DQ for there to be an H1 line'). It is now a no-op, mirroring h2_parser — an H1 can resolve to a non-DQ entry (e.g. a relay DQ, or a non-DQ entry emitted between the DQ result and its H1). The DQ result itself is unaffected; only the reason string is skipped.

Both changes are conservative: they never alter data that parses correctly today. Verified against a large real-world corpus (288 files) where the only effect was that 8 previously-erroring files now parse cleanly with byte-identical parsed output.

Tests

Adds regression unit tests for both parsers under tests/hy3/line_parsers/; full suite green.

Note

Stacked on #25 — please review #25 first; its feat/diving-stroke commit appears in this diff until it merges.

fsalum added 3 commits July 20, 2026 00:07
Hy-Tek uses three diving stroke chars, not one: F = 1-metre
springboard, G = 3-metre springboard, H = platform. The prior
DIVING = "F", "6", 6 treated F as the only diving code and
extrapolated numeric aliases "6"/6 from the FREESTYLE..MEDLEY
pattern (1..5) with no corpus evidence Hy-Tek ever writes those
in the stroke column for diving -- a wrong alias could silently
mis-map some other numeric code onto diving.

Measured on a real corpus: 2012 PAC-12 (F=26 G=26 H=26), 2007 SEC
(F=60 G=60 H=54), 2005 PAC-10 (F=15 G=15 H=12) all show three
parallel diving events. Across 13 multi-diving-event files, G
never appears without F and H never appears without G (strict
nesting). Dive counts match within a meet across chars, and
median scores ascend F < G < H, tracking increasing degree of
difficulty. HS meets emit only F, consistent with NFHS being
1-metre only.

G and H previously fell through select_from_enum() to UNKNOWN,
silently dropping all 3-metre and platform diving results.

Drop the numeric aliases; use the character form only, since
select_from_enum(Stroke, ...) is only ever called with a single
extracted stroke-column char (hy3) or event_stroke field (hyv),
never a numeric value, in the whole codebase.
Two hy3 line parsers raised on real-world Meet Manager exports instead of
degrading gracefully:

- f3_parser: an F3 relay leg referencing a swimmer meet-id with no D1 roster
  record raised KeyError. Skip the unrostered leg (the relay keeps its other
  legs), matching the existing tolerance for the empty-swimmers and absent
  leg-1 cases.
- h1_parser: an H1 DQ-detail line whose last_entry carries no DQ slot raised
  an AssertionError. Make it a no-op, mirroring h2_parser -- an H1 can resolve
  to a non-DQ entry (e.g. a relay DQ, or a non-DQ entry emitted between the DQ
  result and its H1). The DQ result itself is unaffected; only the reason
  string is skipped.

Adds regression unit tests for both.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant