Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5558749

Browse files
committed
Add decorator to inherit keyword-only deprecations
1 parent 79ccf53 commit 5558749

File tree

5 files changed

+154
-8
lines changed

5 files changed

+154
-8
lines changed

lib/matplotlib/cbook/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from .deprecation import (
3636
deprecated, warn_deprecated,
3737
_rename_parameter, _delete_parameter, _make_keyword_only,
38-
_suppress_matplotlib_deprecation_warning,
38+
_inherit_make_keyword_only, _suppress_matplotlib_deprecation_warning,
3939
MatplotlibDeprecationWarning, mplDeprecation)
4040

4141

lib/matplotlib/cbook/deprecation.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import namedtuple
12
import contextlib
23
import functools
34
import inspect
@@ -369,17 +370,15 @@ def wrapper(*args, **kwargs):
369370
return wrapper
370371

371372

373+
_MakeKeyWordOnlyParams = namedtuple('_MakeKeyWordOnlyParams',
374+
'since, name, original_signature')
375+
376+
372377
def _make_keyword_only(since, name, func=None):
373378
"""
374379
Decorator indicating that passing parameter *name* (or any of the following
375380
ones) positionally to *func* is being deprecated.
376-
377-
Note that this decorator **cannot** be applied to a function that has a
378-
pyplot-level wrapper, as the wrapper always pass all arguments by keyword.
379-
If it is used, users will see spurious DeprecationWarnings every time they
380-
call the pyplot wrapper.
381381
"""
382-
383382
if func is None:
384383
return functools.partial(_make_keyword_only, since, name)
385384

@@ -408,6 +407,46 @@ def wrapper(*args, **kwargs):
408407
name=name, obj_type=f"parameter of {func.__name__}()")
409408
return func(*args, **kwargs)
410409

410+
wrapper._make_keyword_only_params = \
411+
_MakeKeyWordOnlyParams(since, name, signature)
412+
413+
return wrapper
414+
415+
416+
def _inherit_make_keyword_only(called_func, func=None):
417+
"""
418+
Decorator for inheriting _make_keyword_only decorator from *called_func*.
419+
420+
This is used in pyplot to inherit the deprecation of positional parameter
421+
use from the wrapped methods.
422+
423+
Notes
424+
-----
425+
The keyword_only warning of the *called_func* is suppressed. It's not
426+
needed since the decorated function already checked the usage.
427+
Additionally, this allows the pyplot wrapper to pass any currently
428+
allowed positional keyword positionally to *called_func* (which is the
429+
current implementation of the wrappers), without risking a warning from
430+
the inner function.
431+
"""
432+
if func is None:
433+
return functools.partial(_inherit_make_keyword_only, called_func)
434+
435+
params = getattr(called_func, '_make_keyword_only_params', None)
436+
if params is None:
437+
return func
438+
since, name, _ = params
439+
440+
@_make_keyword_only(since, name)
441+
@functools.wraps(func)
442+
def wrapper(*args, **kwargs):
443+
with warnings.catch_warnings():
444+
warnings.filterwarnings(
445+
"ignore",
446+
f"Passing the {name} parameter .* positionally is deprecated",
447+
MatplotlibDeprecationWarning)
448+
return func(*args, **kwargs)
449+
411450
return wrapper
412451

413452

0 commit comments

Comments
 (0)