Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit edf1bb7

Browse filesBrowse files
authored
Merge pull request #13601 from anntzer/make_positional_only
Add a make-parameter-keyword-only-with-deprecation decorator.
2 parents b15140a + 001e85f commit edf1bb7
Copy full SHA for edf1bb7

File tree

Expand file treeCollapse file tree

7 files changed

+83
-6
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+83
-6
lines changed
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
API changes
2+
```````````
3+
4+
Passing the ``block`` argument of ``plt.show`` positionally is deprecated; it
5+
should be passed by keyword.
6+
7+
When using the nbagg backend, ``plt.show`` used to silently accept and ignore
8+
all combinations of positional and keyword arguments. This behavior is
9+
deprecated.

‎lib/matplotlib/backend_bases.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_bases.py
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3253,8 +3253,10 @@ def draw_if_interactive(cls):
32533253
cls.trigger_manager_draw(manager)
32543254

32553255
@classmethod
3256+
@cbook._make_keyword_only("3.1", "block")
32563257
def show(cls, block=None):
3257-
"""Show all figures.
3258+
"""
3259+
Show all figures.
32583260
32593261
`show` blocks by calling `mainloop` if *block* is ``True``, or if it
32603262
is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in

‎lib/matplotlib/backends/backend_nbagg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_nbagg.py
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Jupyter/IPython 3.x or earlier
1818
from IPython.kernel.comm import Comm
1919

20-
from matplotlib import is_interactive
20+
from matplotlib import cbook, is_interactive
2121
from matplotlib._pylab_helpers import Gcf
2222
from matplotlib.backend_bases import (
2323
_Backend, FigureCanvasBase, NavigationToolbar2)
@@ -241,7 +241,13 @@ def trigger_manager_draw(manager):
241241
manager.show()
242242

243243
@staticmethod
244-
def show(*args, **kwargs):
244+
def show(*args, block=None, **kwargs):
245+
if args or kwargs:
246+
cbook.warn_deprecated(
247+
"3.1", message="Passing arguments to show(), other than "
248+
"passing 'block' by keyword, is deprecated %(since)s, and "
249+
"support for it will be removed %(removal)s.")
250+
245251
## TODO: something to do when keyword block==False ?
246252
from matplotlib._pylab_helpers import Gcf
247253

‎lib/matplotlib/backends/backend_template.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_template.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def draw_if_interactive():
173173
"""
174174

175175

176-
def show(block=None):
176+
def show(*, block=None):
177177
"""
178178
For image backends - is not required.
179179
For GUI backends - show() is usually the last line of a pyplot script and

‎lib/matplotlib/cbook/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cbook/__init__.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232

3333
import matplotlib
3434
from .deprecation import (
35-
deprecated, warn_deprecated, _rename_parameter, _delete_parameter,
35+
deprecated, warn_deprecated,
36+
_rename_parameter, _delete_parameter, _make_keyword_only,
3637
_suppress_matplotlib_deprecation_warning,
3738
MatplotlibDeprecationWarning, mplDeprecation)
3839

‎lib/matplotlib/cbook/deprecation.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cbook/deprecation.py
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,50 @@ def wrapper(*args, **kwargs):
371371
return wrapper
372372

373373

374+
def _make_keyword_only(since, name, func=None):
375+
"""
376+
Decorator indicating that passing parameter *name* (or any of the following
377+
ones) positionally to *func* is being deprecated.
378+
379+
Note that this decorator **cannot** be applied to a function that has a
380+
pyplot-level wrapper, as the wrapper always pass all arguments by keyword.
381+
If it is used, users will see spurious DeprecationWarnings every time they
382+
call the pyplot wrapper.
383+
"""
384+
385+
if func is None:
386+
return functools.partial(_make_keyword_only, since, name)
387+
388+
signature = inspect.signature(func)
389+
POK = inspect.Parameter.POSITIONAL_OR_KEYWORD
390+
KWO = inspect.Parameter.KEYWORD_ONLY
391+
assert (name in signature.parameters
392+
and signature.parameters[name].kind == POK), (
393+
f"Matplotlib internal error: {name!r} must be a positional-or-keyword "
394+
f"parameter for {func.__name__}()")
395+
names = [*signature.parameters]
396+
kwonly = [name for name in names[names.index(name):]
397+
if signature.parameters[name].kind == POK]
398+
func.__signature__ = signature.replace(parameters=[
399+
param.replace(kind=inspect.Parameter.KEYWORD_ONLY)
400+
if param.name in kwonly
401+
else param
402+
for param in signature.parameters.values()])
403+
404+
@functools.wraps(func)
405+
def wrapper(*args, **kwargs):
406+
bound = signature.bind(*args, **kwargs)
407+
if name in bound.arguments and name not in kwargs:
408+
warn_deprecated(
409+
since, message="Passing the %(name)s %(obj_type)s "
410+
"positionally is deprecated since Matplotlib %(since)s; the "
411+
"parameter will become keyword-only %(removal)s.",
412+
name=name, obj_type=f"parameter of {func.__name__}()")
413+
return func(*args, **kwargs)
414+
415+
return wrapper
416+
417+
374418
@contextlib.contextmanager
375419
def _suppress_matplotlib_deprecation_warning():
376420
with warnings.catch_warnings():

‎lib/matplotlib/tests/test_cbook.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_cbook.py
+16-1Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
import matplotlib.cbook as cbook
1515
import matplotlib.colors as mcolors
16-
from matplotlib.cbook import delete_masked_points as dmp
16+
from matplotlib.cbook import (
17+
MatplotlibDeprecationWarning, delete_masked_points as dmp)
1718

1819

1920
def test_is_hashable():
@@ -545,3 +546,17 @@ def test_safe_first_element_pandas_series(pd):
545546
s = pd.Series(range(5), index=range(10, 15))
546547
actual = cbook.safe_first_element(s)
547548
assert actual == 0
549+
550+
551+
def test_make_keyword_only(recwarn):
552+
@cbook._make_keyword_only("3.0", "arg")
553+
def func(pre, arg, post=None):
554+
pass
555+
556+
func(1, arg=2)
557+
assert len(recwarn) == 0
558+
559+
with pytest.warns(MatplotlibDeprecationWarning):
560+
func(1, 2)
561+
with pytest.warns(MatplotlibDeprecationWarning):
562+
func(1, 2, 3)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.