def experimental(func): """Decorator for marking functions or methods experimental. This decorator logs an experimental warning whenever the decorated function is called. It has the following format: <function> (from <module>) is experimental and may change or be removed at any time, and without warning. <function> will include the class name if it is a method. It also edits the docstring of the function: ' (experimental)' is appended to the first line of the docstring and a notice is prepended to the rest of the docstring. Args: func: A function or method to mark experimental. Returns: Decorated function or method. """ decorator_utils.validate_callable(func, "experimental") @functools.wraps(func) def new_func(*args, **kwargs): logging.warning( "%s (from %s) is experimental and may change or be removed at " "any time, and without warning.", decorator_utils.get_qualified_name(func), func.__module__, ) return func(*args, **kwargs) new_func.__doc__ = _add_experimental_function_notice_to_docstring(func.__doc__) return new_func
def experimental(func): """Decorator for marking functions or methods experimental. This decorator logs an experimental warning whenever the decorated function is called. It has the following format: <function> (from <module>) is experimental and may change or be removed at any time, and without warning. <function> will include the class name if it is a method. It also edits the docstring of the function: ' (experimental)' is appended to the first line of the docstring and a notice is prepended to the rest of the docstring. Args: func: A function or method to mark experimental. Returns: Decorated function or method. """ decorator_utils.validate_callable(func, 'experimental') @functools.wraps(func) def new_func(*args, **kwargs): logging.warning( '%s (from %s) is experimental and may change or be removed at ' 'any time, and without warning.', decorator_utils.get_qualified_name(func), func.__module__) return func(*args, **kwargs) new_func.__doc__ = _add_experimental_function_notice_to_docstring( func.__doc__) return new_func
def deprecated_wrapper(func): """Deprecation wrapper.""" decorator_utils.validate_callable(func, 'deprecated') @functools.wraps(func) def new_func(*args, **kwargs): logging.warning( '%s (from %s) is deprecated and will be removed after %s.\n' 'Instructions for updating:\n%s', decorator_utils.get_qualified_name(func), func.__module__, date, instructions) return func(*args, **kwargs) new_func.__doc__ = _add_deprecated_function_notice_to_docstring( func.__doc__, date, instructions) return new_func
def deprecated_wrapper(func): """Deprecation decorator.""" decorator_utils.validate_callable(func, 'deprecated_args') arg_spec = inspect.getargspec(func) deprecated_positions = [(i, arg_name) for (i, arg_name) in enumerate(arg_spec.args) if arg_name in deprecated_arg_names] is_varargs_deprecated = arg_spec.varargs in deprecated_arg_names is_kwargs_deprecated = arg_spec.keywords in deprecated_arg_names if (len(deprecated_positions) + is_varargs_deprecated + is_kwargs_deprecated != len(deprecated_arg_names)): known_args = arg_spec.args + [arg_spec.varargs, arg_spec.keywords] missing_args = [ arg_name for arg_name in deprecated_arg_names if arg_name not in known_args ] raise ValueError( 'The following deprecated arguments are not present ' 'in the function signature: %s' % missing_args) @functools.wraps(func) def new_func(*args, **kwargs): """Deprecation wrapper.""" invalid_args = [] for (i, arg_name) in deprecated_positions: if i < len(args): invalid_args.append(arg_name) if is_varargs_deprecated and len(args) > len(arg_spec.args): invalid_args.append(arg_spec.varargs) if is_kwargs_deprecated and kwargs: invalid_args.append(arg_spec.keywords) for arg_name in deprecated_arg_names: if arg_name in kwargs: invalid_args.append(arg_name) for arg_name in invalid_args: logging.warning( 'Calling %s (from %s) with %s is deprecated and will be removed ' 'after %s.\nInstructions for updating:\n%s', decorator_utils.get_qualified_name(func), func.__module__, arg_name, date, instructions) return func(*args, **kwargs) new_func.__doc__ = _add_deprecated_arg_notice_to_docstring( func.__doc__, date, instructions) return new_func
def deprecated_wrapper(func): """Deprecation decorator.""" decorator_utils.validate_callable(func, 'deprecated_arg_values') @functools.wraps(func) def new_func(*args, **kwargs): """Deprecation wrapper.""" named_args = inspect.getcallargs(func, *args, **kwargs) for arg_name, arg_value in deprecated_kwargs.items(): if arg_name in named_args and named_args[arg_name] == arg_value: logging.warning( 'Calling %s (from %s) with %s=%s is deprecated and will be ' 'removed after %s.\nInstructions for updating:\n%s', decorator_utils.get_qualified_name(func), func.__module__, arg_name, arg_value, date, instructions) return func(*args, **kwargs) new_func.__doc__ = _add_deprecated_arg_notice_to_docstring( func.__doc__, date, instructions) return new_func
def test_partial(self): partial = functools.partial(_test_function, unused_arg=7) decorator_utils.validate_callable(partial, "test")
def test_callable(self): class TestClass(object): def __call__(self): pass decorator_utils.validate_callable(TestClass(), "test")
def test_method(self): decorator_utils.validate_callable(self.test_method, "test")
def test_function(self): decorator_utils.validate_callable(_test_function, "test")