Summary
Preprocessor(scaling=...) accepts any string. An unrecognized value silently produces a
pipeline with no scaler at all — no error, no warning. A typo therefore disables the
scaling step rather than reporting it, while the same typo in numerical_method raises.
Reproduction
from pretab.pipeline import get_numerical_transformer_steps
for s in ["minmax", "MinMax", "zscore", "not_a_scaler", "minmaxx", "none", None]:
print(f"{s!r:15} -> {[n for n, _ in get_numerical_transformer_steps('ple', scaling=s)]}")
'minmax' -> ['imputer', 'minmax', 'ple']
'MinMax' -> ['imputer', 'minmax', 'ple']
'zscore' -> ['imputer', 'scaler', 'ple']
'not_a_scaler' -> ['imputer', 'ple'] <- silently unscaled
'minmaxx' -> ['imputer', 'ple'] <- silently unscaled
'none' -> ['imputer', 'ple'] <- intentional
None -> ['imputer', 'ple'] <- intentional
End to end, Preprocessor(scaling="minmaxx").fit(df, y) completes without complaint and
produces unscaled features.
Expected
An unrecognized scaling value raises InvalidParamError listing the valid options, exactly
as numerical_method and categorical_method already do. None and "none" keep meaning
"no scaling".
Actual
Anything that isn't a recognized scaler is treated as "no scaling".
Root cause
pretab/pipeline/numerical.py:131-135:
if scaling is not None:
scaling = resolve_method(scaling, NUMERICAL_METHODS, NUMERICAL_ALIASES)
if scaling in scalers and scaling != method:
steps.append(scalers[scaling])
resolve_method returns the input lowercased when it recognizes nothing, and the membership
test then just fails. Contrast with the method name a few lines below, which is explicitly
validated against NUMERICAL_METHODS and raises.
Suggested fix
Validate after resolution, allowing the two documented no-op spellings:
if scaling is not None:
scaling = resolve_method(scaling, NUMERICAL_METHODS, NUMERICAL_ALIASES)
if scaling not in scalers and scaling != "none":
raise invalid_param_error(
"get_numerical_transformer_steps", "scaling", scaling,
"must name a scaler or disable scaling",
valid={*scalers, "none", None},
)
This matters more than a typical typo guard because the failure is invisible: the fit
succeeds, the widths are unchanged, and only the numeric scale of the features differs — so
the mistake surfaces (if at all) as a quietly worse model.
Environment
- pretab 0.1.0 (
main @ 51c3043)
- Python 3.11.15, numpy 2.4.6, pandas 2.3.3, scikit-learn 1.9.0, scipy 1.17.1
- macOS (darwin 25.5.0)
Summary
Preprocessor(scaling=...)accepts any string. An unrecognized value silently produces apipeline with no scaler at all — no error, no warning. A typo therefore disables the
scaling step rather than reporting it, while the same typo in
numerical_methodraises.Reproduction
End to end,
Preprocessor(scaling="minmaxx").fit(df, y)completes without complaint andproduces unscaled features.
Expected
An unrecognized
scalingvalue raisesInvalidParamErrorlisting the valid options, exactlyas
numerical_methodandcategorical_methodalready do.Noneand"none"keep meaning"no scaling".
Actual
Anything that isn't a recognized scaler is treated as "no scaling".
Root cause
pretab/pipeline/numerical.py:131-135:resolve_methodreturns the input lowercased when it recognizes nothing, and the membershiptest then just fails. Contrast with the method name a few lines below, which is explicitly
validated against
NUMERICAL_METHODSand raises.Suggested fix
Validate after resolution, allowing the two documented no-op spellings:
This matters more than a typical typo guard because the failure is invisible: the fit
succeeds, the widths are unchanged, and only the numeric scale of the features differs — so
the mistake surfaces (if at all) as a quietly worse model.
Environment
main@ 51c3043)