Skip to content

fix: forward autofit.plot **kwargs instead of silently discarding them - #1524

Merged
Jammy2211 merged 2 commits into
mainfrom
claude/autofit-plot-functions-kwargs-vvwj5x
Aug 24, 2026
Merged

fix: forward autofit.plot **kwargs instead of silently discarding them#1524
Jammy2211 merged 2 commits into
mainfrom
claude/autofit-plot-functions-kwargs-vvwj5x

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

All five public autofit.plot functions declared **kwargs and never referenced it, so a caller's customization was accepted without error and had no effect. The failure was silent — no TypeError, no warning, just a plot that ignored what was asked for. autofit_workspace/scripts/plot/*.py and docs/cookbooks/search.md both teach the idiom and state that the kwargs are forwarded; that claim was false.

The kwargs are now forwarded to the library each function wraps, through a strict signature filter. Plain forwarding would not have been enough: corner.corner funnels what it does not name into corner.core.hist2d, whose body reads only extent and discards the rest — an unrecognised name would have stayed silently ignored one layer deeper. checked_kwargs validates against the target's named parameters (a **kwargs sink is deliberately not read as "accepts anything") and raises PlotKwargsError, a TypeError, naming what it rejected with a difflib hint.

A second silent defect, found while verifying the first, is fixed here too. corner_cornerpy passed weight_list= to corner.corner, which has no such parameter — it is weights. The sample weights landed in that same hist2d sink, so every weighted posterior has been plotted unweighted, with no error. Nested-sampling and importance-weighted corner figures change appearance as a result.

Issue: #1523

API Changes

autofit.plot's five plot functions now honour their **kwargs instead of ignoring them, and reject what the wrapped library cannot use. Two behaviour changes are user-visible: a call passing an argument the underlying library does not accept now raises TypeError where it previously succeeded silently, and weighted corner figures now actually apply their weights. aplt.PlotKwargsError is exported so callers can catch the former. No symbols were removed or renamed.

See full details below.

Test Plan

  • python -m pytest test_autofit/ — full suite green (2089 passed, 36 skipped locally on 3.12)
  • python -m pytest test_autofit/non_linear/plot/ — 32 tests covering forwarding, rejection, the weights fix, the range guard, and the decorator re-raise
  • aplt.corner_cornerpy(samples=..., bins=5) visibly changes the figure
  • aplt.corner_cornerpy(samples=..., panelsize=3.5) raises TypeError naming panelsize
  • A weighted Samples renders differently from the same samples unweighted
  • Degenerate-column input (every sample equal, e.g. a PYAUTO_TEST_MODE=1 run) still renders — no corner "no dynamic range" crash
  • Paired workspace PR updates the four scripts/plot/*.py tutorials that passed wrong-library kwargs

Verified locally against the pinned corner==2.2.2 by hashing rendered RGBA buffers: bins=5, show_titles=True and weighting each change the output; degenerate columns still render; each of the four workspace scripts' kwarg lists renders end-to-end.

Full API Changes (for automation & release notes)

Added

  • autofit.plot.PlotKwargsError — a TypeError subclass raised when a plot function is given a kwarg its target library cannot honour. Also reachable at autofit.non_linear.plot.plot_util.PlotKwargsError.
  • autofit.non_linear.plot.plot_util.accepted_kwarg_names(*funcs) — the keyword names funcs genuinely honour, ignoring **kwargs sinks.
  • autofit.non_linear.plot.plot_util.checked_kwargs(kwargs, *, accepts=None, reserved=(), target) — validates caller kwargs before forwarding. accepts=None is for a target with a genuine open pass-through that raises on what it cannot use, where only reserved is enforced.

Changed Behaviour

  • corner_cornerpy, corner_anesthetic, subplot_parameters, log_likelihood_vs_iteration, figure_of_merit_vs_iteration**kwargs are now forwarded to corner.corner, anesthetic, and matplotlib respectively. Previously accepted and discarded.
  • All five — a kwarg the target library does not accept now raises PlotKwargsError (TypeError). Previously silently ignored.
  • corner_cornerpy — sample weights now reach corner.corner as weights= rather than the unrecognised weight_list=. Weighted corner figures change appearance; they were rendering unweighted.
  • corner_cornerpy — the computed weights, labels and range are now defaults a caller overrides. A caller None against one of those three keeps the computed value; this keeps the _corner_range_from degenerate-column guard in force for callers that pass range=None (which the emcee tutorial does).
  • corner_anesthetic — kwargs are split by destination: make_2d_axes's named parameters plus figsize / facecolor / dpi shape the figure, the rest style the plot via plot_2d. (figsize and facecolor are named explicitly because anesthetic takes them through its own **fig_kw rather than declaring them.)
  • mle_plotters trace plots — the hard-coded c="k" is now a default a caller's Line2D properties override, validated against the artist's own setters and aliases.
  • log_plot_exception — re-raises PlotKwargsError instead of swallowing it. It catches TypeError, so without this a rejected kwarg on corner_anesthetic surfaced as the misleading "posterior estimate not yet sufficient" info log.

Migration

Callers passing arguments that belong to a different plotting library must remove them — they never did anything, and now raise. The paired autofit_workspace PR does exactly this for the four plot tutorials:

  • Before: aplt.corner_cornerpy(samples=samples, panelsize=3.5, yticksize=16, xticksize=16, bins=20)
  • After: aplt.corner_cornerpy(samples=samples, bins=20)

Full list of names that now raise, by the library they actually came from — dynesty: dims, span, quantiles_2d, hist2d_kwargs, truth_kwargs; zeus: weight_list, span, truth, alpha, linewidth, fill, fontsize, title_fontsize, cut, size; nautilus-style figure geometry: panelsize, xticksize, yticksize.

Generated by the PyAutoLabs agent workflow.


Generated by Claude Code

Claude and others added 2 commits August 24, 2026 20:56
All five public `autofit.plot` functions declared `**kwargs` and never
referenced it, so a caller's customization was accepted without error and had
no effect. `autofit_workspace/scripts/plot/*.py` and `docs/cookbooks/search.md`
both teach the idiom and state the kwargs are forwarded; that claim was false.

The kwargs are now forwarded to the library each function wraps, through a
strict signature filter. Plain forwarding would not have been enough:
`corner.corner` funnels what it does not name into `corner.core.hist2d`, whose
body reads only `extent` and discards the rest — so an unrecognised name would
have stayed silently ignored one layer deeper. `checked_kwargs` validates
against the target's *named* parameters (a `**kwargs` sink is deliberately not
read as "accepts anything") and raises `PlotKwargsError`, a `TypeError`, naming
what it rejected with a difflib hint.

Also fixes a second silent defect in the same call: `corner_cornerpy` passed
`weight_list=` to `corner.corner`, which has no such parameter — it is
`weights`. The sample weights landed in the hist2d sink, so every weighted
posterior has been plotted unweighted, with no error.

- plot_util: `PlotKwargsError`, `accepted_kwarg_names`, `checked_kwargs`;
  `log_plot_exception` re-raises `PlotKwargsError` so a rejected kwarg is not
  reported as an unconverged posterior.
- corner_cornerpy: `weights=` fix; library-computed `weights` / `labels` /
  `range` become defaults a caller overrides. A caller `None` against one of
  those keeps the computed value — notably for `range`, where blanking it would
  hand `corner` back the degenerate columns `_corner_range_from` widens.
- corner_anesthetic: kwargs split between `make_2d_axes` and `plot_2d`
  (`figsize` / `facecolor` / `dpi` route to the figure — anesthetic takes them
  through its own `**fig_kw` rather than declaring them).
- mle_plotters: the three trace plots forward `Line2D` properties, validated
  against the artist's own setters and aliases.

Verified: `bins=5`, `show_titles=True` and weighting each change the rendered
figure (RGBA buffer hash); degenerate-column input still renders.

Full suite: 2088 passed, 36 skipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8EXazf2FEqf4S9UpTwMGV
A caller told their kwarg "raises PlotKwargsError" should be able to catch it
as `aplt.PlotKwargsError`, without reaching into `autofit.non_linear`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8EXazf2FEqf4S9UpTwMGV
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Aug 24, 2026 — with Claude
@Jammy2211
Jammy2211 merged commit 56f1b87 into main Aug 24, 2026
4 checks passed
@Jammy2211
Jammy2211 deleted the claude/autofit-plot-functions-kwargs-vvwj5x branch August 25, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant