diff options
author | Michele Simionato <michele.simionato@gmail.com> | 2018-03-25 14:11:00 +0200 |
---|---|---|
committer | Michele Simionato <michele.simionato@gmail.com> | 2018-03-25 14:11:00 +0200 |
commit | e25ae224da9e4a5f7ded2ff711ddef2ac9e90885 (patch) | |
tree | 69ce86e0f70732e52e1c554a582b6350b60dd395 | |
parent | 3601bbc4bd5092336038227a80dbdc00640dfa5c (diff) | |
download | python-decorator-git-e25ae224da9e4a5f7ded2ff711ddef2ac9e90885.tar.gz |
Refined default args
-rw-r--r-- | src/decorator.py | 19 | ||||
-rw-r--r-- | src/tests/documentation.py | 22 |
2 files changed, 18 insertions, 23 deletions
diff --git a/src/decorator.py b/src/decorator.py index 6e5db6f..fc67e84 100644 --- a/src/decorator.py +++ b/src/decorator.py @@ -66,16 +66,6 @@ except AttributeError: def iscoroutinefunction(f): return False -# getargspec has been deprecated in Python 3.5 -ArgSpec = collections.namedtuple( - 'ArgSpec', 'args varargs varkw defaults') - - -def getargspec(f): - """A replacement for inspect.getargspec""" - spec = getfullargspec(f) - return ArgSpec(spec.args, spec.varargs, spec.varkw, spec.defaults) - DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(') @@ -260,9 +250,13 @@ def decorator(caller, _func=None): else: name = caller.__name__ doc = caller.__doc__ - nargs = caller.__code__.co_argcount + a = getfullargspec(caller) + defargs = a.args[1:] + nargs = len(a.args[1:]) ndefs = len(caller.__defaults__ or ()) - defaultargs = ', '.join(caller.__code__.co_varnames[nargs-ndefs:nargs]) + if ndefs < nargs: + caller.__defaults__ = (None,) * (nargs - ndefs) + defaultargs = ', '.join(defargs) if defaultargs: defaultargs += ',' defaults = caller.__defaults__ @@ -279,6 +273,7 @@ def decorator(caller, _func=None): dec.__defaults__ = (None,) + defaults return dec + # ####################### contextmanager ####################### # try: # Python >= 3.2 diff --git a/src/tests/documentation.py b/src/tests/documentation.py index 2fffc65..df7cfc5 100644 --- a/src/tests/documentation.py +++ b/src/tests/documentation.py @@ -185,9 +185,9 @@ keyword arguments: .. code-block:: python - >>> from decorator import getargspec # akin to inspect.getargspec - >>> print(getargspec(f1)) - ArgSpec(args=[], varargs='args', varkw='kw', defaults=None) + >>> from decorator import getfullargspec + >>> print(getfullargspec(f1)) + FullArgSpec(args=[], varargs='args', varkw='kw', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) This means that introspection tools (like ``pydoc``) will give false information about the signature of ``f1`` -- unless you are using @@ -202,7 +202,7 @@ calling the function with more than one argument raises an error: ... TypeError: f1() takes exactly 1 positional argument (2 given) -Notice that ``inspect.getargspec`` and ``inspect.getfullargspec`` +Notice that ``inspect.getfullargspec`` will give the wrong signature. This even occurs in Python 3.5, although both functions were deprecated in that release. @@ -259,8 +259,8 @@ The signature of ``heavy_computation`` is the one you would expect: .. code-block:: python - >>> print(getargspec(heavy_computation)) - ArgSpec(args=[], varargs=None, varkw=None, defaults=None) + >>> print(getfullargspec(heavy_computation)) + FullArgSpec(args=[], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) A ``trace`` decorator ------------------------------------------------------ @@ -291,8 +291,8 @@ It is immediate to verify that ``f1`` works... .. code-block:: python - >>> print(getargspec(f1)) - ArgSpec(args=['x'], varargs=None, varkw=None, defaults=None) + >>> print(getfullargspec(f1)) + FullArgSpec(args=['x'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) The decorator works with functions of any signature: @@ -305,8 +305,8 @@ The decorator works with functions of any signature: >>> f(0, 3) calling f with args (0, 3, 2), {} - >>> print(getargspec(f)) - ArgSpec(args=['x', 'y', 'z'], varargs='args', varkw='kw', defaults=(1, 2)) + >>> print(getfullargspec(f)) + FullArgSpec(args=['x', 'y', 'z'], varargs='args', varkw='kw', defaults=(1, 2), kwonlyargs=[], kwonlydefaults=None, annotations={}) $FUNCTION_ANNOTATIONS @@ -413,7 +413,7 @@ available. For instance: .. code-block:: python - >>> @blocking(msg="Please wait ...") + >>> @blocking("Please wait ...") ... def read_data(): ... time.sleep(3) # simulate a blocking resource ... return "some data" |