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.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__ = [ _LAZY_EXPORTS: dict[str, str] = {
"Address", # exceptions
"BatchSummary", "CycloneParseError": "cyclone.parsers.exceptions",
"BillingProvider", "CycloneValidationError": "cyclone.parsers.exceptions",
"ClaimHeader", # models
"ClaimOutput", "Address": "cyclone.parsers.models",
"CycloneParseError", "BatchSummary": "cyclone.parsers.models",
"CycloneValidationError", "BillingProvider": "cyclone.parsers.models",
"Delimiters", "ClaimHeader": "cyclone.parsers.models",
"Diagnosis", "ClaimOutput": "cyclone.parsers.models",
"Envelope", "Diagnosis": "cyclone.parsers.models",
"ParseResult", "Envelope": "cyclone.parsers.models",
"Payer", "ParseResult": "cyclone.parsers.models",
"PayerConfig", "Payer": "cyclone.parsers.models",
"Procedure", "Procedure": "cyclone.parsers.models",
"ServiceLine", "ServiceLine": "cyclone.parsers.models",
"Subscriber", "Subscriber": "cyclone.parsers.models",
"ValidationIssue", "ValidationIssue": "cyclone.parsers.models",
"ValidationReport", "ValidationReport": "cyclone.parsers.models",
"parse", # payer
"tokenize", "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())