diff --git a/lib/matplotlib/cbook/deprecation.py b/lib/matplotlib/cbook/deprecation.py index f6c8bfa6473d..5f687a8bb32b 100644 --- a/lib/matplotlib/cbook/deprecation.py +++ b/lib/matplotlib/cbook/deprecation.py @@ -393,11 +393,6 @@ def _make_keyword_only(since, name, func=None): """ Decorator indicating that passing parameter *name* (or any of the following ones) positionally to *func* is being deprecated. - - Note that this decorator **cannot** be applied to a function that has a - pyplot-level wrapper, as the wrapper always pass all arguments by keyword. - If it is used, users will see spurious DeprecationWarnings every time they - call the pyplot wrapper. """ if func is None: @@ -419,8 +414,11 @@ def _make_keyword_only(since, name, func=None): @functools.wraps(func) def wrapper(*args, **kwargs): - bound = signature.bind(*args, **kwargs) - if name in bound.arguments and name not in kwargs: + # Don't use signature.bind here, as it would fail when stacked with + # _rename_parameter and an "old" argument name is passed in + # (signature.bind would fail, but the actual call would succeed). + idx = [*func.__signature__.parameters].index(name) + if len(args) > idx: warn_deprecated( since, message="Passing the %(name)s %(obj_type)s " "positionally is deprecated since Matplotlib %(since)s; the " diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 89b1c64971ee..1571d5bb7a16 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -72,6 +72,36 @@ _log = logging.getLogger(__name__) +_code_objs = { + cbook._rename_parameter: + cbook._rename_parameter("", "old", "new", lambda new: None).__code__, + cbook._make_keyword_only: + cbook._make_keyword_only("", "p", lambda p: None).__code__, +} + + +def _copy_docstring_and_deprecators(method, func=None): + if func is None: + return functools.partial(_copy_docstring_and_deprecators, method) + decorators = [docstring.copy(method)] + # Check whether the definition of *method* includes _rename_parameter or + # _make_keyword_only decorators; if so, propagate them to the pyplot + # wrapper as well. + while getattr(method, "__wrapped__", None) is not None: + for decorator_maker, code in _code_objs.items(): + if method.__code__ is code: + kwargs = { + k: v.cell_contents + for k, v in zip(code.co_freevars, method.__closure__)} + assert kwargs["func"] is method.__wrapped__ + kwargs.pop("func") + decorators.append(decorator_maker(**kwargs)) + method = method.__wrapped__ + for decorator in decorators[::-1]: + func = decorator(func) + return func + + ## Global ## @@ -172,7 +202,7 @@ def set_loglevel(*args, **kwargs): # Ensure this appears in the pyplot docs. return matplotlib.set_loglevel(*args, **kwargs) -@docstring.copy(Artist.findobj) +@_copy_docstring_and_deprecators(Artist.findobj) def findobj(o=None, match=None, include_self=True): if o is None: o = gcf() @@ -342,17 +372,17 @@ def pause(interval): time.sleep(interval) -@docstring.copy(matplotlib.rc) +@_copy_docstring_and_deprecators(matplotlib.rc) def rc(group, **kwargs): matplotlib.rc(group, **kwargs) -@docstring.copy(matplotlib.rc_context) +@_copy_docstring_and_deprecators(matplotlib.rc_context) def rc_context(rc=None, fname=None): return matplotlib.rc_context(rc, fname) -@docstring.copy(matplotlib.rcdefaults) +@_copy_docstring_and_deprecators(matplotlib.rcdefaults) def rcdefaults(): matplotlib.rcdefaults() if matplotlib.is_interactive(): @@ -362,17 +392,17 @@ def rcdefaults(): # getp/get/setp are explicitly reexported so that they show up in pyplot docs. -@docstring.copy(matplotlib.artist.getp) +@_copy_docstring_and_deprecators(matplotlib.artist.getp) def getp(obj, *args, **kwargs): return matplotlib.artist.getp(obj, *args, **kwargs) -@docstring.copy(matplotlib.artist.get) +@_copy_docstring_and_deprecators(matplotlib.artist.get) def get(obj, *args, **kwargs): return matplotlib.artist.get(obj, *args, **kwargs) -@docstring.copy(matplotlib.artist.setp) +@_copy_docstring_and_deprecators(matplotlib.artist.setp) def setp(obj, *args, **kwargs): return matplotlib.artist.setp(obj, *args, **kwargs) @@ -659,12 +689,12 @@ def get_current_fig_manager(): return gcf().canvas.manager -@docstring.copy(FigureCanvasBase.mpl_connect) +@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_connect) def connect(s, func): return gcf().canvas.mpl_connect(s, func) -@docstring.copy(FigureCanvasBase.mpl_disconnect) +@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_disconnect) def disconnect(cid): return gcf().canvas.mpl_disconnect(cid) @@ -731,7 +761,7 @@ def draw(): gcf().canvas.draw_idle() -@docstring.copy(Figure.savefig) +@_copy_docstring_and_deprecators(Figure.savefig) def savefig(*args, **kwargs): fig = gcf() res = fig.savefig(*args, **kwargs) @@ -2044,12 +2074,12 @@ def set_cmap(cmap): im.set_cmap(cmap) -@docstring.copy(matplotlib.image.imread) +@_copy_docstring_and_deprecators(matplotlib.image.imread) def imread(fname, format=None): return matplotlib.image.imread(fname, format) -@docstring.copy(matplotlib.image.imsave) +@_copy_docstring_and_deprecators(matplotlib.image.imsave) def imsave(fname, arr, **kwargs): return matplotlib.image.imsave(fname, arr, **kwargs) @@ -2150,7 +2180,7 @@ def polar(*args, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.figimage) +@_copy_docstring_and_deprecators(Figure.figimage) def figimage( X, xo=0, yo=0, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, origin=None, resize=False, **kwargs): @@ -2160,25 +2190,25 @@ def figimage( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.text) +@_copy_docstring_and_deprecators(Figure.text) def figtext(x, y, s, fontdict=None, **kwargs): return gcf().text(x, y, s, fontdict=fontdict, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.gca) +@_copy_docstring_and_deprecators(Figure.gca) def gca(**kwargs): return gcf().gca(**kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure._gci) +@_copy_docstring_and_deprecators(Figure._gci) def gci(): return gcf()._gci() # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.ginput) +@_copy_docstring_and_deprecators(Figure.ginput) def ginput( n=1, timeout=30, show_clicks=True, mouse_add=MouseButton.LEFT, mouse_pop=MouseButton.RIGHT, @@ -2190,26 +2220,26 @@ def ginput( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.suptitle) +@_copy_docstring_and_deprecators(Figure.suptitle) def suptitle(t, **kwargs): return gcf().suptitle(t, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Figure.waitforbuttonpress) +@_copy_docstring_and_deprecators(Figure.waitforbuttonpress) def waitforbuttonpress(timeout=-1): return gcf().waitforbuttonpress(timeout=timeout) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.acorr) +@_copy_docstring_and_deprecators(Axes.acorr) def acorr(x, *, data=None, **kwargs): return gca().acorr( x, **({"data": data} if data is not None else {}), **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.angle_spectrum) +@_copy_docstring_and_deprecators(Axes.angle_spectrum) def angle_spectrum( x, Fs=None, Fc=None, window=None, pad_to=None, sides=None, *, data=None, **kwargs): @@ -2219,61 +2249,61 @@ def angle_spectrum( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.annotate) +@_copy_docstring_and_deprecators(Axes.annotate) def annotate(s, xy, *args, **kwargs): return gca().annotate(s, xy, *args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.arrow) +@_copy_docstring_and_deprecators(Axes.arrow) def arrow(x, y, dx, dy, **kwargs): return gca().arrow(x, y, dx, dy, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.autoscale) +@_copy_docstring_and_deprecators(Axes.autoscale) def autoscale(enable=True, axis='both', tight=None): return gca().autoscale(enable=enable, axis=axis, tight=tight) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axhline) +@_copy_docstring_and_deprecators(Axes.axhline) def axhline(y=0, xmin=0, xmax=1, **kwargs): return gca().axhline(y=y, xmin=xmin, xmax=xmax, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axhspan) +@_copy_docstring_and_deprecators(Axes.axhspan) def axhspan(ymin, ymax, xmin=0, xmax=1, **kwargs): return gca().axhspan(ymin, ymax, xmin=xmin, xmax=xmax, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axis) +@_copy_docstring_and_deprecators(Axes.axis) def axis(*args, emit=True, **kwargs): return gca().axis(*args, emit=emit, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axline) +@_copy_docstring_and_deprecators(Axes.axline) def axline(xy1, xy2, **kwargs): return gca().axline(xy1, xy2, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axvline) +@_copy_docstring_and_deprecators(Axes.axvline) def axvline(x=0, ymin=0, ymax=1, **kwargs): return gca().axvline(x=x, ymin=ymin, ymax=ymax, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.axvspan) +@_copy_docstring_and_deprecators(Axes.axvspan) def axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs): return gca().axvspan(xmin, xmax, ymin=ymin, ymax=ymax, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.bar) +@_copy_docstring_and_deprecators(Axes.bar) def bar( x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs): @@ -2283,21 +2313,21 @@ def bar( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.barbs) +@_copy_docstring_and_deprecators(Axes.barbs) def barbs(*args, data=None, **kw): return gca().barbs( *args, **({"data": data} if data is not None else {}), **kw) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.barh) +@_copy_docstring_and_deprecators(Axes.barh) def barh(y, width, height=0.8, left=None, *, align='center', **kwargs): return gca().barh( y, width, height=height, left=left, align=align, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.boxplot) +@_copy_docstring_and_deprecators(Axes.boxplot) def boxplot( x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, @@ -2322,7 +2352,7 @@ def boxplot( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.broken_barh) +@_copy_docstring_and_deprecators(Axes.broken_barh) def broken_barh(xranges, yrange, *, data=None, **kwargs): return gca().broken_barh( xranges, yrange, @@ -2330,19 +2360,19 @@ def broken_barh(xranges, yrange, *, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.cla) +@_copy_docstring_and_deprecators(Axes.cla) def cla(): return gca().cla() # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.clabel) +@_copy_docstring_and_deprecators(Axes.clabel) def clabel(CS, levels=None, **kwargs): return gca().clabel(CS, levels=levels, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.cohere) +@_copy_docstring_and_deprecators(Axes.cohere) def cohere( x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=0, pad_to=None, @@ -2355,7 +2385,7 @@ def cohere( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.contour) +@_copy_docstring_and_deprecators(Axes.contour) def contour(*args, data=None, **kwargs): __ret = gca().contour( *args, **({"data": data} if data is not None else {}), @@ -2365,7 +2395,7 @@ def contour(*args, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.contourf) +@_copy_docstring_and_deprecators(Axes.contourf) def contourf(*args, data=None, **kwargs): __ret = gca().contourf( *args, **({"data": data} if data is not None else {}), @@ -2375,7 +2405,7 @@ def contourf(*args, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.csd) +@_copy_docstring_and_deprecators(Axes.csd) def csd( x, y, NFFT=None, Fs=None, Fc=None, detrend=None, window=None, noverlap=None, pad_to=None, sides=None, scale_by_freq=None, @@ -2388,7 +2418,7 @@ def csd( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.errorbar) +@_copy_docstring_and_deprecators(Axes.errorbar) def errorbar( x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, @@ -2403,7 +2433,7 @@ def errorbar( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.eventplot) +@_copy_docstring_and_deprecators(Axes.eventplot) def eventplot( positions, orientation='horizontal', lineoffsets=1, linelengths=1, linewidths=None, colors=None, @@ -2416,7 +2446,7 @@ def eventplot( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.fill) +@_copy_docstring_and_deprecators(Axes.fill) def fill(*args, data=None, **kwargs): return gca().fill( *args, **({"data": data} if data is not None else {}), @@ -2424,7 +2454,7 @@ def fill(*args, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.fill_between) +@_copy_docstring_and_deprecators(Axes.fill_between) def fill_between( x, y1, y2=0, where=None, interpolate=False, step=None, *, data=None, **kwargs): @@ -2434,7 +2464,7 @@ def fill_between( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.fill_betweenx) +@_copy_docstring_and_deprecators(Axes.fill_betweenx) def fill_betweenx( y, x1, x2=0, where=None, step=None, interpolate=False, *, data=None, **kwargs): @@ -2444,13 +2474,13 @@ def fill_betweenx( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.grid) +@_copy_docstring_and_deprecators(Axes.grid) def grid(b=None, which='major', axis='both', **kwargs): return gca().grid(b=b, which=which, axis=axis, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.hexbin) +@_copy_docstring_and_deprecators(Axes.hexbin) def hexbin( x, y, C=None, gridsize=100, bins=None, xscale='linear', yscale='linear', extent=None, cmap=None, norm=None, vmin=None, @@ -2469,7 +2499,7 @@ def hexbin( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.hist) +@_copy_docstring_and_deprecators(Axes.hist) def hist( x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', @@ -2484,7 +2514,7 @@ def hist( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.hist2d) +@_copy_docstring_and_deprecators(Axes.hist2d) def hist2d( x, y, bins=10, range=None, density=False, weights=None, cmin=None, cmax=None, *, data=None, **kwargs): @@ -2497,7 +2527,7 @@ def hist2d( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.hlines) +@_copy_docstring_and_deprecators(Axes.hlines) def hlines( y, xmin, xmax, colors='k', linestyles='solid', label='', *, data=None, **kwargs): @@ -2508,7 +2538,7 @@ def hlines( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.imshow) +@_copy_docstring_and_deprecators(Axes.imshow) def imshow( X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, *, @@ -2526,25 +2556,25 @@ def imshow( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.legend) +@_copy_docstring_and_deprecators(Axes.legend) def legend(*args, **kwargs): return gca().legend(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.locator_params) +@_copy_docstring_and_deprecators(Axes.locator_params) def locator_params(axis='both', tight=None, **kwargs): return gca().locator_params(axis=axis, tight=tight, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.loglog) +@_copy_docstring_and_deprecators(Axes.loglog) def loglog(*args, **kwargs): return gca().loglog(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.magnitude_spectrum) +@_copy_docstring_and_deprecators(Axes.magnitude_spectrum) def magnitude_spectrum( x, Fs=None, Fc=None, window=None, pad_to=None, sides=None, scale=None, *, data=None, **kwargs): @@ -2555,25 +2585,25 @@ def magnitude_spectrum( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.margins) +@_copy_docstring_and_deprecators(Axes.margins) def margins(*margins, x=None, y=None, tight=True): return gca().margins(*margins, x=x, y=y, tight=tight) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.minorticks_off) +@_copy_docstring_and_deprecators(Axes.minorticks_off) def minorticks_off(): return gca().minorticks_off() # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.minorticks_on) +@_copy_docstring_and_deprecators(Axes.minorticks_on) def minorticks_on(): return gca().minorticks_on() # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.pcolor) +@_copy_docstring_and_deprecators(Axes.pcolor) def pcolor( *args, shading=None, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, data=None, **kwargs): @@ -2586,7 +2616,7 @@ def pcolor( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.pcolormesh) +@_copy_docstring_and_deprecators(Axes.pcolormesh) def pcolormesh( *args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, shading=None, antialiased=False, data=None, @@ -2600,7 +2630,7 @@ def pcolormesh( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.phase_spectrum) +@_copy_docstring_and_deprecators(Axes.phase_spectrum) def phase_spectrum( x, Fs=None, Fc=None, window=None, pad_to=None, sides=None, *, data=None, **kwargs): @@ -2610,7 +2640,7 @@ def phase_spectrum( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.pie) +@_copy_docstring_and_deprecators(Axes.pie) def pie( x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, @@ -2628,7 +2658,7 @@ def pie( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.plot) +@_copy_docstring_and_deprecators(Axes.plot) def plot(*args, scalex=True, scaley=True, data=None, **kwargs): return gca().plot( *args, scalex=scalex, scaley=scaley, @@ -2636,7 +2666,7 @@ def plot(*args, scalex=True, scaley=True, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.plot_date) +@_copy_docstring_and_deprecators(Axes.plot_date) def plot_date( x, y, fmt='o', tz=None, xdate=True, ydate=False, *, data=None, **kwargs): @@ -2646,7 +2676,7 @@ def plot_date( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.psd) +@_copy_docstring_and_deprecators(Axes.psd) def psd( x, NFFT=None, Fs=None, Fc=None, detrend=None, window=None, noverlap=None, pad_to=None, sides=None, scale_by_freq=None, @@ -2659,7 +2689,7 @@ def psd( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.quiver) +@_copy_docstring_and_deprecators(Axes.quiver) def quiver(*args, data=None, **kw): __ret = gca().quiver( *args, **({"data": data} if data is not None else {}), **kw) @@ -2668,13 +2698,13 @@ def quiver(*args, data=None, **kw): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.quiverkey) +@_copy_docstring_and_deprecators(Axes.quiverkey) def quiverkey(Q, X, Y, U, label, **kw): return gca().quiverkey(Q, X, Y, U, label, **kw) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.scatter) +@_copy_docstring_and_deprecators(Axes.scatter) def scatter( x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, @@ -2691,19 +2721,19 @@ def scatter( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.semilogx) +@_copy_docstring_and_deprecators(Axes.semilogx) def semilogx(*args, **kwargs): return gca().semilogx(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.semilogy) +@_copy_docstring_and_deprecators(Axes.semilogy) def semilogy(*args, **kwargs): return gca().semilogy(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.specgram) +@_copy_docstring_and_deprecators(Axes.specgram) def specgram( x, NFFT=None, Fs=None, Fc=None, detrend=None, window=None, noverlap=None, cmap=None, xextent=None, pad_to=None, @@ -2720,7 +2750,7 @@ def specgram( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.spy) +@_copy_docstring_and_deprecators(Axes.spy) def spy( Z, precision=0, marker=None, markersize=None, aspect='equal', origin='upper', **kwargs): @@ -2732,7 +2762,7 @@ def spy( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.stackplot) +@_copy_docstring_and_deprecators(Axes.stackplot) def stackplot( x, *args, labels=(), colors=None, baseline='zero', data=None, **kwargs): @@ -2742,7 +2772,7 @@ def stackplot( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.stem) +@_copy_docstring_and_deprecators(Axes.stem) def stem( *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, label=None, use_line_collection=True, data=None): @@ -2754,7 +2784,7 @@ def stem( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.step) +@_copy_docstring_and_deprecators(Axes.step) def step(x, y, *args, where='pre', data=None, **kwargs): return gca().step( x, y, *args, where=where, @@ -2762,7 +2792,7 @@ def step(x, y, *args, where='pre', data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.streamplot) +@_copy_docstring_and_deprecators(Axes.streamplot) def streamplot( x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, @@ -2781,7 +2811,7 @@ def streamplot( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.table) +@_copy_docstring_and_deprecators(Axes.table) def table( cellText=None, cellColours=None, cellLoc='right', colWidths=None, rowLabels=None, rowColours=None, @@ -2797,19 +2827,19 @@ def table( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.text) +@_copy_docstring_and_deprecators(Axes.text) def text(x, y, s, fontdict=None, **kwargs): return gca().text(x, y, s, fontdict=fontdict, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.tick_params) +@_copy_docstring_and_deprecators(Axes.tick_params) def tick_params(axis='both', **kwargs): return gca().tick_params(axis=axis, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.ticklabel_format) +@_copy_docstring_and_deprecators(Axes.ticklabel_format) def ticklabel_format( *, axis='both', style='', scilimits=None, useOffset=None, useLocale=None, useMathText=None): @@ -2820,7 +2850,7 @@ def ticklabel_format( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.tricontour) +@_copy_docstring_and_deprecators(Axes.tricontour) def tricontour(*args, **kwargs): __ret = gca().tricontour(*args, **kwargs) if __ret._A is not None: sci(__ret) # noqa @@ -2828,7 +2858,7 @@ def tricontour(*args, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.tricontourf) +@_copy_docstring_and_deprecators(Axes.tricontourf) def tricontourf(*args, **kwargs): __ret = gca().tricontourf(*args, **kwargs) if __ret._A is not None: sci(__ret) # noqa @@ -2836,7 +2866,7 @@ def tricontourf(*args, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.tripcolor) +@_copy_docstring_and_deprecators(Axes.tripcolor) def tripcolor( *args, alpha=1.0, norm=None, cmap=None, vmin=None, vmax=None, shading='flat', facecolors=None, **kwargs): @@ -2848,13 +2878,13 @@ def tripcolor( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.triplot) +@_copy_docstring_and_deprecators(Axes.triplot) def triplot(*args, **kwargs): return gca().triplot(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.violinplot) +@_copy_docstring_and_deprecators(Axes.violinplot) def violinplot( dataset, positions=None, vert=True, widths=0.5, showmeans=False, showextrema=True, showmedians=False, @@ -2868,7 +2898,7 @@ def violinplot( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.vlines) +@_copy_docstring_and_deprecators(Axes.vlines) def vlines( x, ymin, ymax, colors='k', linestyles='solid', label='', *, data=None, **kwargs): @@ -2879,7 +2909,7 @@ def vlines( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.xcorr) +@_copy_docstring_and_deprecators(Axes.xcorr) def xcorr( x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags=10, *, data=None, **kwargs): @@ -2890,20 +2920,20 @@ def xcorr( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes._sci) +@_copy_docstring_and_deprecators(Axes._sci) def sci(im): return gca()._sci(im) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.set_title) +@_copy_docstring_and_deprecators(Axes.set_title) def title(label, fontdict=None, loc=None, pad=None, **kwargs): return gca().set_title( label, fontdict=fontdict, loc=loc, pad=pad, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.set_xlabel) +@_copy_docstring_and_deprecators(Axes.set_xlabel) def xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs): return gca().set_xlabel( xlabel, fontdict=fontdict, labelpad=labelpad, loc=loc, @@ -2911,7 +2941,7 @@ def xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.set_ylabel) +@_copy_docstring_and_deprecators(Axes.set_ylabel) def ylabel(ylabel, fontdict=None, labelpad=None, *, loc=None, **kwargs): return gca().set_ylabel( ylabel, fontdict=fontdict, labelpad=labelpad, loc=loc, @@ -2919,13 +2949,13 @@ def ylabel(ylabel, fontdict=None, labelpad=None, *, loc=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.set_xscale) +@_copy_docstring_and_deprecators(Axes.set_xscale) def xscale(value, **kwargs): return gca().set_xscale(value, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. -@docstring.copy(Axes.set_yscale) +@_copy_docstring_and_deprecators(Axes.set_yscale) def yscale(value, **kwargs): return gca().set_yscale(value, **kwargs) diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index c5a2c842d85e..1d9405f53d10 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -7,6 +7,7 @@ import matplotlib as mpl from matplotlib import pyplot as plt +from matplotlib.cbook import MatplotlibDeprecationWarning def test_pyplot_up_to_date(): @@ -36,6 +37,27 @@ def test_pyplot_up_to_date(): Path(plt.__file__).write_text(orig_contents) +def test_copy_docstring_and_deprecators(recwarn): + @mpl.cbook._rename_parameter("(version)", "old", "new") + @mpl.cbook._make_keyword_only("(version)", "kwo") + def func(new, kwo=None): + pass + + @plt._copy_docstring_and_deprecators(func) + def wrapper_func(new, kwo=None): + pass + + wrapper_func(None) + wrapper_func(new=None) + wrapper_func(None, kwo=None) + wrapper_func(new=None, kwo=None) + assert not recwarn + with pytest.warns(MatplotlibDeprecationWarning): + wrapper_func(old=None) + with pytest.warns(MatplotlibDeprecationWarning): + wrapper_func(None, None) + + def test_pyplot_box(): fig, ax = plt.subplots() plt.box(False) diff --git a/tools/boilerplate.py b/tools/boilerplate.py index 58d4fb3c17fd..089a317c7881 100644 --- a/tools/boilerplate.py +++ b/tools/boilerplate.py @@ -37,7 +37,7 @@ # Autogenerated by boilerplate.py. Do not edit as changes will be lost.""" AXES_CMAPPABLE_METHOD_TEMPLATE = AUTOGEN_MSG + """ -@docstring.copy(Axes.{called_name}) +@_copy_docstring_and_deprecators(Axes.{called_name}) def {name}{signature}: __ret = gca().{called_name}{call} {sci_command} @@ -45,13 +45,13 @@ def {name}{signature}: """ AXES_METHOD_TEMPLATE = AUTOGEN_MSG + """ -@docstring.copy(Axes.{called_name}) +@_copy_docstring_and_deprecators(Axes.{called_name}) def {name}{signature}: return gca().{called_name}{call} """ FIGURE_METHOD_TEMPLATE = AUTOGEN_MSG + """ -@docstring.copy(Figure.{called_name}) +@_copy_docstring_and_deprecators(Figure.{called_name}) def {name}{signature}: return gcf().{called_name}{call} """