summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Rose <rotu@users.noreply.github.com>2019-05-24 11:38:01 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-05-24 11:38:01 (GMT)
commit2a37f8f55b543589cc77a67b5cd17cbd9d0311c9 (patch)
tree7bf4242f52dd92ffb0c8a731fe7d2e0f1864556e
parentcf7d5ef49b1d28f35af137d23ec1a94f3eae090d (diff)
downloadcpython-2a37f8f55b543589cc77a67b5cd17cbd9d0311c9.zip
cpython-2a37f8f55b543589cc77a67b5cd17cbd9d0311c9.tar.gz
cpython-2a37f8f55b543589cc77a67b5cd17cbd9d0311c9.tar.bz2
bpo-36045: builtins.help() now prefixes `async` for async functions (GH-12010)
Previously, it was hard to tell whether a function should be awaited. It was also incorrect (per PEP 484) to put this in the type hint for coroutine functions. Added this info to the output of builtins.help and pydoc. https://bugs.python.org/issue36045
-rw-r--r--Lib/pydoc.py18
-rw-r--r--Lib/test/test_pydoc.py23
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst1
3 files changed, 39 insertions, 3 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 679a596..9a22e56 100644
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -951,6 +951,12 @@ class HTMLDoc(Doc):
else:
note = ' unbound %s method' % self.classlink(imclass,mod)
+ if (inspect.iscoroutinefunction(object) or
+ inspect.isasyncgenfunction(object)):
+ asyncqualifier = 'async '
+ else:
+ asyncqualifier = ''
+
if name == realname:
title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
else:
@@ -979,8 +985,8 @@ class HTMLDoc(Doc):
if not argspec:
argspec = '(...)'
- decl = title + self.escape(argspec) + (note and self.grey(
- '<font face="helvetica, arial">%s</font>' % note))
+ decl = asyncqualifier + title + self.escape(argspec) + (note and
+ self.grey('<font face="helvetica, arial">%s</font>' % note))
if skipdocs:
return '<dl><dt>%s</dt></dl>\n' % decl
@@ -1382,6 +1388,12 @@ location listed above.
else:
note = ' unbound %s method' % classname(imclass,mod)
+ if (inspect.iscoroutinefunction(object) or
+ inspect.isasyncgenfunction(object)):
+ asyncqualifier = 'async '
+ else:
+ asyncqualifier = ''
+
if name == realname:
title = self.bold(realname)
else:
@@ -1405,7 +1417,7 @@ location listed above.
argspec = argspec[1:-1] # remove parentheses
if not argspec:
argspec = '(...)'
- decl = title + argspec + note
+ decl = asyncqualifier + title + argspec + note
if skipdocs:
return decl + '\n'
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 67c6c5d..6efdeb0 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1288,6 +1288,29 @@ foo
Custom descriptor
""")
+ def test_async_annotation(self):
+ async def coro_function(ign) -> int:
+ return 1
+
+ text = pydoc.plain(pydoc.plaintext.document(coro_function))
+ self.assertIn('async coro_function', text)
+
+ html = pydoc.HTMLDoc().document(coro_function)
+ self.assertIn(
+ 'async <a name="-coro_function"><strong>coro_function',
+ html)
+
+ def test_async_generator_annotation(self):
+ async def an_async_generator():
+ yield 1
+
+ text = pydoc.plain(pydoc.plaintext.document(an_async_generator))
+ self.assertIn('async an_async_generator', text)
+
+ html = pydoc.HTMLDoc().document(an_async_generator)
+ self.assertIn(
+ 'async <a name="-an_async_generator"><strong>an_async_generator',
+ html)
class PydocServerTest(unittest.TestCase):
"""Tests for pydoc._start_server"""
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst
new file mode 100644
index 0000000..7cab3ea
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst
@@ -0,0 +1 @@
+builtins.help() now prefixes `async` for async functions