fix(backend): make parsers __init__ re-exports lazy via __getattr__

This commit is contained in:
Tyler
2026-06-19 15:32:26 -06:00
parent 260b32afac
commit 760d031535
+59 -42
View File
@@ -1,45 +1,62 @@
"""Public re-exports for the 837P parser."""
"""Public re-exports for the 837P parser.
Re-exports are lazy via PEP 562 ``__getattr__`` so that importing a name from
this package (e.g. ``from cyclone.parsers.exceptions import CycloneParseError``)
does not require every referenced module to be importable. Downstream code can
write ``cyclone.parsers.PayerConfig`` and it will be loaded on first access.
"""
from __future__ import annotations
# Eager: only the exceptions module is needed early and unconditionally.
from cyclone.parsers.exceptions import CycloneParseError, CycloneValidationError
from cyclone.parsers.models import (
Address,
BatchSummary,
BillingProvider,
ClaimHeader,
ClaimOutput,
Diagnosis,
Envelope,
ParseResult,
Payer,
Procedure,
ServiceLine,
Subscriber,
ValidationIssue,
ValidationReport,
)
from cyclone.parsers.payer import PayerConfig
from cyclone.parsers.segments import Delimiters, tokenize
from cyclone.parsers.parse_837 import parse
__all__ = [
"Address",
"BatchSummary",
"BillingProvider",
"ClaimHeader",
"ClaimOutput",
"CycloneParseError",
"CycloneValidationError",
"Delimiters",
"Diagnosis",
"Envelope",
"ParseResult",
"Payer",
"PayerConfig",
"Procedure",
"ServiceLine",
"Subscriber",
"ValidationIssue",
"ValidationReport",
"parse",
"tokenize",
]
_LAZY_EXPORTS: dict[str, str] = {
# exceptions
"CycloneParseError": "cyclone.parsers.exceptions",
"CycloneValidationError": "cyclone.parsers.exceptions",
# models
"Address": "cyclone.parsers.models",
"BatchSummary": "cyclone.parsers.models",
"BillingProvider": "cyclone.parsers.models",
"ClaimHeader": "cyclone.parsers.models",
"ClaimOutput": "cyclone.parsers.models",
"Diagnosis": "cyclone.parsers.models",
"Envelope": "cyclone.parsers.models",
"ParseResult": "cyclone.parsers.models",
"Payer": "cyclone.parsers.models",
"Procedure": "cyclone.parsers.models",
"ServiceLine": "cyclone.parsers.models",
"Subscriber": "cyclone.parsers.models",
"ValidationIssue": "cyclone.parsers.models",
"ValidationReport": "cyclone.parsers.models",
# payer
"PayerConfig": "cyclone.parsers.payer",
# segments
"Delimiters": "cyclone.parsers.segments",
"tokenize": "cyclone.parsers.segments",
# orchestrator
"parse": "cyclone.parsers.parse_837",
}
_cache: dict[str, object] = {}
def __getattr__(name: str) -> object:
module_path = _LAZY_EXPORTS.get(name)
if module_path is None:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
if name in _cache:
return _cache[name]
import importlib
mod = importlib.import_module(module_path)
value = getattr(mod, name)
_cache[name] = value
return value
def __dir__() -> list[str]:
return sorted(list(_LAZY_EXPORTS.keys()))
__all__ = sorted(_LAZY_EXPORTS.keys())