mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Replace deprecated inspect.formatargspec
Python 3.7 raises a deprecation warning: salt/utils/decorators/signature.py:31: DeprecationWarning: `formatargspec` is deprecated since Python 3.5. Use `signature` and the `Signature` object directly `inspect.formatargspec` is only used in `salt.utils.decorators.signature.identical_signature_wrapper` which is only used in `salt.utils.decorators.path` for decorating the `which` and `which_bin` functions. The function `identical_signature_wrapper` can be simply replaced by Python's `functools.wraps` which is available since at least Python 2.7. When inspecting those wrapped functions, the underlying function (stored in the `__wrapped__` attribute) needs to be inspect instead. fixes #50911 Signed-off-by: Benjamin Drung <benjamin.drung@cloud.ionos.com>
This commit is contained in:
parent
9536d322ac
commit
61ec59375b
3 changed files with 15 additions and 48 deletions
|
@ -244,7 +244,12 @@ def yamlify_arg(arg):
|
|||
|
||||
def get_function_argspec(func, is_class_method=None):
|
||||
"""
|
||||
A small wrapper around getargspec that also supports callable classes
|
||||
A small wrapper around getargspec that also supports callable classes and wrapped functions
|
||||
|
||||
If the given function is a wrapper around another function (i.e. has a
|
||||
``__wrapped__`` attribute), return the functions specification of the underlying
|
||||
function.
|
||||
|
||||
:param is_class_method: Pass True if you are sure that the function being passed
|
||||
is a class method. The reason for this is that on Python 3
|
||||
``inspect.ismethod`` only returns ``True`` for bound methods,
|
||||
|
@ -256,6 +261,9 @@ def get_function_argspec(func, is_class_method=None):
|
|||
if not callable(func):
|
||||
raise TypeError("{0} is not a callable".format(func))
|
||||
|
||||
if hasattr(func, "__wrapped__"):
|
||||
func = func.__wrapped__
|
||||
|
||||
if is_class_method is True:
|
||||
aspec = _getargspec(func)
|
||||
del aspec.args[0] # self
|
||||
|
|
|
@ -4,10 +4,11 @@ Decorators for salt.utils.path
|
|||
"""
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import functools
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.path
|
||||
from salt.exceptions import CommandNotFoundError
|
||||
from salt.utils.decorators.signature import identical_signature_wrapper
|
||||
|
||||
|
||||
def which(exe):
|
||||
|
@ -16,6 +17,7 @@ def which(exe):
|
|||
"""
|
||||
|
||||
def wrapper(function):
|
||||
@functools.wraps(function)
|
||||
def wrapped(*args, **kwargs):
|
||||
if salt.utils.path.which(exe) is None:
|
||||
raise CommandNotFoundError(
|
||||
|
@ -23,7 +25,7 @@ def which(exe):
|
|||
)
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return identical_signature_wrapper(function, wrapped)
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
||||
|
||||
|
@ -34,6 +36,7 @@ def which_bin(exes):
|
|||
"""
|
||||
|
||||
def wrapper(function):
|
||||
@functools.wraps(function)
|
||||
def wrapped(*args, **kwargs):
|
||||
if salt.utils.path.which_bin(exes) is None:
|
||||
raise CommandNotFoundError(
|
||||
|
@ -42,6 +45,6 @@ def which_bin(exes):
|
|||
)
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return identical_signature_wrapper(function, wrapped)
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
A decorator which returns a function with the same signature of the function
|
||||
which is being wrapped.
|
||||
"""
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import inspect
|
||||
from functools import wraps
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.args
|
||||
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
||||
|
||||
def identical_signature_wrapper(original_function, wrapped_function):
|
||||
"""
|
||||
Return a function with identical signature as ``original_function``'s which
|
||||
will call the ``wrapped_function``.
|
||||
"""
|
||||
context = {"__wrapped__": wrapped_function}
|
||||
function_def = compile(
|
||||
"def {0}({1}):\n"
|
||||
" return __wrapped__({2})".format(
|
||||
# Keep the original function name
|
||||
original_function.__name__,
|
||||
# The function signature including defaults, i.e., 'timeout=1'
|
||||
inspect.formatargspec(
|
||||
*salt.utils.args.get_function_argspec(original_function)
|
||||
)[1:-1],
|
||||
# The function signature without the defaults
|
||||
inspect.formatargspec(
|
||||
formatvalue=lambda val: "",
|
||||
*salt.utils.args.get_function_argspec(original_function)
|
||||
)[1:-1],
|
||||
),
|
||||
"<string>",
|
||||
"exec",
|
||||
)
|
||||
six.exec_(function_def, context)
|
||||
return wraps(original_function)(context[original_function.__name__])
|
Loading…
Add table
Reference in a new issue