summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2018-03-25 14:11:00 +0200
committerMichele Simionato <michele.simionato@gmail.com>2018-03-25 14:11:00 +0200
commite25ae224da9e4a5f7ded2ff711ddef2ac9e90885 (patch)
tree69ce86e0f70732e52e1c554a582b6350b60dd395
parent3601bbc4bd5092336038227a80dbdc00640dfa5c (diff)
downloadpython-decorator-git-e25ae224da9e4a5f7ded2ff711ddef2ac9e90885.tar.gz
Refined default args
-rw-r--r--src/decorator.py19
-rw-r--r--src/tests/documentation.py22
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"