Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sphinx-doc/sphinx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-05-24 17:11:10 +0300
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-05-31 17:22:20 +0300
commita59f83b6bdaf86dec6058cf72ae12eae967426c5 (patch)
treecf098636d0f8b7849483d668383fe5956c427299
parentc063c9c0fe383a20da613448d1f606b9635773b9 (diff)
Add sphinx.util.inspect:signature_from_ast()
-rw-r--r--sphinx/util/inspect.py12
-rw-r--r--tests/test_util_inspect.py33
2 files changed, 41 insertions, 4 deletions
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 0f3f47562..d4928c847 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -527,10 +527,14 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
def signature_from_str(signature: str) -> inspect.Signature:
"""Create a Signature object from string."""
module = ast.parse('def func' + signature + ': pass')
- definition = cast(ast.FunctionDef, module.body[0]) # type: ignore
+ function = cast(ast.FunctionDef, module.body[0]) # type: ignore
- # parameters
- args = definition.args
+ return signature_from_ast(function)
+
+
+def signature_from_ast(node: ast.FunctionDef) -> inspect.Signature:
+ """Create a Signature object from AST *node*."""
+ args = node.args
defaults = list(args.defaults)
params = []
if hasattr(args, "posonlyargs"):
@@ -580,7 +584,7 @@ def signature_from_str(signature: str) -> inspect.Signature:
params.append(Parameter(args.kwarg.arg, Parameter.VAR_KEYWORD,
annotation=annotation))
- return_annotation = ast_unparse(definition.returns) or Parameter.empty
+ return_annotation = ast_unparse(node.returns) or Parameter.empty
return inspect.Signature(params, return_annotation=return_annotation)
diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py
index fa0ff84e1..6a14dc1ac 100644
--- a/tests/test_util_inspect.py
+++ b/tests/test_util_inspect.py
@@ -9,6 +9,7 @@
"""
import _testcapi
+import ast
import datetime
import functools
import sys
@@ -350,6 +351,38 @@ def test_signature_from_str_invalid():
inspect.signature_from_str('')
+def test_signature_from_ast():
+ signature = 'def func(a, b, *args, c=0, d="blah", **kwargs): pass'
+ tree = ast.parse(signature)
+ sig = inspect.signature_from_ast(tree.body[0])
+ assert list(sig.parameters.keys()) == ['a', 'b', 'args', 'c', 'd', 'kwargs']
+ assert sig.parameters['a'].name == 'a'
+ assert sig.parameters['a'].kind == Parameter.POSITIONAL_OR_KEYWORD
+ assert sig.parameters['a'].default == Parameter.empty
+ assert sig.parameters['a'].annotation == Parameter.empty
+ assert sig.parameters['b'].name == 'b'
+ assert sig.parameters['b'].kind == Parameter.POSITIONAL_OR_KEYWORD
+ assert sig.parameters['b'].default == Parameter.empty
+ assert sig.parameters['b'].annotation == Parameter.empty
+ assert sig.parameters['args'].name == 'args'
+ assert sig.parameters['args'].kind == Parameter.VAR_POSITIONAL
+ assert sig.parameters['args'].default == Parameter.empty
+ assert sig.parameters['args'].annotation == Parameter.empty
+ assert sig.parameters['c'].name == 'c'
+ assert sig.parameters['c'].kind == Parameter.KEYWORD_ONLY
+ assert sig.parameters['c'].default == '0'
+ assert sig.parameters['c'].annotation == Parameter.empty
+ assert sig.parameters['d'].name == 'd'
+ assert sig.parameters['d'].kind == Parameter.KEYWORD_ONLY
+ assert sig.parameters['d'].default == "'blah'"
+ assert sig.parameters['d'].annotation == Parameter.empty
+ assert sig.parameters['kwargs'].name == 'kwargs'
+ assert sig.parameters['kwargs'].kind == Parameter.VAR_KEYWORD
+ assert sig.parameters['kwargs'].default == Parameter.empty
+ assert sig.parameters['kwargs'].annotation == Parameter.empty
+ assert sig.return_annotation == Parameter.empty
+
+
def test_safe_getattr_with_default():
class Foo:
def __getattr__(self, item):