diff options
Diffstat (limited to 'sphinx/util/inspect.py')
-rw-r--r-- | sphinx/util/inspect.py | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index e8e858f68..16f153ff8 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -121,6 +121,17 @@ def isenumattribute(x: Any) -> bool: return isinstance(x, enum.Enum) +def unpartial(obj: Any) -> Any: + """Get an original object from partial object. + + This returns given object itself if not partial. + """ + while ispartial(obj): + obj = obj.func + + return obj + + def ispartial(obj: Any) -> bool: """Check if the object is partial.""" return isinstance(obj, (partial, partialmethod)) @@ -197,24 +208,21 @@ def isattributedescriptor(obj: Any) -> bool: def isfunction(obj: Any) -> bool: """Check if the object is function.""" - return inspect.isfunction(obj) or ispartial(obj) and inspect.isfunction(obj.func) + return inspect.isfunction(unpartial(obj)) def isbuiltin(obj: Any) -> bool: """Check if the object is builtin.""" - return inspect.isbuiltin(obj) or ispartial(obj) and inspect.isbuiltin(obj.func) + return inspect.isbuiltin(unpartial(obj)) def iscoroutinefunction(obj: Any) -> bool: """Check if the object is coroutine-function.""" + obj = unpartial(obj) if hasattr(obj, '__code__') and inspect.iscoroutinefunction(obj): # check obj.__code__ because iscoroutinefunction() crashes for custom method-like # objects (see https://github.com/sphinx-doc/sphinx/issues/6605) return True - elif (ispartial(obj) and hasattr(obj.func, '__code__') and - inspect.iscoroutinefunction(obj.func)): - # partialed - return True else: return False @@ -374,44 +382,40 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True, args = [] last_kind = None for param in sig.parameters.values(): - # insert '*' between POSITIONAL args and KEYWORD_ONLY args:: - # func(a, b, *, c, d): - if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD, - param.POSITIONAL_ONLY, - None): + if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY: + # PEP-570: Separator for Positional Only Parameter: / + args.append('/') + elif param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD, + param.POSITIONAL_ONLY, + None): + # PEP-3102: Separator for Keyword Only Parameter: * args.append('*') arg = StringIO() - if param.kind in (param.POSITIONAL_ONLY, - param.POSITIONAL_OR_KEYWORD, - param.KEYWORD_ONLY): - arg.write(param.name) - if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(param.annotation)) - if param.default is not param.empty: - if show_annotation and param.annotation is not param.empty: - arg.write(' = ') - arg.write(object_description(param.default)) - else: - arg.write('=') - arg.write(object_description(param.default)) - elif param.kind == param.VAR_POSITIONAL: - arg.write('*') - arg.write(param.name) - if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(param.annotation)) + if param.kind == param.VAR_POSITIONAL: + arg.write('*' + param.name) elif param.kind == param.VAR_KEYWORD: - arg.write('**') + arg.write('**' + param.name) + else: arg.write(param.name) + + if show_annotation and param.annotation is not param.empty: + arg.write(': ') + arg.write(stringify_annotation(param.annotation)) + if param.default is not param.empty: if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(param.annotation)) + arg.write(' = ') + else: + arg.write('=') + arg.write(object_description(param.default)) args.append(arg.getvalue()) last_kind = param.kind + if last_kind == Parameter.POSITIONAL_ONLY: + # PEP-570: Separator for Positional Only Parameter: / + args.append('/') + if (sig.return_annotation is Parameter.empty or show_annotation is False or show_return_annotation is False): |