Skip to content

Commit

Permalink
Merge pull request #10427 from tk0miya/10421_autodoc_preserve_default…
Browse files Browse the repository at this point in the history
…s_for_classmethod

Fix #10421: autodoc_preserve_defaults doesn't work on class methods
  • Loading branch information
tk0miya committed May 8, 2022
2 parents f58771c + 10dd5a0 commit e770e25
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion sphinx/ext/autodoc/preserve_defaults.py
Expand Up @@ -7,6 +7,7 @@
import ast
import inspect
import sys
from inspect import Parameter
from typing import Any, Dict, List, Optional

from sphinx.application import Sphinx
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions tests/roots/test-ext-autodoc/target/preserve_defaults.py
Expand Up @@ -22,3 +22,9 @@ def meth(self, name: str = CONSTANT, sentinel: Any = SENTINEL,
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"""
9 changes: 9 additions & 0 deletions tests/test_ext_autodoc_preserve_defaults.py
Expand Up @@ -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),
Expand Down

0 comments on commit e770e25

Please sign in to comment.