Parsing & Diagnostics¶
Detailed references for the parse functions and issue diagnostics.
read_cl2
¶
read_cl2(
source: Source,
*,
strict: bool = False,
encoding: str = "cp1252",
errors: str = "replace",
) -> Iterator[MeetArchive]
Parse .cl2 / SDIF v3 files, yielding one :class:MeetArchive per source.
Parsing is lazy: files are read and parsed one at a time as the iterator is
consumed, so a large corpus is never held in memory all at once. To materialize
everything, drain the iterator (e.g.
meets = [m for arc in read_cl2(...) for m in arc.meets]).
Per the SDIF spec a "no time" is a blank field or a status code
(NT/NS/DNF/DQ/SCR) — never 0.00 — so a missing time
surfaces as time=None with a non-OK :class:~tunas.ResultStatus (Hy-Tek
.hy3 instead uses a 0.00 sentinel; see :func:read_hy3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Source
|
File path, directory (walked recursively for |
required |
strict
|
bool
|
If True, raises ParseError on the first recovered/skipped warning. Otherwise, parsing is lenient. Fatal M1 structural violations always raise. |
False
|
encoding
|
str
|
Text encoding to use when opening file paths. |
'cp1252'
|
errors
|
str
|
Error handling scheme for decoding errors. |
'replace'
|
Yields:
| Type | Description |
|---|---|
MeetArchive
|
class: |
Raises:
| Type | Description |
|---|---|
ParseError
|
During iteration, on a fatal structural violation, or in strict mode on any parse warning. The earliest failing source raises first. |
Source code in src/tunas/parser.py
read_hy3
¶
read_hy3(
source: Source,
*,
strict: bool = False,
encoding: str = "cp1252",
errors: str = "replace",
) -> Iterator[MeetArchive]
Parse Hy-Tek .hy3 result files, yielding one :class:MeetArchive per source.
Only fields confirmed by the reverse-engineered .hy3 specification are parsed
into the returned Meet object graph. Iteration and ordering semantics are
identical to :func:read_cl2.
Hy-Tek encodes a "no time" entry as the sentinel 0.00, normalized here to
time=None (SDIF instead uses a blank field or an NT code; see
:func:read_cl2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Source
|
File path, directory (walked recursively for |
required |
strict
|
bool
|
If True, raises ParseError on the first recovered/skipped warning. Otherwise, parsing is lenient. Fatal M1 structural violations always raise. |
False
|
encoding
|
str
|
Text encoding to use when opening file paths. |
'cp1252'
|
errors
|
str
|
Error handling scheme for decoding errors. |
'replace'
|
Yields:
| Type | Description |
|---|---|
MeetArchive
|
class: |
Raises:
| Type | Description |
|---|---|
ParseError
|
During iteration, on a fatal structural violation, or in strict mode on any parse warning. The earliest failing source raises first. |
Source code in src/tunas/parser.py
MeetArchive
dataclass
¶
MeetArchive(
source: str,
meets: list[Meet] = list(),
report: ParseReport = ParseReport(),
)
The parse result for a single source file (or stream).
A single .cl2/.hy3 file can legitimately hold more than one meet, so
meets is a list. report carries the diagnostics and counts for this
source only — readers yield one MeetArchive per file, never a merged one.
Attributes:
| Name | Type | Description |
|---|---|---|
source |
str
|
File path, or " |
meets |
list[Meet]
|
List of Meet objects parsed from the source. |
report |
ParseReport
|
Diagnostic and metric report for the parsed source. |
ParseReport
dataclass
¶
ParseReport(
warnings: list[ParseWarning] = list(),
files_read: int = 0,
meets_parsed: int = 0,
swimmers_parsed: int = 0,
individual_swims_parsed: int = 0,
relays_parsed: int = 0,
splits_parsed: int = 0,
records_skipped: int = 0,
fields_recovered: int = 0,
)
Metrics and warnings for a single parsed source (one file or stream).
Both :func:~tunas.read_cl2 and :func:~tunas.read_hy3 attach one report per
:class:~tunas.MeetArchive; use :meth:merge to fold several into a corpus-wide total.
Attributes:
| Name | Type | Description |
|---|---|---|
warnings |
list[ParseWarning]
|
List of collected ParseWarning diagnostics. |
files_read |
int
|
Count of processed files. |
meets_parsed |
int
|
Count of successfully parsed meets. |
swimmers_parsed |
int
|
Count of parsed athlete profiles. |
individual_swims_parsed |
int
|
Count of individual swim results. |
relays_parsed |
int
|
Count of parsed relay squads. |
splits_parsed |
int
|
Count of split-time objects parsed. |
records_skipped |
int
|
Count of records dropped entirely. |
fields_recovered |
int
|
Count of recovered (nulled) optional fields. |
by_severity
property
¶
by_severity: dict[Severity, list[ParseWarning]]
Warnings grouped by Severity.
merge
¶
merge(other: ParseReport) -> None
Fold another report into this report: append warnings and sum all counts.
Source code in src/tunas/_parser/diagnostics.py
warnings_for
¶
warnings_for(
*,
record_type: str | None = None,
field: str | None = None,
severity: Severity | None = None,
kind: IssueKind | None = None,
) -> list[ParseWarning]
Warnings filtered by attributes.
Source code in src/tunas/_parser/diagnostics.py
ParseWarning
dataclass
¶
ParseWarning(
source: str,
line_no: int,
record_type: str | None,
field: str | None,
column: str | None,
mandatory: str | None,
severity: Severity,
kind: IssueKind,
reason: str,
raw_line: str,
)
A single structured diagnostic.
Attributes:
| Name | Type | Description |
|---|---|---|
source |
str
|
Source file or stream label. |
line_no |
int
|
1-based line number of the record. |
record_type |
str | None
|
Coded record type (e.g. "D0", "F0"). |
field |
str | None
|
Name of the problematic field. |
column |
str | None
|
SDIF "start/length" (e.g. "40/12"). |
mandatory |
str | None
|
Requirement level ("M1", "M2", "", "*", etc.). |
severity |
Severity
|
Handling outcome (FATAL, SKIPPED, RECOVERED). |
kind |
IssueKind
|
Classification of the issue (MISSING, MALFORMED, etc.). |
reason |
str
|
Explanation of the validation failure. |
raw_line |
str
|
Raw source line (truncated to 200 characters). |
Severity
¶
Bases: Enum
How a parse issue was handled.
IssueKind
¶
Bases: Enum
What kind of data problem a warning describes.