@@ -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
375419def _suppress_matplotlib_deprecation_warning ():
376420 with warnings .catch_warnings ():
0 commit comments