Merge pull request #10427 from tk0miya/10421_autodoc_preserve_defaults_for_classmethod

Fix #10421: autodoc_preserve_defaults doesn't work on class methods
This commit is contained in:
Takeshi KOMIYA 2022-05-08 23:19:10 +09:00 committed by GitHub
commit e770e2567f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 1 deletions

View File

@ -99,6 +99,8 @@ Bugs fixed
function
* #10305: autodoc: Failed to extract optional forward-ref'ed typehints correctly
via :confval:`autodoc_type_aliases`
* #10421: autodoc: :confval:`autodoc_preserve_defaults` doesn't work on class
methods
* #10214: html: invalid language tag was generated if :confval:`language`
contains a country code (ex. zh_CN)
* #9974: html: Updated jQuery version from 3.5.1 to 3.6.0

View File

@ -7,6 +7,7 @@ and keep them not evaluated for readability.
import ast
import inspect
import sys
from inspect import Parameter
from typing import Any, Dict, List, Optional
from sphinx.application import Sphinx
@ -96,8 +97,18 @@ def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:
if value is None:
value = ast_unparse(default) # type: ignore
parameters[i] = param.replace(default=DefaultValue(value))
if bound_method and inspect.ismethod(obj):
# classmethods
cls = inspect.Parameter('cls', Parameter.POSITIONAL_OR_KEYWORD)
parameters.insert(0, cls)
sig = sig.replace(parameters=parameters)
obj.__signature__ = sig
if bound_method and inspect.ismethod(obj):
# classmethods can't be assigned __signature__ attribute.
obj.__dict__['__signature__'] = sig
else:
obj.__signature__ = sig
except (AttributeError, TypeError):
# failed to update signature (ex. built-in or extension types)
pass

View File

@ -22,3 +22,9 @@ class Class:
now: datetime = datetime.now(), color: int = 0xFFFFFF,
*, kwarg1, kwarg2 = 0xFFFFFF) -> None:
"""docstring"""
@classmethod
def clsmeth(cls, name: str = CONSTANT, sentinel: Any = SENTINEL,
now: datetime = datetime.now(), color: int = 0xFFFFFF,
*, kwarg1, kwarg2 = 0xFFFFFF) -> None:
"""docstring"""

View File

@ -28,6 +28,15 @@ def test_preserve_defaults(app):
' docstring',
'',
'',
' .. py:method:: Class.clsmeth(name: str = CONSTANT, sentinel: ~typing.Any = '
'SENTINEL, now: ~datetime.datetime = datetime.now(), color: int = %s, *, '
'kwarg1, kwarg2=%s) -> None' % (color, color),
' :module: target.preserve_defaults',
' :classmethod:',
'',
' docstring',
'',
'',
' .. py:method:: Class.meth(name: str = CONSTANT, sentinel: ~typing.Any = '
'SENTINEL, now: ~datetime.datetime = datetime.now(), color: int = %s, *, '
'kwarg1, kwarg2=%s) -> None' % (color, color),