summaryrefslogtreecommitdiff
path: root/sphinx/util/inspect.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/util/inspect.py')
-rw-r--r--sphinx/util/inspect.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 80cac97d9..7c977daf1 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -21,8 +21,11 @@ from inspect import ( # NOQA
)
from io import StringIO
from typing import Any, Callable, Mapping, List, Tuple
+from typing import cast
from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
+from sphinx.pycode.ast import ast # for py35-37
+from sphinx.pycode.ast import unparse as ast_unparse
from sphinx.util import logging
from sphinx.util.typing import stringify as stringify_annotation
@@ -429,6 +432,52 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
return '(%s) -> %s' % (', '.join(args), annotation)
+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
+
+ # parameters
+ args = definition.args
+ params = []
+
+ if hasattr(args, "posonlyargs"):
+ for arg in args.posonlyargs: # type: ignore
+ annotation = ast_unparse(arg.annotation) or Parameter.empty
+ params.append(Parameter(arg.arg, Parameter.POSITIONAL_ONLY,
+ annotation=annotation))
+
+ for i, arg in enumerate(args.args):
+ if len(args.args) - i <= len(args.defaults):
+ default = ast_unparse(args.defaults[-len(args.args) + i])
+ else:
+ default = Parameter.empty
+
+ annotation = ast_unparse(arg.annotation) or Parameter.empty
+ params.append(Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD,
+ default=default, annotation=annotation))
+
+ if args.vararg:
+ annotation = ast_unparse(args.vararg.annotation) or Parameter.empty
+ params.append(Parameter(args.vararg.arg, Parameter.VAR_POSITIONAL,
+ annotation=annotation))
+
+ for i, arg in enumerate(args.kwonlyargs):
+ default = ast_unparse(args.kw_defaults[i])
+ annotation = ast_unparse(arg.annotation) or Parameter.empty
+ params.append(Parameter(arg.arg, Parameter.KEYWORD_ONLY, default=default,
+ annotation=annotation))
+
+ if args.kwarg:
+ annotation = ast_unparse(args.kwarg.annotation) or Parameter.empty
+ params.append(Parameter(args.kwarg.arg, Parameter.VAR_KEYWORD,
+ annotation=annotation))
+
+ return_annotation = ast_unparse(definition.returns) or Parameter.empty
+
+ return inspect.Signature(params, return_annotation=return_annotation)
+
+
class Signature:
"""The Signature object represents the call signature of a callable object and
its return annotation.