summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2021-05-15 06:08:54 +0200
committerMichele Simionato <michele.simionato@gmail.com>2021-05-15 06:08:54 +0200
commitdbb10360ec5e11126c6c3354038e1d41485c6323 (patch)
tree4e1c72ee9d035ce867333288f85d99014421b4da /src
parente3c07ea54b6ea08765f01f72042debc66159d0a3 (diff)
downloadpython-decorator-git-dbb10360ec5e11126c6c3354038e1d41485c6323.tar.gz
Decorating builtin functions5.0.8
Diffstat (limited to 'src')
-rw-r--r--src/decorator.py33
-rw-r--r--src/tests/test.py11
2 files changed, 37 insertions, 7 deletions
diff --git a/src/decorator.py b/src/decorator.py
index d8db26d..1cffad4 100644
--- a/src/decorator.py
+++ b/src/decorator.py
@@ -40,7 +40,7 @@ import itertools
from contextlib import _GeneratorContextManager
from inspect import getfullargspec, iscoroutinefunction, isgeneratorfunction
-__version__ = '5.0.7'
+__version__ = '5.0.8'
DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(')
POS = inspect.Parameter.POSITIONAL_OR_KEYWORD
@@ -232,14 +232,33 @@ def decorate(func, caller, extras=(), kwsyntax=False):
return caller(func, *(extras + args), **kw)
fun.__name__ = func.__name__
fun.__doc__ = func.__doc__
- fun.__defaults__ = func.__defaults__
- fun.__kwdefaults__ = func.__kwdefaults__
- fun.__annotations__ = func.__annotations__
- fun.__module__ = func.__module__
- fun.__signature__ = sig
fun.__wrapped__ = func
+ # builtin functions like defaultdict.__setitem__ lack many attributes
+ try:
+ fun.__defaults__ = func.__defaults__
+ except AttributeError:
+ pass
+ try:
+ fun.__kwdefaults__ = func.__kwdefaults__
+ except AttributeError:
+ pass
+ try:
+ fun.__annotations__ = func.__annotations__
+ except AttributeError:
+ pass
+ try:
+ fun.__module__ = func.__module__
+ except AttributeError:
+ pass
+ try:
+ fun.__signature__ = sig
+ except ValueError:
+ pass
fun.__qualname__ = func.__qualname__
- fun.__dict__.update(func.__dict__)
+ try:
+ fun.__dict__.update(func.__dict__)
+ except AttributeError:
+ pass
return fun
diff --git a/src/tests/test.py b/src/tests/test.py
index acdaf93..4531ce3 100644
--- a/src/tests/test.py
+++ b/src/tests/test.py
@@ -183,6 +183,17 @@ class ExtraTestCase(unittest.TestCase):
self.assertEqual(f(0, 1), [0, 1, None])
+ def test_slow_wrapper(self):
+ # see https://github.com/micheles/decorator/issues/123
+ dd = defaultdict(list)
+ doc.trace(defaultdict.__setitem__)(dd, 'x', [1])
+ self.assertEqual(dd['x'], [1])
+ # NB: defaultdict.__getitem__ has no signature and cannot be decorated
+ with self.assertRaises(ValueError):
+ doc.trace(defaultdict.__getitem__)
+ doc.trace(defaultdict.__delitem__)(dd, 'x')
+ self.assertEqual(dd['x'], [])
+
# ################### test dispatch_on ############################# #
# adapted from test_functools in Python 3.5