Merge branch '1.8' into 5437_autodoc_crashed_for_egg_packages

This commit is contained in:
Takeshi KOMIYA 2018-09-18 17:44:27 +09:00 committed by GitHub
commit c938dd29d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 29 deletions

View File

@ -20,6 +20,8 @@ Bugs fixed
* #5421: autodoc emits deprecation warning for :confval:`autodoc_default_flags` * #5421: autodoc emits deprecation warning for :confval:`autodoc_default_flags`
* #5422: lambda object causes PicklingError on storing environment * #5422: lambda object causes PicklingError on storing environment
* #5417: Sphinx fails to build with syntax error in Python 2.7.5 * #5417: Sphinx fails to build with syntax error in Python 2.7.5
* #4911: add latexpdf to make.bat for non make-mode
* #5436: Autodoc does not work with enum subclasses with properties/methods
* #5437: autodoc: crashed on modules importing eggs * #5437: autodoc: crashed on modules importing eggs
Testing Testing
@ -37,6 +39,7 @@ Dependencies
``xelatex/lualatex``), instructs ``make latexpdf`` to use :program:`xindy` ``xelatex/lualatex``), instructs ``make latexpdf`` to use :program:`xindy`
for general index. Make sure your LaTeX distribution includes it. for general index. Make sure your LaTeX distribution includes it.
(refs: #5134) (refs: #5134)
* LaTeX: ``latexmk`` is required for ``make latexpdf`` on Windows
Incompatible changes Incompatible changes
-------------------- --------------------

View File

@ -16,7 +16,7 @@ import warnings
from collections import namedtuple from collections import namedtuple
from types import FunctionType, MethodType, ModuleType from types import FunctionType, MethodType, ModuleType
from six import PY2 from six import PY2, iteritems
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.inspect import isenumclass, safe_getattr from sphinx.util.inspect import isenumclass, safe_getattr
@ -248,6 +248,11 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None):
if name not in members: if name not in members:
members[name] = Attribute(name, True, value) members[name] = Attribute(name, True, value)
superclass = subject.__mro__[1]
for name, value in iteritems(obj_dict):
if name not in superclass.__dict__:
members[name] = Attribute(name, True, value)
# other members # other members
for name in dir(subject): for name in dir(subject):
try: try:

View File

