mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Handle singledispatch functions with rewritten signatures.
If a singledispatch function has its `__signature__` rewritten, autodoc fails to annotate that signature because `func.__annotations__` is not consulted. Instead, directly assign to `__signature__` instead.
This commit is contained in:
parent
5caaa5534b
commit
f9048cf18e
@ -13,6 +13,7 @@
|
|||||||
import importlib
|
import importlib
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
from inspect import Parameter
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union
|
from typing import Any, Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
@ -1108,9 +1109,10 @@ class SingledispatchFunctionDocumenter(FunctionDocumenter):
|
|||||||
if len(sig.parameters) == 0:
|
if len(sig.parameters) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
name = list(sig.parameters)[0]
|
params = list(sig.parameters.values())
|
||||||
if name not in func.__annotations__:
|
if params[0].annotation is Parameter.empty:
|
||||||
func.__annotations__[name] = typ
|
params[0] = params[0].replace(annotation=typ)
|
||||||
|
func.__signature__ = sig.replace(parameters=params) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class DecoratorDocumenter(FunctionDocumenter):
|
class DecoratorDocumenter(FunctionDocumenter):
|
||||||
@ -1508,13 +1510,14 @@ class SingledispatchMethodDocumenter(MethodDocumenter):
|
|||||||
|
|
||||||
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
|
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
|
||||||
"""Annotate type hint to the first argument of function if needed."""
|
"""Annotate type hint to the first argument of function if needed."""
|
||||||
sig = inspect.signature(func, bound_method=True)
|
sig = inspect.signature(func)
|
||||||
if len(sig.parameters) == 0:
|
if len(sig.parameters) == 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
name = list(sig.parameters)[0]
|
params = list(sig.parameters.values())
|
||||||
if name not in func.__annotations__:
|
if params[1].annotation is Parameter.empty:
|
||||||
func.__annotations__[name] = typ
|
params[1] = params[1].replace(annotation=typ)
|
||||||
|
func.__signature__ = sig.replace(parameters=params) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): # type: ignore
|
class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): # type: ignore
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
from functools import singledispatch
|
from functools import singledispatch
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def assign_signature(func):
|
||||||
|
# This is intended to cover more complex signature-rewriting decorators.
|
||||||
|
func.__signature__ = inspect.signature(func)
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
@singledispatch
|
@singledispatch
|
||||||
@ -14,6 +21,7 @@ def _func_int(arg, kwarg=None):
|
|||||||
|
|
||||||
|
|
||||||
@func.register(str)
|
@func.register(str)
|
||||||
|
@assign_signature
|
||||||
def _func_str(arg, kwarg=None):
|
def _func_str(arg, kwarg=None):
|
||||||
"""A function for str."""
|
"""A function for str."""
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user