Parent
#94
What to build
Extend _resolve_effective_nulls in utils/_null_normalization.py to accept an optional numeric_sentinels: dict[str, list[float]] | None parameter (default None).
For each column present in both the DataFrame and the sentinels dict, if the column's dtype passes _numeric_sentinel_eligible, append Polars expressions that replace each matching sentinel value with pl.lit(None, dtype=dtype). The function remains pure and side-effect-free; sentinel expressions are appended to the existing expression list alongside the existing string-sentinel and Inf/NaN rules.
When numeric_sentinels is None or {}, the function is strictly identical to its current behaviour — no existing caller is broken.
Acceptance criteria
Blocked by
Parent
#94
What to build
Extend
_resolve_effective_nullsinutils/_null_normalization.pyto accept an optionalnumeric_sentinels: dict[str, list[float]] | Noneparameter (defaultNone).For each column present in both the DataFrame and the sentinels dict, if the column's dtype passes
_numeric_sentinel_eligible, append Polars expressions that replace each matching sentinel value withpl.lit(None, dtype=dtype). The function remains pure and side-effect-free; sentinel expressions are appended to the existing expression list alongside the existing string-sentinel and Inf/NaN rules.When
numeric_sentinelsisNoneor{}, the function is strictly identical to its current behaviour — no existing caller is broken.Acceptance criteria
_resolve_effective_nullssignature is(df, numeric_sentinels=None)numeric_sentinels=None: output is byte-for-byte identical to calling with no argumenttests/unit/imputation/test_null_normalization.pyBlocked by