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

Skip to content

Commit 45901b1

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

File tree

5 files changed

+153
-8
lines changed

5 files changed

+153
-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: 44 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,14 @@ def wrapper(*args, **kwargs):
369370
return wrapper
370371

371372

373+
_MakeKeyWordOnlyParams = namedtuple('_MakeKeyWordOnlyParams',
374+
'since, name, original_signature')
375+
372376
def _make_keyword_only(since, name, func=None):
373377
"""
374378
Decorator indicating that passing parameter *name* (or any of the following
375379
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.
381380
"""
382-
383381
if func is None:
384382
return functools.partial(_make_keyword_only, since, name)
385383

@@ -408,6 +406,46 @@ def wrapper(*args, **kwargs):
408406
name=name, obj_type=f"parameter of {func.__name__}()")
409407
return func(*args, **kwargs)
410408

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

413451

0 commit comments

Comments
 (0)