Summary
Replace the 30-key raw dict used by _build_options() / _options() with a @dataclass.
Current pattern
opts_default = {
"init": "random",
"maxiters": 1000,
"bias": True,
"hp_va": 0.001,
# ... 25+ more string keys
}
opts, wrnmsg = _options(opts_default, **kwargs)
Case-insensitive key matching in _options.py works around unclear contracts. Callers pass and receive untyped dicts with no IDE support.
Proposed change
@dataclass
class PCAOptions:
init: str = "random"
maxiters: int = 1000
bias: bool = True
hp_va: float = 0.001
hp_vb: float = 0.001
hp_v: float = 0.001
# ... rest as typed fields
@classmethod
def from_kwargs(cls, **kwargs: object) -> PCAOptions:
return cls(**{k: v for k, v in kwargs.items() if hasattr(cls, k)})
Follows the pattern already used by SelectionConfig in model_selection.py.
Benefits
- Construction-time validation (typos fail immediately)
- IDE autocomplete for every option
- mypy catches type mismatches
- Eliminates the case-insensitive key hack
Scope
~80 lines of dataclass + update _options.py logic. Non-breaking — from_kwargs() classmethod preserves the existing **kwargs API.
Depends on
Summary
Replace the 30-key raw
dictused by_build_options()/_options()with a@dataclass.Current pattern
Case-insensitive key matching in
_options.pyworks around unclear contracts. Callers pass and receive untyped dicts with no IDE support.Proposed change
Follows the pattern already used by
SelectionConfiginmodel_selection.py.Benefits
Scope
~80 lines of dataclass + update
_options.pylogic. Non-breaking —from_kwargs()classmethod preserves the existing**kwargsAPI.Depends on