@ -31,6 +31,7 @@ if "%1" == "help" (
echo. devhelp to make HTML files and a Devhelp project echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. latexpdf to make LaTeX files and run them through platex/dvipdfmx
echo. text to make text files echo. text to make text files
echo. man to make manual pages echo. man to make manual pages
echo. texinfo to make Texinfo files echo. texinfo to make Texinfo files

View File

@ -223,19 +223,6 @@ class InstAttCls(object):
"""Docstring for instance attribute InstAttCls.ia2.""" """Docstring for instance attribute InstAttCls.ia2."""
class EnumCls(enum.Enum):
"""
this is enum class
"""
#: doc for val1
val1 = 12
val2 = 23 #: doc for val2
val3 = 34
"""doc for val3"""
val4 = 34
class CustomIter(object): class CustomIter(object):
def __init__(self): def __init__(self):
"""Create a new `CustomIter`.""" """Create a new `CustomIter`."""

View File

@ -0,0 +1,19 @@
from __future__ import absolute_import
import enum
class EnumCls(enum.Enum):
"""
this is enum class
"""
#: doc for val1
val1 = 12
val2 = 23 #: doc for val2
val3 = 34
"""doc for val3"""
val4 = 34
def say_hello(self):
"""a method says hello to you."""
pass

View File

@ -829,7 +829,6 @@ def test_autodoc_ignore_module_all(app):
'.. py:class:: CustomDataDescriptor2(doc)', '.. py:class:: CustomDataDescriptor2(doc)',
'.. py:class:: CustomDataDescriptorMeta', '.. py:class:: CustomDataDescriptorMeta',
'.. py:class:: CustomDict', '.. py:class:: CustomDict',
'.. py:class:: EnumCls',
'.. py:class:: InstAttCls()', '.. py:class:: InstAttCls()',
'.. py:class:: Outer', '.. py:class:: Outer',
' .. py:class:: Outer.Inner', ' .. py:class:: Outer.Inner',
@ -1263,48 +1262,54 @@ def test_instance_attributes(app):
def test_enum_class(app): def test_enum_class(app):
options = {"members": None, options = {"members": None,
"undoc-members": True} "undoc-members": True}
actual = do_autodoc(app, 'class', 'target.EnumCls', options) actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options)
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:class:: EnumCls', '.. py:class:: EnumCls',
' :module: target', ' :module: target.enum',
'', '',
' this is enum class', ' this is enum class',
' ', ' ',
' ', ' ',
' .. py:method:: EnumCls.say_hello()',
' :module: target.enum',
' ',
' a method says hello to you.',
' ',
' ',
' .. py:attribute:: EnumCls.val1', ' .. py:attribute:: EnumCls.val1',
' :module: target', ' :module: target.enum',
' :annotation: = 12', ' :annotation: = 12',
' ', ' ',
' doc for val1', ' doc for val1',
' ', ' ',
' ', ' ',
' .. py:attribute:: EnumCls.val2', ' .. py:attribute:: EnumCls.val2',
' :module: target', ' :module: target.enum',
' :annotation: = 23', ' :annotation: = 23',
' ', ' ',
' doc for val2', ' doc for val2',
' ', ' ',
' ', ' ',
' .. py:attribute:: EnumCls.val3', ' .. py:attribute:: EnumCls.val3',
' :module: target', ' :module: target.enum',
' :annotation: = 34', ' :annotation: = 34',
' ', ' ',
' doc for val3', ' doc for val3',
' ', ' ',
' ', ' ',
' .. py:attribute:: EnumCls.val4', ' .. py:attribute:: EnumCls.val4',
' :module: target', ' :module: target.enum',
' :annotation: = 34', ' :annotation: = 34',
' ' ' '
] ]
# checks for an attribute of EnumClass # checks for an attribute of EnumClass
actual = do_autodoc(app, 'attribute', 'target.EnumCls.val1') actual = do_autodoc(app, 'attribute', 'target.enum.EnumCls.val1')
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:attribute:: EnumCls.val1', '.. py:attribute:: EnumCls.val1',
' :module: target', ' :module: target.enum',
' :annotation: = 12', ' :annotation: = 12',
'', '',
' doc for val1', ' doc for val1',
@ -1473,7 +1478,7 @@ def test_merge_autodoc_default_flags2(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_default_options(app): def test_autodoc_default_options(app):
# no settings # no settings
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' not in actual assert ' .. py:attribute:: EnumCls.val1' not in actual
assert ' .. py:attribute:: EnumCls.val4' not in actual assert ' .. py:attribute:: EnumCls.val4' not in actual
actual = do_autodoc(app, 'class', 'target.CustomIter') actual = do_autodoc(app, 'class', 'target.CustomIter')
@ -1481,7 +1486,7 @@ def test_autodoc_default_options(app):
# with :members: # with :members:
app.config.autodoc_default_options = {'members': None} app.config.autodoc_default_options = {'members': None}
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' in actual assert ' .. py:attribute:: EnumCls.val1' in actual
assert ' .. py:attribute:: EnumCls.val4' not in actual assert ' .. py:attribute:: EnumCls.val4' not in actual
@ -1490,7 +1495,7 @@ def test_autodoc_default_options(app):
'members': None, 'members': None,
'undoc-members': None, 'undoc-members': None,
} }
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' in actual assert ' .. py:attribute:: EnumCls.val1' in actual
assert ' .. py:attribute:: EnumCls.val4' in actual assert ' .. py:attribute:: EnumCls.val4' in actual
@ -1516,7 +1521,7 @@ def test_autodoc_default_options(app):
'members': None, 'members': None,
'exclude-members': None, 'exclude-members': None,
} }
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' in actual assert ' .. py:attribute:: EnumCls.val1' in actual
assert ' .. py:attribute:: EnumCls.val4' not in actual assert ' .. py:attribute:: EnumCls.val4' not in actual
app.config.autodoc_default_options = { app.config.autodoc_default_options = {
@ -1540,7 +1545,7 @@ def test_autodoc_default_options(app):
def test_autodoc_default_options_with_values(app): def test_autodoc_default_options_with_values(app):
# with :members: # with :members:
app.config.autodoc_default_options = {'members': 'val1,val2'} app.config.autodoc_default_options = {'members': 'val1,val2'}
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' in actual assert ' .. py:attribute:: EnumCls.val1' in actual
assert ' .. py:attribute:: EnumCls.val2' in actual assert ' .. py:attribute:: EnumCls.val2' in actual
assert ' .. py:attribute:: EnumCls.val3' not in actual assert ' .. py:attribute:: EnumCls.val3' not in actual
@ -1564,7 +1569,7 @@ def test_autodoc_default_options_with_values(app):
'members': None, 'members': None,
'exclude-members': 'val1' 'exclude-members': 'val1'
} }
actual = do_autodoc(app, 'class', 'target.EnumCls') actual = do_autodoc(app, 'class', 'target.enum.EnumCls')
assert ' .. py:attribute:: EnumCls.val1' not in actual assert ' .. py:attribute:: EnumCls.val1' not in actual
assert ' .. py:attribute:: EnumCls.val2' in actual assert ' .. py:attribute:: EnumCls.val2' in actual
assert ' .. py:attribute:: EnumCls.val3' in actual assert ' .. py:attribute:: EnumCls.val3' in actual