From da67ff862002d5a4f19e89cedcf6ce4701bb49dd Mon Sep 17 00:00:00 2001 From: Joseph Weston <joseph@weston.cloud> Date: Thu, 14 Feb 2019 16:04:25 +0100 Subject: [PATCH] implement decorator for deprecating function parameters Also implement a specialization of this decorator for the 'args' parameter, so as to avoid boilerplate (i.e. redefining the help string everywhere the decorator is used). The deprecation decorator can also be called directly with no parameters to raise the warning. This is necessary because methods of Cython cdef classes do not seem to play well with this decorator (even after applying @cython.bind(True)), so we need to call it directly from the body of the method. --- kwant/_common.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/kwant/_common.py b/kwant/_common.py index 71b4f782..e4623b8d 100644 --- a/kwant/_common.py +++ b/kwant/_common.py @@ -12,6 +12,7 @@ import numbers import inspect import warnings import importlib +import functools from contextlib import contextmanager __all__ = ['KwantDeprecationWarning', 'UserCodeError'] @@ -41,6 +42,46 @@ class UserCodeError(Exception): pass +def deprecate_parameter(parameter_name, version=None, help=None, + stacklevel=3): + """Trigger a deprecation warning if the wrapped function is called + with the provided parameter.""" + + message = ("The '{}' parameter has been deprecated since version {} -- {}" + .format(parameter_name, version, help)) + + def warn(): + warnings.warn(message, KwantDeprecationWarning, + stacklevel=stacklevel) + + def wrapper(f=None): + + # Instead of being used as a decorator, can be called with + # no arguments to just raise the warning. + if f is None: + warn() + return + + sig = inspect.signature(f) + + @functools.wraps(f) + def inner(*args, **kwargs): + # If the named argument is truthy + if sig.bind(*args, **kwargs).arguments.get(parameter_name): + warn() + return f(*args, **kwargs) + + return inner + + return wrapper + + +# Deprecation for 'args' parameter; defined once to minimize boilerplate, +# as this parameter is present all over Kwant. +deprecate_args = deprecate_parameter('args', version=1.4, help= + "Instead, provide named parameters as a dictionary via 'params'.") + + def interleave(seq): """Return an iterator that yields pairs of elements from a sequence. -- GitLab