From 0ac710d2026b8dca3452b8c50d1417fefd3f62b7 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 18 Jul 2019 21:10:04 -0700 Subject: [PATCH] [Experiement] Auto-expand signature when **kwarg passed to other functions. Many functions current takes **kwargs and pass them down. During a SciPy discussion it was brought up that this was sub-optimal for new user. We can use the fact that signature can be faked, and inspect to propagate the actual keyword arguments and substitute them for **kwargs in another. With this, the signature of pyplot.subplots(), which currently as viewed in IPython is plt.subplots( nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw, ) now becomes: plt.subplots( nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, + num=None, + figsize=None, + dpi=None, + facecolor=None, + edgecolor=None, + frameon=True, + FigureClass=, + clear=False, + **kwargs, # used to be **fig_kw, to fix. ) ... which is not totally correct (they are kwargs only...) but you should see the point. This is nice as: 1) it now appear in IPython ? and ?? 2) tab completion pick up these kwargs. And it should have minimal overhead at import time, and is so far limited to function that pass all of **kwarg. Many places in matplotlib are also too dynamic to properly do it, but could allow a manual variant. --- lib/matplotlib/pyplot.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 65ea7a9db423..88ff59edf3a9 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1038,7 +1038,25 @@ def subplot(*args, **kwargs): return a +def inherit(target): + def decorate(function): + sig = inspect.signature(target) + parameters = sig.parameters + + current_sig = inspect.signature(function) + current_params = [(k,v) for k,v in current_sig.parameters.items()] + if current_params[-1][1].kind == inspect.Parameter.VAR_KEYWORD: + del current_params[-1] + current_params.extend([(k,v) for k,v in parameters.items()]) + new_sig = inspect.Signature([v for k,v in current_params]) + function.__signature__ = new_sig + return function + + return decorate + + +@inherit(figure) def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw): """