Skip to content

bug: ParetoScaler estimator (maybe more) crash HTML representation with scikit-learn >= 1.8.0 #289

Description

@Gnpd

Describe the bug
ParetoScaler's class docstring has a malformed NumPy-style "See Also" section: the entry's description wraps onto a second line that is not indented relative to the entry. scikit-learn's vendored numpydoc (used when building an estimator's HTML representation, _repr_html_) parses this section with a strict grammar, treats the un-indented continuation line as a new entry, fails to parse it, and raises:

ValueError: Error parsing See Also entry 'and scaling to unit variance.'

This makes any ParetoScaler instance — or any Pipeline/ColumnTransformer containing one, crash whenever its HTML repr is rendered. In Jupyter/IPython this happens automatically when the estimator is a cell's last expression or is passed to display(). It also happens in plain scripts, web apps/dashboards, or Sphinx builds that render the estimator HTML. Plain computation (fit/transform/predict/CV) and text repr() are unaffected, so the bug stays latent until something displays the estimator.

The lines in chemotools/scale/_pareto_scaler.py:

See also
--------
sklearn.preprocessing.StandardScaler : Standardize features by removing the mean
and scaling to unit variance.

The second line (and scaling to unit variance.) is at the same indentation as the entry, so numpydoc parses it as a (broken) new See Also entry.

To Reproduce

Minimal, self-contained example (no notebook required):

from chemotools.scale import ParetoScaler

# This is exactly what Jupyter calls to render the rich estimator diagram;
# in a notebook it fires automatically when `ParetoScaler()` is a cell's last line.
ParetoScaler()._repr_html_()

Run it (python repro.py) and it raises:

ValueError: Error parsing See Also entry 'and scaling to unit variance.'

Equivalent reproduction inside a notebook, just evaluate the estimator (or a pipeline containing it) as the last expression of a cell:

from sklearn.pipeline import make_pipeline
from chemotools.scale import NormScaler, ParetoScaler
prep = make_pipeline(NormScaler(l_norm=1), ParetoScaler())
prep        # last-expression repr -> Jupyter calls _repr_html_ -> ValueError

Confirmation that the cause is the docstring (not chemotools logic), by parsing the docstring directly:

from sklearn.externals._numpydoc.docscrape import NumpyDocString
NumpyDocString(ParetoScaler.__doc__)   # -> same ValueError

Expected behavior

ParetoScaler()._repr_html_() (and rendering any pipeline containing a ParetoScaler in a notebook) should produce the estimator HTML diagram without error, like every other chemotools transformer.

Suggested fix

The "See Also" description must be a single line, or the continuation must be indented. Either of these resolves it (verified against scikit-learn 1.8.0's vendored numpydoc):

# Option A — single line
See Also
--------
sklearn.preprocessing.StandardScaler : Standardize features by removing the mean and scaling to unit variance.
# Option B — indented continuation
See Also
--------
sklearn.preprocessing.StandardScaler : Standardize features by removing the mean
    and scaling to unit variance.

(Note: the capitalization See alsoSee Also is not the issue — numpydoc matches the header case-insensitively. The wrapping is the sole cause.)

It's worth grepping other docstrings in the package for the same wrapped-See Also pattern, since any of them would fail identically.

Environment

  • chemotools: 0.4.2
  • scikit-learn: 1.8.0 and 1.9.0 (its numpydoc raises on malformed See Also; older versions only warned, which is why this may not reproduce on every setup)
  • Python: 3.12.9
  • OS: Windows 11 (10.0.26200) — platform-independent
  • Trigger: any call to _repr_html_() (Jupyter/IPython rich display, display(), sklearn.utils.estimator_html_repr, dashboards, Sphinx numpydoc builds)

Additional context

  • The bug does not affect fitting/transforming or any numerical behavior — only HTML/diagram rendering, so it can hide in passing test suites and only surface for interactive users.
  • Severity is mostly UX, but it's a hard crash for the common workflow of inspecting a preprocessing Pipeline in a notebook.
  • scikit-learn made this stricter over time (warn → raise in _parse_see_also), so the same docstring may behave differently across sklearn versions.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

Status
To be done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions