EternalTalentSpace / src /redstack /ports /candidate_source.py
Jerlshin's picture
refined progress and defect fix
761d149
Raw
History Blame Contribute Delete
1.4 kB
from __future__ import annotations
from collections.abc import Iterator
from typing import Protocol, runtime_checkable
from redstack.domain.errors import DomainError
from redstack.ports._types import SourceRecord
class CandidateSourceError(DomainError):
"""Cannot open or decompress the source, or a low-level IO error occurred.
Per-line decode failures are *not* this error — they surface as
``SourceMalformed`` records so the pipeline can apply skip-vs-abort policy.
"""
@runtime_checkable
class CandidateSourcePort(Protocol):
"""Lazy, single-pass, order-preserving stream of raw candidate records."""
def stream(self) -> Iterator[SourceRecord]:
"""Yield records lazily in file order, one at a time.
Each ``SourceOk`` carries the undecoded record plus ``source_index``
(enumeration order) and ``line_no``; each ``SourceMalformed`` carries
``line_no`` and an error string. Calling ``stream`` again starts a
fresh, independent pass (a new iterator).
Raises:
CandidateSourceError: the source cannot be opened or decompressed,
or an IO error occurs mid-stream.
"""
...
def count(self) -> int | None:
"""Return the record count, or ``None`` if unknown without a full pass."""
...
__all__: tuple[str, ...] = ("CandidateSourceError", "CandidateSourcePort")