mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Retireve docstirng form base classes (Closes #3140)
This commit is contained in:
parent
b2f841fcaa
commit
620491fcd5
@ -393,6 +393,16 @@ There are also new config values that you can set:
|
||||
If ``False`` is given, autodoc forcely suppresses the error if the imported
|
||||
module emits warnings. By default, ``True``.
|
||||
|
||||
.. confval:: autodoc_inherit_docstrings
|
||||
|
||||
This value controls the docstrings inheritance.
|
||||
If set to True the cocstring for classes or methods, if not explicitly set,
|
||||
is inherited form parents.
|
||||
|
||||
The default is ``True``.
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Docstring preprocessing
|
||||
-----------------------
|
||||
|
||||
|
@ -35,7 +35,7 @@ from sphinx.util import logging
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \
|
||||
safe_getattr, object_description, is_builtin_class_method, \
|
||||
isenumclass, isenumattribute
|
||||
isenumclass, isenumattribute, getdoc
|
||||
from sphinx.util.docstrings import prepare_docstring
|
||||
|
||||
if False:
|
||||
@ -525,6 +525,8 @@ class Documenter(object):
|
||||
# type: (unicode, int) -> List[List[unicode]]
|
||||
"""Decode and return lines of the docstring(s) for the object."""
|
||||
docstring = self.get_attr(self.object, '__doc__', None)
|
||||
if docstring is None and self.env.config.autodoc_inherit_docstrings:
|
||||
docstring = getdoc(self.object)
|
||||
# make sure we have Unicode docstrings, then sanitize and split
|
||||
# into lines
|
||||
if isinstance(docstring, text_type):
|
||||
@ -682,6 +684,9 @@ class Documenter(object):
|
||||
isattr = False
|
||||
|
||||
doc = self.get_attr(member, '__doc__', None)
|
||||
if doc is None and self.env.config.autodoc_inherit_docstrings:
|
||||
doc = getdoc(member)
|
||||
|
||||
# if the member __doc__ is the same as self's __doc__, it's just
|
||||
# inherited and therefore not the member's doc
|
||||
cls = self.get_attr(member, '__class__', None)
|
||||
@ -1617,6 +1622,7 @@ def setup(app):
|
||||
app.add_config_value('autodoc_docstring_signature', True, True)
|
||||
app.add_config_value('autodoc_mock_imports', [], True)
|
||||
app.add_config_value('autodoc_warningiserror', True, True)
|
||||
app.add_config_value('autodoc_inherit_docstrings', True, True)
|
||||
app.add_event('autodoc-process-docstring')
|
||||
app.add_event('autodoc-process-signature')
|
||||
app.add_event('autodoc-skip-member')
|
||||
|
@ -11,6 +11,7 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
import sys
|
||||
import typing
|
||||
import inspect
|
||||
from collections import OrderedDict
|
||||
@ -456,3 +457,98 @@ class Signature(object):
|
||||
', '.join(param_strings))
|
||||
|
||||
return qualified_name
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5):
|
||||
getdoc = inspect.getdoc
|
||||
else:
|
||||
# code copyed from the inspect.py module of the standard library
|
||||
# of Python 3.5
|
||||
|
||||
def _findclass(func):
|
||||
cls = sys.modules.get(func.__module__)
|
||||
if cls is None:
|
||||
return None
|
||||
for name in func.__qualname__.split('.')[:-1]:
|
||||
cls = getattr(cls, name)
|
||||
if not inspect.isclass(cls):
|
||||
return None
|
||||
return cls
|
||||
|
||||
def _finddoc(obj):
|
||||
if inspect.isclass(obj):
|
||||
for base in obj.__mro__:
|
||||
if base is not object:
|
||||
try:
|
||||
doc = base.__doc__
|
||||
except AttributeError:
|
||||
continue
|
||||
if doc is not None:
|
||||
return doc
|
||||
return None
|
||||
|
||||
if inspect.ismethod(obj):
|
||||
name = obj.__func__.__name__
|
||||
self = obj.__self__
|
||||
if (inspect.isclass(self) and
|
||||
getattr(getattr(self, name, None), '__func__') is obj.__func__):
|
||||
# classmethod
|
||||
cls = self
|
||||
else:
|
||||
cls = self.__class__
|
||||
elif inspect.isfunction(obj):
|
||||
name = obj.__name__
|
||||
cls = _findclass(obj)
|
||||
if cls is None or getattr(cls, name) is not obj:
|
||||
return None
|
||||
elif inspect.isbuiltin(obj):
|
||||
name = obj.__name__
|
||||
self = obj.__self__
|
||||
if (inspect.isclass(self) and
|
||||
self.__qualname__ + '.' + name == obj.__qualname__):
|
||||
# classmethod
|
||||
cls = self
|
||||
else:
|
||||
cls = self.__class__
|
||||
# Should be tested before isdatadescriptor().
|
||||
elif isinstance(obj, property):
|
||||
func = obj.fget
|
||||
name = func.__name__
|
||||
cls = _findclass(func)
|
||||
if cls is None or getattr(cls, name) is not obj:
|
||||
return None
|
||||
elif inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj):
|
||||
name = obj.__name__
|
||||
cls = obj.__objclass__
|
||||
if getattr(cls, name) is not obj:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
for base in cls.__mro__:
|
||||
try:
|
||||
doc = getattr(base, name).__doc__
|
||||
except AttributeError:
|
||||
continue
|
||||
if doc is not None:
|
||||
return doc
|
||||
return None
|
||||
|
||||
def getdoc(object):
|
||||
"""Get the documentation string for an object.
|
||||
|
||||
All tabs are expanded to spaces. To clean up docstrings that are
|
||||
indented to line up with blocks of code, any whitespace than can be
|
||||
uniformly removed from the second line onwards is removed."""
|
||||
try:
|
||||
doc = object.__doc__
|
||||
except AttributeError:
|
||||
return None
|
||||
if doc is None:
|
||||
try:
|
||||
doc = _finddoc(object)
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
if not isinstance(doc, str):
|
||||
return None
|
||||
return inspect.cleandoc(doc)
|
||||
|
Loading…
Reference in New Issue
Block a user