1"""
2    sphinx.util.inspect
3    ~~~~~~~~~~~~~~~~~~~
4
5    Helpers for inspecting Python modules.
6
7    :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
8    :license: BSD, see LICENSE for details.
9"""
10
11import builtins
12import contextlib
13import enum
14import inspect
15import re
16import sys
17import types
18import typing
19import warnings
20from functools import partial, partialmethod
21from inspect import Parameter, isclass, ismethod, ismethoddescriptor, ismodule  # NOQA
22from io import StringIO
23from typing import Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple, cast
24
25from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning
26from sphinx.pycode.ast import ast  # for py35-37
27from sphinx.pycode.ast import unparse as ast_unparse
28from sphinx.util import logging
29from sphinx.util.typing import ForwardRef
30from sphinx.util.typing import stringify as stringify_annotation
31
32if sys.version_info > (3, 7):
33    from types import ClassMethodDescriptorType, MethodDescriptorType, WrapperDescriptorType
34else:
35    ClassMethodDescriptorType = type(object.__init__)
36    MethodDescriptorType = type(str.join)
37    WrapperDescriptorType = type(dict.__dict__['fromkeys'])
38
39if False:
40    # For type annotation
41    from typing import Type  # NOQA
42
43logger = logging.getLogger(__name__)
44
45memory_address_re = re.compile(r' at 0x[0-9a-f]{8,16}(?=>)', re.IGNORECASE)
46
47
48# Copied from the definition of inspect.getfullargspec from Python master,
49# and modified to remove the use of special flags that break decorated
50# callables and bound methods in the name of backwards compatibility. Used
51# under the terms of PSF license v2, which requires the above statement
52# and the following:
53#
54#   Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
55#   2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software
56#   Foundation; All Rights Reserved
57def getargspec(func: Callable) -> Any:
58    """Like inspect.getfullargspec but supports bound methods, and wrapped
59    methods."""
60    warnings.warn('sphinx.ext.inspect.getargspec() is deprecated',
61                  RemovedInSphinx50Warning, stacklevel=2)
62
63    sig = inspect.signature(func)
64
65    args = []
66    varargs = None
67    varkw = None
68    kwonlyargs = []
69    defaults = ()
70    annotations = {}
71    defaults = ()
72    kwdefaults = {}
73
74    if sig.return_annotation is not sig.empty:
75        annotations['return'] = sig.return_annotation
76
77    for param in sig.parameters.values():
78        kind = param.kind
79        name = param.name
80
81        if kind is Parameter.POSITIONAL_ONLY:
82            args.append(name)
83        elif kind is Parameter.POSITIONAL_OR_KEYWORD:
84            args.append(name)
85            if param.default is not param.empty:
86                defaults += (param.default,)  # type: ignore
87        elif kind is Parameter.VAR_POSITIONAL:
88            varargs = name
89        elif kind is Parameter.KEYWORD_ONLY:
90            kwonlyargs.append(name)
91            if param.default is not param.empty:
92                kwdefaults[name] = param.default
93        elif kind is Parameter.VAR_KEYWORD:
94            varkw = name
95
96        if param.annotation is not param.empty:
97            annotations[name] = param.annotation
98
99    if not kwdefaults:
100        # compatibility with 'func.__kwdefaults__'
101        kwdefaults = None
102
103    if not defaults:
104        # compatibility with 'func.__defaults__'
105        defaults = None
106
107    return inspect.FullArgSpec(args, varargs, varkw, defaults,
108                               kwonlyargs, kwdefaults, annotations)
109
110
111def unwrap(obj: Any) -> Any:
112    """Get an original object from wrapped object (wrapped functions)."""
113    try:
114        if hasattr(obj, '__sphinx_mock__'):
115            # Skip unwrapping mock object to avoid RecursionError
116            return obj
117        else:
118            return inspect.unwrap(obj)
119    except ValueError:
120        # might be a mock object
121        return obj
122
123
124def unwrap_all(obj: Any, *, stop: Callable = None) -> Any:
125    """
126    Get an original object from wrapped object (unwrapping partials, wrapped
127    functions, and other decorators).
128    """
129    while True:
130        if stop and stop(obj):
131            return obj
132        elif ispartial(obj):
133            obj = obj.func
134        elif inspect.isroutine(obj) and hasattr(obj, '__wrapped__'):
135            obj = obj.__wrapped__
136        elif isclassmethod(obj):
137            obj = obj.__func__
138        elif isstaticmethod(obj):
139            obj = obj.__func__
140        else:
141            return obj
142
143
144def getall(obj: Any) -> Optional[Sequence[str]]:
145    """Get __all__ attribute of the module as dict.
146
147    Return None if given *obj* does not have __all__.
148    Raises ValueError if given *obj* have invalid __all__.
149    """
150    __all__ = safe_getattr(obj, '__all__', None)
151    if __all__ is None:
152        return None
153    else:
154        if (isinstance(__all__, (list, tuple)) and all(isinstance(e, str) for e in __all__)):
155            return __all__
156        else:
157            raise ValueError(__all__)
158
159
160def getannotations(obj: Any) -> Mapping[str, Any]:
161    """Get __annotations__ from given *obj* safely."""
162    __annotations__ = safe_getattr(obj, '__annotations__', None)
163    if isinstance(__annotations__, Mapping):
164        return __annotations__
165    else:
166        return {}
167
168
169def getmro(obj: Any) -> Tuple["Type", ...]:
170    """Get __mro__ from given *obj* safely."""
171    __mro__ = safe_getattr(obj, '__mro__', None)
172    if isinstance(__mro__, tuple):
173        return __mro__
174    else:
175        return tuple()
176
177
178def getslots(obj: Any) -> Optional[Dict]:
179    """Get __slots__ attribute of the class as dict.
180
181    Return None if gienv *obj* does not have __slots__.
182    Raises TypeError if given *obj* is not a class.
183    Raises ValueError if given *obj* have invalid __slots__.
184    """
185    if not inspect.isclass(obj):
186        raise TypeError
187
188    __slots__ = safe_getattr(obj, '__slots__', None)
189    if __slots__ is None:
190        return None
191    elif isinstance(__slots__, dict):
192        return __slots__
193    elif isinstance(__slots__, str):
194        return {__slots__: None}
195    elif isinstance(__slots__, (list, tuple)):
196        return {e: None for e in __slots__}
197    else:
198        raise ValueError
199
200
201def isNewType(obj: Any) -> bool:
202    """Check the if object is a kind of NewType."""
203    __module__ = safe_getattr(obj, '__module__', None)
204    __qualname__ = safe_getattr(obj, '__qualname__', None)
205    if __module__ == 'typing' and __qualname__ == 'NewType.<locals>.new_type':
206        return True
207    else:
208        return False
209
210
211def isenumclass(x: Any) -> bool:
212    """Check if the object is subclass of enum."""
213    return inspect.isclass(x) and issubclass(x, enum.Enum)
214
215
216def isenumattribute(x: Any) -> bool:
217    """Check if the object is attribute of enum."""
218    return isinstance(x, enum.Enum)
219
220
221def unpartial(obj: Any) -> Any:
222    """Get an original object from partial object.
223
224    This returns given object itself if not partial.
225    """
226    while ispartial(obj):
227        obj = obj.func
228
229    return obj
230
231
232def ispartial(obj: Any) -> bool:
233    """Check if the object is partial."""
234    return isinstance(obj, (partial, partialmethod))
235
236
237def isclassmethod(obj: Any) -> bool:
238    """Check if the object is classmethod."""
239    if isinstance(obj, classmethod):
240        return True
241    elif inspect.ismethod(obj) and obj.__self__ is not None and isclass(obj.__self__):
242        return True
243
244    return False
245
246
247def isstaticmethod(obj: Any, cls: Any = None, name: str = None) -> bool:
248    """Check if the object is staticmethod."""
249    if isinstance(obj, staticmethod):
250        return True
251    elif cls and name:
252        # trace __mro__ if the method is defined in parent class
253        #
254        # .. note:: This only works well with new style classes.
255        for basecls in getattr(cls, '__mro__', [cls]):
256            meth = basecls.__dict__.get(name)
257            if meth:
258                if isinstance(meth, staticmethod):
259                    return True
260                else:
261                    return False
262
263    return False
264
265
266def isdescriptor(x: Any) -> bool:
267    """Check if the object is some kind of descriptor."""
268    for item in '__get__', '__set__', '__delete__':
269        if hasattr(safe_getattr(x, item, None), '__call__'):
270            return True
271    return False
272
273
274def isabstractmethod(obj: Any) -> bool:
275    """Check if the object is an abstractmethod."""
276    return safe_getattr(obj, '__isabstractmethod__', False) is True
277
278
279def is_cython_function_or_method(obj: Any) -> bool:
280    """Check if the object is a function or method in cython."""
281    try:
282        return obj.__class__.__name__ == 'cython_function_or_method'
283    except AttributeError:
284        return False
285
286
287def isattributedescriptor(obj: Any) -> bool:
288    """Check if the object is an attribute like descriptor."""
289    if inspect.isdatadescriptor(obj):
290        # data descriptor is kind of attribute
291        return True
292    elif isdescriptor(obj):
293        # non data descriptor
294        unwrapped = unwrap(obj)
295        if isfunction(unwrapped) or isbuiltin(unwrapped) or inspect.ismethod(unwrapped):
296            # attribute must not be either function, builtin and method
297            return False
298        elif is_cython_function_or_method(unwrapped):
299            # attribute must not be either function and method (for cython)
300            return False
301        elif inspect.isclass(unwrapped):
302            # attribute must not be a class
303            return False
304        elif isinstance(unwrapped, (ClassMethodDescriptorType,
305                                    MethodDescriptorType,
306                                    WrapperDescriptorType)):
307            # attribute must not be a method descriptor
308            return False
309        elif type(unwrapped).__name__ == "instancemethod":
310            # attribute must not be an instancemethod (C-API)
311            return False
312        else:
313            return True
314    else:
315        return False
316
317
318def is_singledispatch_function(obj: Any) -> bool:
319    """Check if the object is singledispatch function."""
320    if (inspect.isfunction(obj) and
321            hasattr(obj, 'dispatch') and
322            hasattr(obj, 'register') and
323            obj.dispatch.__module__ == 'functools'):
324        return True
325    else:
326        return False
327
328
329def is_singledispatch_method(obj: Any) -> bool:
330    """Check if the object is singledispatch method."""
331    try:
332        from functools import singledispatchmethod  # type: ignore
333        return isinstance(obj, singledispatchmethod)
334    except ImportError:  # py35-37
335        return False
336
337
338def isfunction(obj: Any) -> bool:
339    """Check if the object is function."""
340    return inspect.isfunction(unwrap_all(obj))
341
342
343def isbuiltin(obj: Any) -> bool:
344    """Check if the object is builtin."""
345    return inspect.isbuiltin(unwrap_all(obj))
346
347
348def isroutine(obj: Any) -> bool:
349    """Check is any kind of function or method."""
350    return inspect.isroutine(unwrap_all(obj))
351
352
353def iscoroutinefunction(obj: Any) -> bool:
354    """Check if the object is coroutine-function."""
355    # unwrap staticmethod, classmethod and partial (except wrappers)
356    obj = unwrap_all(obj, stop=lambda o: hasattr(o, '__wrapped__'))
357    if hasattr(obj, '__code__') and inspect.iscoroutinefunction(obj):
358        # check obj.__code__ because iscoroutinefunction() crashes for custom method-like
359        # objects (see https://github.com/sphinx-doc/sphinx/issues/6605)
360        return True
361    else:
362        return False
363
364
365def isproperty(obj: Any) -> bool:
366    """Check if the object is property."""
367    if sys.version_info >= (3, 8):
368        from functools import cached_property  # cached_property is available since py3.8
369        if isinstance(obj, cached_property):
370            return True
371
372    return isinstance(obj, property)
373
374
375def isgenericalias(obj: Any) -> bool:
376    """Check if the object is GenericAlias."""
377    if (hasattr(typing, '_GenericAlias') and  # only for py37+
378            isinstance(obj, typing._GenericAlias)):  # type: ignore
379        return True
380    elif (hasattr(types, 'GenericAlias') and  # only for py39+
381          isinstance(obj, types.GenericAlias)):  # type: ignore
382        return True
383    elif (hasattr(typing, '_SpecialGenericAlias') and  # for py39+
384            isinstance(obj, typing._SpecialGenericAlias)):  # type: ignore
385        return True
386    else:
387        return False
388
389
390def safe_getattr(obj: Any, name: str, *defargs: Any) -> Any:
391    """A getattr() that turns all exceptions into AttributeErrors."""
392    try:
393        return getattr(obj, name, *defargs)
394    except Exception as exc:
395        # sometimes accessing a property raises an exception (e.g.
396        # NotImplementedError), so let's try to read the attribute directly
397        try:
398            # In case the object does weird things with attribute access
399            # such that accessing `obj.__dict__` may raise an exception
400            return obj.__dict__[name]
401        except Exception:
402            pass
403
404        # this is a catch-all for all the weird things that some modules do
405        # with attribute access
406        if defargs:
407            return defargs[0]
408
409        raise AttributeError(name) from exc
410
411
412def safe_getmembers(object: Any, predicate: Callable[[str], bool] = None,
413                    attr_getter: Callable = safe_getattr) -> List[Tuple[str, Any]]:
414    """A version of inspect.getmembers() that uses safe_getattr()."""
415    warnings.warn('safe_getmembers() is deprecated', RemovedInSphinx40Warning, stacklevel=2)
416
417    results = []  # type: List[Tuple[str, Any]]
418    for key in dir(object):
419        try:
420            value = attr_getter(object, key, None)
421        except AttributeError:
422            continue
423        if not predicate or predicate(value):
424            results.append((key, value))
425    results.sort()
426    return results
427
428
429def object_description(object: Any) -> str:
430    """A repr() implementation that returns text safe to use in reST context."""
431    if isinstance(object, dict):
432        try:
433            sorted_keys = sorted(object)
434        except Exception:
435            pass  # Cannot sort dict keys, fall back to generic repr
436        else:
437            items = ("%s: %s" %
438                     (object_description(key), object_description(object[key]))
439                     for key in sorted_keys)
440            return "{%s}" % ", ".join(items)
441    if isinstance(object, set):
442        try:
443            sorted_values = sorted(object)
444        except TypeError:
445            pass  # Cannot sort set values, fall back to generic repr
446        else:
447            return "{%s}" % ", ".join(object_description(x) for x in sorted_values)
448    if isinstance(object, frozenset):
449        try:
450            sorted_values = sorted(object)
451        except TypeError:
452            pass  # Cannot sort frozenset values, fall back to generic repr
453        else:
454            return "frozenset({%s})" % ", ".join(object_description(x)
455                                                 for x in sorted_values)
456    try:
457        s = repr(object)
458    except Exception as exc:
459        raise ValueError from exc
460    # Strip non-deterministic memory addresses such as
461    # ``<__main__.A at 0x7f68cb685710>``
462    s = memory_address_re.sub('', s)
463    return s.replace('\n', ' ')
464
465
466def is_builtin_class_method(obj: Any, attr_name: str) -> bool:
467    """If attr_name is implemented at builtin class, return True.
468
469        >>> is_builtin_class_method(int, '__init__')
470        True
471
472    Why this function needed? CPython implements int.__init__ by Descriptor
473    but PyPy implements it by pure Python code.
474    """
475    try:
476        mro = getmro(obj)
477        cls = next(c for c in mro if attr_name in safe_getattr(c, '__dict__', {}))
478    except StopIteration:
479        return False
480
481    try:
482        name = safe_getattr(cls, '__name__')
483    except AttributeError:
484        return False
485
486    return getattr(builtins, name, None) is cls
487
488
489class DefaultValue:
490    """A simple wrapper for default value of the parameters of overload functions."""
491
492    def __init__(self, value: str) -> None:
493        self.value = value
494
495    def __eq__(self, other: object) -> bool:
496        return self.value == other
497
498    def __repr__(self) -> str:
499        return self.value
500
501
502def _should_unwrap(subject: Callable) -> bool:
503    """Check the function should be unwrapped on getting signature."""
504    if (safe_getattr(subject, '__globals__', None) and
505            subject.__globals__.get('__name__') == 'contextlib' and  # type: ignore
506            subject.__globals__.get('__file__') == contextlib.__file__):  # type: ignore
507        # contextmanger should be unwrapped
508        return True
509
510    return False
511
512
513def signature(subject: Callable, bound_method: bool = False, follow_wrapped: bool = None,
514              type_aliases: Dict = {}) -> inspect.Signature:
515    """Return a Signature object for the given *subject*.
516
517    :param bound_method: Specify *subject* is a bound method or not
518    :param follow_wrapped: Same as ``inspect.signature()``.
519    """
520
521    if follow_wrapped is None:
522        follow_wrapped = True
523    else:
524        warnings.warn('The follow_wrapped argument of sphinx.util.inspect.signature() is '
525                      'deprecated', RemovedInSphinx50Warning, stacklevel=2)
526
527    try:
528        try:
529            if _should_unwrap(subject):
530                signature = inspect.signature(subject)
531            else:
532                signature = inspect.signature(subject, follow_wrapped=follow_wrapped)
533        except ValueError:
534            # follow built-in wrappers up (ex. functools.lru_cache)
535            signature = inspect.signature(subject)
536        parameters = list(signature.parameters.values())
537        return_annotation = signature.return_annotation
538    except IndexError:
539        # Until python 3.6.4, cpython has been crashed on inspection for
540        # partialmethods not having any arguments.
541        # https://bugs.python.org/issue33009
542        if hasattr(subject, '_partialmethod'):
543            parameters = []
544            return_annotation = Parameter.empty
545        else:
546            raise
547
548    try:
549        # Resolve annotations using ``get_type_hints()`` and type_aliases.
550        annotations = typing.get_type_hints(subject, None, type_aliases)
551        for i, param in enumerate(parameters):
552            if param.name in annotations:
553                parameters[i] = param.replace(annotation=annotations[param.name])
554        if 'return' in annotations:
555            return_annotation = annotations['return']
556    except Exception:
557        # ``get_type_hints()`` does not support some kind of objects like partial,
558        # ForwardRef and so on.
559        pass
560
561    if bound_method:
562        if inspect.ismethod(subject):
563            # ``inspect.signature()`` considers the subject is a bound method and removes
564            # first argument from signature.  Therefore no skips are needed here.
565            pass
566        else:
567            if len(parameters) > 0:
568                parameters.pop(0)
569
570    # To allow to create signature object correctly for pure python functions,
571    # pass an internal parameter __validate_parameters__=False to Signature
572    #
573    # For example, this helps a function having a default value `inspect._empty`.
574    # refs: https://github.com/sphinx-doc/sphinx/issues/7935
575    return inspect.Signature(parameters, return_annotation=return_annotation,  # type: ignore
576                             __validate_parameters__=False)
577
578
579def evaluate_signature(sig: inspect.Signature, globalns: Dict = None, localns: Dict = None
580                       ) -> inspect.Signature:
581    """Evaluate unresolved type annotations in a signature object."""
582    def evaluate_forwardref(ref: ForwardRef, globalns: Dict, localns: Dict) -> Any:
583        """Evaluate a forward reference."""
584        if sys.version_info > (3, 9):
585            return ref._evaluate(globalns, localns, frozenset())
586        else:
587            return ref._evaluate(globalns, localns)
588
589    def evaluate(annotation: Any, globalns: Dict, localns: Dict) -> Any:
590        """Evaluate unresolved type annotation."""
591        try:
592            if isinstance(annotation, str):
593                ref = ForwardRef(annotation, True)
594                annotation = evaluate_forwardref(ref, globalns, localns)
595
596                if isinstance(annotation, ForwardRef):
597                    annotation = evaluate_forwardref(ref, globalns, localns)
598                elif isinstance(annotation, str):
599                    # might be a ForwardRef'ed annotation in overloaded functions
600                    ref = ForwardRef(annotation, True)
601                    annotation = evaluate_forwardref(ref, globalns, localns)
602        except (NameError, TypeError):
603            # failed to evaluate type. skipped.
604            pass
605
606        return annotation
607
608    if globalns is None:
609        globalns = {}
610    if localns is None:
611        localns = globalns
612
613    parameters = list(sig.parameters.values())
614    for i, param in enumerate(parameters):
615        if param.annotation:
616            annotation = evaluate(param.annotation, globalns, localns)
617            parameters[i] = param.replace(annotation=annotation)
618
619    return_annotation = sig.return_annotation
620    if return_annotation:
621        return_annotation = evaluate(return_annotation, globalns, localns)
622
623    return sig.replace(parameters=parameters, return_annotation=return_annotation)
624
625
626def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
627                        show_return_annotation: bool = True) -> str:
628    """Stringify a Signature object.
629
630    :param show_annotation: Show annotation in result
631    """
632    args = []
633    last_kind = None
634    for param in sig.parameters.values():
635        if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY:
636            # PEP-570: Separator for Positional Only Parameter: /
637            args.append('/')
638        if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD,
639                                                              param.POSITIONAL_ONLY,
640                                                              None):
641            # PEP-3102: Separator for Keyword Only Parameter: *
642            args.append('*')
643
644        arg = StringIO()
645        if param.kind == param.VAR_POSITIONAL:
646            arg.write('*' + param.name)
647        elif param.kind == param.VAR_KEYWORD:
648            arg.write('**' + param.name)
649        else:
650            arg.write(param.name)
651
652        if show_annotation and param.annotation is not param.empty:
653            arg.write(': ')
654            arg.write(stringify_annotation(param.annotation))
655        if param.default is not param.empty:
656            if show_annotation and param.annotation is not param.empty:
657                arg.write(' = ')
658            else:
659                arg.write('=')
660            arg.write(object_description(param.default))
661
662        args.append(arg.getvalue())
663        last_kind = param.kind
664
665    if last_kind == Parameter.POSITIONAL_ONLY:
666        # PEP-570: Separator for Positional Only Parameter: /
667        args.append('/')
668
669    if (sig.return_annotation is Parameter.empty or
670            show_annotation is False or
671            show_return_annotation is False):
672        return '(%s)' % ', '.join(args)
673    else:
674        annotation = stringify_annotation(sig.return_annotation)
675        return '(%s) -> %s' % (', '.join(args), annotation)
676
677
678def signature_from_str(signature: str) -> inspect.Signature:
679    """Create a Signature object from string."""
680    code = 'def func' + signature + ': pass'
681    module = ast.parse(code)
682    function = cast(ast.FunctionDef, module.body[0])  # type: ignore
683
684    return signature_from_ast(function, code)
685
686
687def signature_from_ast(node: ast.FunctionDef, code: str = '') -> inspect.Signature:
688    """Create a Signature object from AST *node*."""
689    args = node.args
690    defaults = list(args.defaults)
691    params = []
692    if hasattr(args, "posonlyargs"):
693        posonlyargs = len(args.posonlyargs)  # type: ignore
694        positionals = posonlyargs + len(args.args)
695    else:
696        posonlyargs = 0
697        positionals = len(args.args)
698
699    for _ in range(len(defaults), positionals):
700        defaults.insert(0, Parameter.empty)
701
702    if hasattr(args, "posonlyargs"):
703        for i, arg in enumerate(args.posonlyargs):  # type: ignore
704            if defaults[i] is Parameter.empty:
705                default = Parameter.empty
706            else:
707                default = DefaultValue(ast_unparse(defaults[i], code))
708
709            annotation = ast_unparse(arg.annotation, code) or Parameter.empty
710            params.append(Parameter(arg.arg, Parameter.POSITIONAL_ONLY,
711                                    default=default, annotation=annotation))
712
713    for i, arg in enumerate(args.args):
714        if defaults[i + posonlyargs] is Parameter.empty:
715            default = Parameter.empty
716        else:
717            default = DefaultValue(ast_unparse(defaults[i + posonlyargs], code))
718
719        annotation = ast_unparse(arg.annotation, code) or Parameter.empty
720        params.append(Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD,
721                                default=default, annotation=annotation))
722
723    if args.vararg:
724        annotation = ast_unparse(args.vararg.annotation, code) or Parameter.empty
725        params.append(Parameter(args.vararg.arg, Parameter.VAR_POSITIONAL,
726                                annotation=annotation))
727
728    for i, arg in enumerate(args.kwonlyargs):
729        default = ast_unparse(args.kw_defaults[i], code) or Parameter.empty
730        annotation = ast_unparse(arg.annotation, code) or Parameter.empty
731        params.append(Parameter(arg.arg, Parameter.KEYWORD_ONLY, default=default,
732                                annotation=annotation))
733
734    if args.kwarg:
735        annotation = ast_unparse(args.kwarg.annotation, code) or Parameter.empty
736        params.append(Parameter(args.kwarg.arg, Parameter.VAR_KEYWORD,
737                                annotation=annotation))
738
739    return_annotation = ast_unparse(node.returns, code) or Parameter.empty
740
741    return inspect.Signature(params, return_annotation=return_annotation)
742
743
744class Signature:
745    """The Signature object represents the call signature of a callable object and
746    its return annotation.
747    """
748
749    empty = inspect.Signature.empty
750
751    def __init__(self, subject: Callable, bound_method: bool = False,
752                 has_retval: bool = True) -> None:
753        warnings.warn('sphinx.util.inspect.Signature() is deprecated',
754                      RemovedInSphinx40Warning, stacklevel=2)
755
756        # check subject is not a built-in class (ex. int, str)
757        if (isinstance(subject, type) and
758                is_builtin_class_method(subject, "__new__") and
759                is_builtin_class_method(subject, "__init__")):
760            raise TypeError("can't compute signature for built-in type {}".format(subject))
761
762        self.subject = subject
763        self.has_retval = has_retval
764        self.partialmethod_with_noargs = False
765
766        try:
767            self.signature = inspect.signature(subject)  # type: Optional[inspect.Signature]
768        except IndexError:
769            # Until python 3.6.4, cpython has been crashed on inspection for
770            # partialmethods not having any arguments.
771            # https://bugs.python.org/issue33009
772            if hasattr(subject, '_partialmethod'):
773                self.signature = None
774                self.partialmethod_with_noargs = True
775            else:
776                raise
777
778        try:
779            self.annotations = typing.get_type_hints(subject)
780        except Exception:
781            # get_type_hints() does not support some kind of objects like partial,
782            # ForwardRef and so on.  For them, it raises an exception. In that case,
783            # we try to build annotations from argspec.
784            self.annotations = {}
785
786        if bound_method:
787            # client gives a hint that the subject is a bound method
788
789            if inspect.ismethod(subject):
790                # inspect.signature already considers the subject is bound method.
791                # So it is not need to skip first argument.
792                self.skip_first_argument = False
793            else:
794                self.skip_first_argument = True
795        else:
796            # inspect.signature recognizes type of method properly without any hints
797            self.skip_first_argument = False
798
799    @property
800    def parameters(self) -> Mapping:
801        if self.partialmethod_with_noargs:
802            return {}
803        else:
804            return self.signature.parameters
805
806    @property
807    def return_annotation(self) -> Any:
808        if self.signature:
809            if self.has_retval:
810                return self.signature.return_annotation
811            else:
812                return Parameter.empty
813        else:
814            return None
815
816    def format_args(self, show_annotation: bool = True) -> str:
817        def get_annotation(param: Parameter) -> Any:
818            if isinstance(param.annotation, str) and param.name in self.annotations:
819                return self.annotations[param.name]
820            else:
821                return param.annotation
822
823        args = []
824        last_kind = None
825        for i, param in enumerate(self.parameters.values()):
826            # skip first argument if subject is bound method
827            if self.skip_first_argument and i == 0:
828                continue
829
830            arg = StringIO()
831
832            # insert '*' between POSITIONAL args and KEYWORD_ONLY args::
833            #     func(a, b, *, c, d):
834            if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD,
835                                                                  param.POSITIONAL_ONLY,
836                                                                  None):
837                args.append('*')
838
839            if param.kind in (param.POSITIONAL_ONLY,
840                              param.POSITIONAL_OR_KEYWORD,
841                              param.KEYWORD_ONLY):
842                arg.write(param.name)
843                if show_annotation and param.annotation is not param.empty:
844                    arg.write(': ')
845                    arg.write(stringify_annotation(get_annotation(param)))
846                if param.default is not param.empty:
847                    if param.annotation is param.empty or show_annotation is False:
848                        arg.write('=')
849                        arg.write(object_description(param.default))
850                    else:
851                        arg.write(' = ')
852                        arg.write(object_description(param.default))
853            elif param.kind == param.VAR_POSITIONAL:
854                arg.write('*')
855                arg.write(param.name)
856                if show_annotation and param.annotation is not param.empty:
857                    arg.write(': ')
858                    arg.write(stringify_annotation(get_annotation(param)))
859            elif param.kind == param.VAR_KEYWORD:
860                arg.write('**')
861                arg.write(param.name)
862                if show_annotation and param.annotation is not param.empty:
863                    arg.write(': ')
864                    arg.write(stringify_annotation(get_annotation(param)))
865
866            args.append(arg.getvalue())
867            last_kind = param.kind
868
869        if self.return_annotation is Parameter.empty or show_annotation is False:
870            return '(%s)' % ', '.join(args)
871        else:
872            if 'return' in self.annotations:
873                annotation = stringify_annotation(self.annotations['return'])
874            else:
875                annotation = stringify_annotation(self.return_annotation)
876
877            return '(%s) -> %s' % (', '.join(args), annotation)
878
879    def format_annotation(self, annotation: Any) -> str:
880        """Return formatted representation of a type annotation."""
881        return stringify_annotation(annotation)
882
883    def format_annotation_new(self, annotation: Any) -> str:
884        """format_annotation() for py37+"""
885        return stringify_annotation(annotation)
886
887    def format_annotation_old(self, annotation: Any) -> str:
888        """format_annotation() for py36 or below"""
889        return stringify_annotation(annotation)
890
891
892def getdoc(obj: Any, attrgetter: Callable = safe_getattr,
893           allow_inherited: bool = False, cls: Any = None, name: str = None) -> str:
894    """Get the docstring for the object.
895
896    This tries to obtain the docstring for some kind of objects additionally:
897
898    * partial functions
899    * inherited docstring
900    * inherited decorated methods
901    """
902    doc = attrgetter(obj, '__doc__', None)
903    if ispartial(obj) and doc == obj.__class__.__doc__:
904        return getdoc(obj.func)
905    elif doc is None and allow_inherited:
906        doc = inspect.getdoc(obj)
907
908        if doc is None and cls:
909            # inspect.getdoc() does not support some kind of inherited and decorated methods.
910            # This tries to obtain the docstring from super classes.
911            for basecls in getattr(cls, '__mro__', []):
912                meth = safe_getattr(basecls, name, None)
913                if meth is not None:
914                    doc = inspect.getdoc(meth)
915                    if doc:
916                        break
917
918    return doc
919