@@ -310,6 +310,63 @@ def wrapper(*args, **kwargs):
310
310
return wrapper
311
311
312
312
313
+ class _deprecated_parameter_class :
314
+ def __repr__ (self ):
315
+ return "<deprecated parameter>"
316
+
317
+
318
+ _deprecated_parameter = _deprecated_parameter_class ()
319
+
320
+
321
+ def _delete_parameter (since , name , func = None ):
322
+ """
323
+ Decorator indicating that parameter *name* of *func* is being deprecated.
324
+
325
+ The actual implementation of *func* should keep the *name* parameter in its
326
+ signature.
327
+
328
+ Parameters that come after the deprecated parameter effectively become
329
+ keyword-only (as they cannot be passed positionally without triggering the
330
+ DeprecationWarning on the deprecated parameter), and should be marked as
331
+ such after the deprecation period has passed and the deprecated parameter
332
+ is removed.
333
+
334
+ Examples
335
+ --------
336
+
337
+ ::
338
+ @_delete_parameter("3.1", "unused")
339
+ def func(used_arg, other_arg, unused, more_args): ...
340
+ """
341
+
342
+ if func is None :
343
+ return functools .partial (_delete_parameter , since , name )
344
+
345
+ signature = inspect .signature (func )
346
+ assert name in signature .parameters , (
347
+ f"Matplotlib internal error: { name !r} must be a parameter for "
348
+ f"{ func .__name__ } ()" )
349
+ func .__signature__ = signature .replace (parameters = [
350
+ param .replace (default = _deprecated_parameter ) if param .name == name
351
+ else param
352
+ for param in signature .parameters .values ()])
353
+
354
+ @functools .wraps (func )
355
+ def wrapper (* args , ** kwargs ):
356
+ arguments = func .__signature__ .bind (* args , ** kwargs ).arguments
357
+ # We cannot just check `name not in arguments` because the pyplot
358
+ # wrappers always pass all arguments explicitly.
359
+ if name in arguments and arguments [name ] != _deprecated_parameter :
360
+ warn_deprecated (
361
+ since , message = f"The { name !r} parameter of { func .__name__ } () "
362
+ f"is deprecated since Matplotlib { since } and will be removed "
363
+ f"%(removal)s. If any parameter follows { name !r} , they "
364
+ f"should be pass as keyword, not positionally." )
365
+ return func (* args , ** kwargs )
366
+
367
+ return wrapper
368
+
369
+
313
370
@contextlib .contextmanager
314
371
def _suppress_matplotlib_deprecation_warning ():
315
372
with warnings .catch_warnings ():
0 commit comments