diff options
| -rw-r--r-- | docs/README.rst | 2 | ||||
| -rw-r--r-- | documentation.pdf | 60 | ||||
| -rw-r--r-- | src/decorator.py | 14 | ||||
| -rw-r--r-- | src/tests/test.py | 15 |
4 files changed, 58 insertions, 33 deletions
diff --git a/docs/README.rst b/docs/README.rst index f17110b..7226146 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -52,7 +52,7 @@ There are various versions of the documentation: - `PDF version`_
.. _HTML version: http://pythonhosted.org/decorator/documentation.html
-.. _PDF version: https://github.com/micheles/decorator/blob/4.0.10/documentation.pdf
+.. _PDF version: https://github.com/micheles/decorator/blob/4.0.11/documentation.pdf
Repository
---------------
diff --git a/documentation.pdf b/documentation.pdf index eba7cbb..d814452 100644 --- a/documentation.pdf +++ b/documentation.pdf @@ -280,7 +280,7 @@ endobj << /Outlines 86 0 R /PageLabels 129 0 R /PageMode /UseNone /Pages 106 0 R /Type /Catalog >>
endobj
85 0 obj
-<< /Author () /CreationDate (D:20170115100338-01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20170115100338-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
+<< /Author () /CreationDate (D:20170116054911-01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20170116054911-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (\(unspecified\)) /Title () /Trapped /False >>
endobj
86 0 obj
@@ -419,7 +419,7 @@ q 1 0 0 1 91.03937 3 cm
q
0 0 0 rg
-BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.0.11 \(2017-01-15\)) Tj T* ET
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (4.0.11 \(2017-01-16\)) Tj T* ET
Q
Q
q
@@ -8922,7 +8922,7 @@ Q endstream
endobj
127 0 obj
-<< /Length 14045 >>
+<< /Length 14063 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -8934,7 +8934,7 @@ Q q
1 0 0 1 62.69291 663.0236 cm
q
-BT 1 0 0 1 0 50 Tm .155251 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should be noted that in Python 3.5, a ) Tj /F4 10 Tf (lot ) Tj /F1 10 Tf (of improvements have been made: you can decorate a function) Tj T* 0 Tw 2.710976 Tw (with ) Tj /F2 10 Tf 0 0 0 rg (func_tools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F2 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will see the correct signature. Unfortunately, the) Tj T* 0 Tw 9.38229 Tw (function will still have an incorrect signature internally, as you can see by using) Tj T* 0 Tw .243307 Tw /F2 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj /F1 10 Tf 0 0 0 rg (; so, all documentation tools using ) Tj 1 0 0 rg (``) Tj 0 0 0 rg (inspect.getfullargspec`- which has been) Tj T* 0 Tw (rightly deprecated - will see the wrong signature.) Tj T* ET
+BT 1 0 0 1 0 50 Tm .155251 Tw 12 TL /F1 10 Tf 0 0 0 rg (It should be noted that in Python 3.5, a ) Tj /F4 10 Tf (lot ) Tj /F1 10 Tf (of improvements have been made: you can decorate a function) Tj T* 0 Tw 2.710976 Tw (with ) Tj /F2 10 Tf 0 0 0 rg (func_tools.update_wrapper) Tj /F1 10 Tf 0 0 0 rg (, and ) Tj /F2 10 Tf 0 0 0 rg (pydoc ) Tj /F1 10 Tf 0 0 0 rg (will see the correct signature. Unfortunately, the) Tj T* 0 Tw 9.38229 Tw (function will still have an incorrect signature internally, as you can see by using) Tj T* 0 Tw 1.85122 Tw /F2 10 Tf 0 0 0 rg (inspect.getfullargspec) Tj /F1 10 Tf 0 0 0 rg (; so, all documentation tools using ) Tj /F2 10 Tf 0 0 0 rg (inspect.getfullargspec ) Tj /F1 10 Tf 0 0 0 rg (- which) Tj T* 0 Tw (has been rightly deprecated - will see the wrong signature.) Tj T* ET
Q
Q
q
@@ -9766,35 +9766,35 @@ xref 0000281234 00000 n
0000294965 00000 n
0000305969 00000 n
-0000320073 00000 n
-0000331748 00000 n
-0000332032 00000 n
-0000332070 00000 n
-0000332108 00000 n
-0000332146 00000 n
-0000332184 00000 n
-0000332222 00000 n
-0000332260 00000 n
-0000332298 00000 n
-0000332336 00000 n
-0000332374 00000 n
-0000332413 00000 n
-0000332452 00000 n
-0000332491 00000 n
-0000332530 00000 n
-0000332569 00000 n
-0000332608 00000 n
-0000332647 00000 n
-0000332686 00000 n
-0000332725 00000 n
-0000332764 00000 n
-0000332803 00000 n
-0000332842 00000 n
+0000320091 00000 n
+0000331766 00000 n
+0000332050 00000 n
+0000332088 00000 n
+0000332126 00000 n
+0000332164 00000 n
+0000332202 00000 n
+0000332240 00000 n
+0000332278 00000 n
+0000332316 00000 n
+0000332354 00000 n
+0000332392 00000 n
+0000332431 00000 n
+0000332470 00000 n
+0000332509 00000 n
+0000332548 00000 n
+0000332587 00000 n
+0000332626 00000 n
+0000332665 00000 n
+0000332704 00000 n
+0000332743 00000 n
+0000332782 00000 n
+0000332821 00000 n
+0000332860 00000 n
trailer
<< /ID
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
- [(d\361p`_\330\303@\326\177hR\227\011V\331) (d\361p`_\330\303@\326\177hR\227\011V\331)]
+ [(@\364"\)l\303 \016L\245\020\343x\243\3645) (@\364"\)l\303 \016L\245\020\343x\243\3645)]
/Info 85 0 R /Root 84 0 R /Size 152 >>
startxref
-332881
+332899
%%EOF
diff --git a/src/decorator.py b/src/decorator.py index 43be279..bdb8e71 100644 --- a/src/decorator.py +++ b/src/decorator.py @@ -59,6 +59,13 @@ else: def get_init(cls): return cls.__init__.__func__ +try: + iscoroutinefunction = inspect.iscoroutinefunction +except AttributeError: + # let's assume there are no coroutine functions in old Python + def iscoroutinefunction(f): + return False + # getargspec has been deprecated in Python 3.5 ArgSpec = collections.namedtuple( 'ArgSpec', 'args varargs varkw defaults') @@ -90,6 +97,7 @@ class FunctionMaker(object): def __init__(self, func=None, name=None, signature=None, defaults=None, doc=None, module=None, funcdict=None): self.shortsignature = signature + self.coro = False if func: # func can be a class or a callable, but not an instance method self.name = func.__name__ @@ -98,6 +106,7 @@ class FunctionMaker(object): self.doc = func.__doc__ self.module = func.__module__ if inspect.isfunction(func): + self.coro = iscoroutinefunction(func) argspec = getfullargspec(func) self.annotations = getattr(func, '__annotations__', {}) for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', @@ -165,7 +174,7 @@ class FunctionMaker(object): "Make a new function from a given template and update the signature" src = src_templ % vars(self) # expand name and signature evaldict = evaldict or {} - mo = DEF.match(src) + mo = DEF.search(src) if mo is None: raise SyntaxError('not a valid function template\n%s' % src) name = mo.group(1) # extract the function name @@ -214,7 +223,8 @@ class FunctionMaker(object): func = obj self = cls(func, name, signature, defaults, doc, module) ibody = '\n'.join(' ' + line for line in body.splitlines()) - return self.make('def %(name)s(%(signature)s):\n' + ibody, + coro = 'async ' if self.coro else '' + return self.make(coro + 'def %(name)s(%(signature)s):\n' + ibody, evaldict, addsource, **attrs) diff --git a/src/tests/test.py b/src/tests/test.py index 8b74c3a..0e31053 100644 --- a/src/tests/test.py +++ b/src/tests/test.py @@ -23,6 +23,21 @@ def assertRaises(etype): else: raise Exception('Expected %s' % etype.__name__) +if sys.version >= '3.5': + exec('''\ +class CoroutineTestCase(unittest.TestCase): + def test(self): + async def cor(): + pass + self.assertTrue(inspect.iscoroutinefunction(cor)) + + @decorator + def identity(f, *args, **kwargs): + return f(*args, **kwargs) + + self.assertTrue(inspect.iscoroutinefunction(identity(cor))) +''') + class DocumentationTestCase(unittest.TestCase): def test(self): |
