Skip to content

ui.subplot silently mis-routes projection kwargs if Figure._parse_proj's signature drifts #755

Description

@cvanelteren

Found while reviewing #698 (SubplotManager extraction). Not a regression — the signatures are correct today. This is about a trap that has already fired once.

The coupling

ultraplot/ui.py uses _pop_params to decide which keyword arguments belong to the subplot and which belong to the figure, and it does so by introspecting the signature of two Figure methods:

# ui.py:185
kwsub.update(_pop_params(kwargs, pfigure.Figure._parse_proj))
# ui.py:230
kwsubs.update(_pop_params(kwargs, pfigure.Figure._add_subplots))

After #698, Figure._parse_proj and Figure._add_subplots are pure delegators to SubplotManager. Their bodies do nothing but forward. Their only remaining job is to carry a parameter list that mirrors the manager's — a contract enforced by nothing but a docstring NOTE:.

Why this is not hypothetical

It already broke. During #698, an earlier commit collapsed _parse_proj to (*args, **kwargs). _pop_params then saw no proj/projection/proj_kw parameters, routed proj= to the figure instead of the subplot, and uplt.subplot(proj='polar') silently raised from Figure.set(). Commit 537f794 fixed it by spelling the parameters back out.

So the failure mode is: a reasonable-looking cleanup of a method that appears to be a trivial pass-through silently breaks projection handling, with no type error and no local test failure.

Suggested fix

Point _pop_params at the functions that actually own the parameters, so the signature and its meaning live in one place:

from ._subplots import SubplotManager
kwsub.update(_pop_params(kwargs, SubplotManager.parse_proj))
kwsubs.update(_pop_params(kwargs, SubplotManager.add_subplots))

Figure._parse_proj / ._add_subplots can then go back to thin (*args, **kwargs) delegators and the drift hazard disappears entirely.

This matters more as the rest of the manager split in #677 lands — each future extraction is exactly the kind of change that steps on this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions