fix: forward autofit.plot **kwargs instead of silently discarding them - #1524
Merged
Conversation
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
This was referenced Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
All five public
autofit.plotfunctions declared**kwargsand never referenced it, so a caller's customization was accepted without error and had no effect. The failure was silent — noTypeError, no warning, just a plot that ignored what was asked for.autofit_workspace/scripts/plot/*.pyanddocs/cookbooks/search.mdboth 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.cornerfunnels what it does not name intocorner.core.hist2d, whose body reads onlyextentand discards the rest — an unrecognised name would have stayed silently ignored one layer deeper.checked_kwargsvalidates against the target's named parameters (a**kwargssink is deliberately not read as "accepts anything") and raisesPlotKwargsError, aTypeError, naming what it rejected with adifflibhint.A second silent defect, found while verifying the first, is fixed here too.
corner_cornerpypassedweight_list=tocorner.corner, which has no such parameter — it isweights. The sample weights landed in that samehist2dsink, 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**kwargsinstead 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 raisesTypeErrorwhere it previously succeeded silently, and weighted corner figures now actually apply their weights.aplt.PlotKwargsErroris 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, theweightsfix, therangeguard, and the decorator re-raiseaplt.corner_cornerpy(samples=..., bins=5)visibly changes the figureaplt.corner_cornerpy(samples=..., panelsize=3.5)raisesTypeErrornamingpanelsizeSamplesrenders differently from the same samples unweightedPYAUTO_TEST_MODE=1run) still renders — nocorner"no dynamic range" crashscripts/plot/*.pytutorials that passed wrong-library kwargsVerified locally against the pinned
corner==2.2.2by hashing rendered RGBA buffers:bins=5,show_titles=Trueand 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— aTypeErrorsubclass raised when a plot function is given a kwarg its target library cannot honour. Also reachable atautofit.non_linear.plot.plot_util.PlotKwargsError.autofit.non_linear.plot.plot_util.accepted_kwarg_names(*funcs)— the keyword namesfuncsgenuinely honour, ignoring**kwargssinks.autofit.non_linear.plot.plot_util.checked_kwargs(kwargs, *, accepts=None, reserved=(), target)— validates caller kwargs before forwarding.accepts=Noneis for a target with a genuine open pass-through that raises on what it cannot use, where onlyreservedis enforced.Changed Behaviour
corner_cornerpy,corner_anesthetic,subplot_parameters,log_likelihood_vs_iteration,figure_of_merit_vs_iteration—**kwargsare now forwarded tocorner.corner,anesthetic, andmatplotlibrespectively. Previously accepted and discarded.PlotKwargsError(TypeError). Previously silently ignored.corner_cornerpy— sample weights now reachcorner.cornerasweights=rather than the unrecognisedweight_list=. Weighted corner figures change appearance; they were rendering unweighted.corner_cornerpy— the computedweights,labelsandrangeare now defaults a caller overrides. A callerNoneagainst one of those three keeps the computed value; this keeps the_corner_range_fromdegenerate-column guard in force for callers that passrange=None(which the emcee tutorial does).corner_anesthetic— kwargs are split by destination:make_2d_axes's named parameters plusfigsize/facecolor/dpishape the figure, the rest style the plot viaplot_2d. (figsizeandfacecolorare named explicitly because anesthetic takes them through its own**fig_kwrather than declaring them.)mle_plotterstrace plots — the hard-codedc="k"is now a default a caller'sLine2Dproperties override, validated against the artist's own setters and aliases.log_plot_exception— re-raisesPlotKwargsErrorinstead of swallowing it. It catchesTypeError, so without this a rejected kwarg oncorner_anestheticsurfaced 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_workspacePR does exactly this for the four plot tutorials:aplt.corner_cornerpy(samples=samples, panelsize=3.5, yticksize=16, xticksize=16, bins=20)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