Merge pull request #6441 from tk0miya/refactor_test_autodoc

Refactor test_autodoc
This commit is contained in:
Takeshi KOMIYA 2019-06-04 01:03:06 +09:00 committed by GitHub
commit ff43a0edb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 358 additions and 170 deletions

View File

@ -34,26 +34,7 @@ def _funky_classmethod(name, b, c, d, docstring=None):
return classmethod(function) return classmethod(function)
class Base(object): class Class(object):
def inheritedmeth(self):
"""Inherited function."""
@classmethod
def inheritedclassmeth(cls):
"""Inherited class method."""
@staticmethod
def inheritedstaticmeth(cls):
"""Inherited static method."""
class Derived(Base):
def inheritedmeth(self):
# no docstring here
pass
class Class(Base):
"""Class to document.""" """Class to document."""
def meth(self): def meth(self):

View File

@ -0,0 +1,35 @@
class A:
"""A class having no __init__, no __new__"""
class B:
"""A class having __init__(no docstring), no __new__"""
def __init__(self):
pass
class C:
"""A class having __init__, no __new__"""
def __init__(self):
"""__init__ docstring"""
class D:
"""A class having no __init__, __new__(no docstring)"""
def __new__(cls):
pass
class E:
"""A class having no __init__, __new__"""
def __new__(cls):
"""__new__ docstring"""
class F:
"""A class having both __init__ and __new__"""
def __init__(self):
"""__init__ docstring"""
def __new__(cls):
"""__new__ docstring"""

View File

@ -0,0 +1,19 @@
class A:
"""A(foo, bar)"""
class B:
"""B(foo, bar)"""
def __init__(self):
"""B(foo, bar, baz)"""
class C:
"""C(foo, bar)"""
def __new__(cls):
"""C(foo, bar, baz)"""
class D:
def __init__(self):
"""D(foo, bar, baz)"""

View File

@ -0,0 +1,19 @@
class Base(object):
def inheritedmeth(self):
"""Inherited function."""
@classmethod
def inheritedclassmeth(cls):
"""Inherited class method."""
@staticmethod
def inheritedstaticmeth(cls):
"""Inherited static method."""
class Derived(Base):
def inheritedmeth(self):
# no docstring here
pass

View File

@ -325,127 +325,6 @@ def test_get_doc():
"""Döcstring""" """Döcstring"""
assert getdocl('function', f) == ['Döcstring'] assert getdocl('function', f) == ['Döcstring']
# class docstring: depends on config value which one is taken
class C:
"""Class docstring"""
def __init__(self):
"""Init docstring"""
def __new__(cls):
"""New docstring"""
directive.env.config.autoclass_content = 'class'
assert getdocl('class', C) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', C) == ['Init docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', C) == ['Class docstring', '', 'Init docstring']
class D:
"""Class docstring"""
def __init__(self):
"""Init docstring
Other
lines
"""
# Indentation is normalized for 'both'
assert getdocl('class', D) == ['Class docstring', '', 'Init docstring',
'', 'Other', ' lines']
# __init__ have signature at first line of docstring
class E:
"""Class docstring"""
def __init__(self, *args, **kw):
"""
__init__(a1, a2, kw1=True, kw2=False)
Init docstring
"""
# signature line in the docstring will be kept when
# autodoc_docstring_signature == False
directive.env.config.autodoc_docstring_signature = False
directive.env.config.autoclass_content = 'class'
assert getdocl('class', E) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', E) == ['__init__(a1, a2, kw1=True, kw2=False)',
'', 'Init docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', E) == ['Class docstring', '',
'__init__(a1, a2, kw1=True, kw2=False)',
'', 'Init docstring']
# signature line in the docstring will be removed when
# autodoc_docstring_signature == True
directive.env.config.autodoc_docstring_signature = True # default
directive.env.config.autoclass_content = 'class'
assert getdocl('class', E) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', E) == ['Init docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', E) == ['Class docstring', '', 'Init docstring']
# class does not have __init__ method
class F:
"""Class docstring"""
# docstring in the __init__ method of base class will be discard
for f in (False, True):
directive.env.config.autodoc_docstring_signature = f
directive.env.config.autoclass_content = 'class'
assert getdocl('class', F) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', F) == ['Class docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', F) == ['Class docstring']
# class has __init__ method with no docstring
class G:
"""Class docstring"""
def __init__(self):
pass
# docstring in the __init__ method of base class will not be used
for f in (False, True):
directive.env.config.autodoc_docstring_signature = f
directive.env.config.autoclass_content = 'class'
assert getdocl('class', G) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', G) == ['Class docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', G) == ['Class docstring']
# class has __new__ method with docstring
# class docstring: depends on config value which one is taken
class H:
"""Class docstring"""
def __init__(self):
pass
def __new__(cls):
"""New docstring"""
directive.env.config.autoclass_content = 'class'
assert getdocl('class', H) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', H) == ['New docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', H) == ['Class docstring', '', 'New docstring']
# class has __init__ method without docstring and
# __new__ method with docstring
# class docstring: depends on config value which one is taken
class I: # NOQA
"""Class docstring"""
def __new__(cls):
"""New docstring"""
directive.env.config.autoclass_content = 'class'
assert getdocl('class', I) == ['Class docstring']
directive.env.config.autoclass_content = 'init'
assert getdocl('class', I) == ['New docstring']
directive.env.config.autoclass_content = 'both'
assert getdocl('class', I) == ['Class docstring', '', 'New docstring']
# verify that method docstrings get extracted in both normal case # verify that method docstrings get extracted in both normal case
# and in case of bound method posing as a function # and in case of bound method posing as a function
class J: # NOQA class J: # NOQA
@ -454,15 +333,6 @@ def test_get_doc():
assert getdocl('method', J.foo) == ['Method docstring'] assert getdocl('method', J.foo) == ['Method docstring']
assert getdocl('function', J().foo) == ['Method docstring'] assert getdocl('function', J().foo) == ['Method docstring']
from target import Base, Derived
# NOTE: inspect.getdoc seems not to work with locally defined classes
directive.env.config.autodoc_inherit_docstrings = False
assert getdocl('method', Base.inheritedmeth) == ['Inherited function.']
assert getdocl('method', Derived.inheritedmeth) == []
directive.env.config.autodoc_inherit_docstrings = True
assert getdocl('method', Derived.inheritedmeth) == ['Inherited function.']
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_new_documenter(app): def test_new_documenter(app):
@ -498,6 +368,7 @@ def test_new_documenter(app):
@pytest.mark.usefixtures('setup_test') @pytest.mark.usefixtures('setup_test')
def test_attrgetter_using(): def test_attrgetter_using():
from target import Class from target import Class
from target.inheritance import Derived
def assert_getter_works(objtype, name, obj, attrs=[], **kw): def assert_getter_works(objtype, name, obj, attrs=[], **kw):
getattr_spy = [] getattr_spy = []
@ -527,7 +398,7 @@ def test_attrgetter_using():
assert_getter_works('class', 'target.Class', Class, ['meth']) assert_getter_works('class', 'target.Class', Class, ['meth'])
options.inherited_members = True options.inherited_members = True
assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth']) assert_getter_works('class', 'target.inheritance.Derived', Derived, ['inheritedmeth'])
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
@ -630,14 +501,14 @@ def test_autodoc_attributes(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_members(app): def test_autodoc_members(app):
# default (no-members) # default (no-members)
actual = do_autodoc(app, 'class', 'target.Base') actual = do_autodoc(app, 'class', 'target.inheritance.Base')
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Base', '.. py:class:: Base',
] ]
# default ALL-members # default ALL-members
options = {"members": None} options = {"members": None}
actual = do_autodoc(app, 'class', 'target.Base', options) actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Base', '.. py:class:: Base',
' .. py:method:: Base.inheritedclassmeth()', ' .. py:method:: Base.inheritedclassmeth()',
@ -647,7 +518,7 @@ def test_autodoc_members(app):
# default specific-members # default specific-members
options = {"members": "inheritedmeth,inheritedstaticmeth"} options = {"members": "inheritedmeth,inheritedstaticmeth"}
actual = do_autodoc(app, 'class', 'target.Base', options) actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Base', '.. py:class:: Base',
' .. py:method:: Base.inheritedmeth()', ' .. py:method:: Base.inheritedmeth()',
@ -659,7 +530,7 @@ def test_autodoc_members(app):
def test_autodoc_exclude_members(app): def test_autodoc_exclude_members(app):
options = {"members": None, options = {"members": None,
"exclude-members": "inheritedmeth,inheritedstaticmeth"} "exclude-members": "inheritedmeth,inheritedstaticmeth"}
actual = do_autodoc(app, 'class', 'target.Base', options) actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Base', '.. py:class:: Base',
' .. py:method:: Base.inheritedclassmeth()' ' .. py:method:: Base.inheritedclassmeth()'
@ -668,7 +539,7 @@ def test_autodoc_exclude_members(app):
# members vs exclude-members # members vs exclude-members
options = {"members": "inheritedmeth", options = {"members": "inheritedmeth",
"exclude-members": "inheritedmeth"} "exclude-members": "inheritedmeth"}
actual = do_autodoc(app, 'class', 'target.Base', options) actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Base', '.. py:class:: Base',
] ]
@ -702,15 +573,11 @@ def test_autodoc_undoc_members(app):
def test_autodoc_inherited_members(app): def test_autodoc_inherited_members(app):
options = {"members": None, options = {"members": None,
"inherited-members": None} "inherited-members": None}
actual = do_autodoc(app, 'class', 'target.Class', options) actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
assert list(filter(lambda l: 'method::' in l, actual)) == [ assert list(filter(lambda l: 'method::' in l, actual)) == [
' .. py:method:: Class.excludemeth()', ' .. py:method:: Derived.inheritedclassmeth()',
' .. py:method:: Class.inheritedclassmeth()', ' .. py:method:: Derived.inheritedmeth()',
' .. py:method:: Class.inheritedmeth()', ' .. py:method:: Derived.inheritedstaticmeth(cls)',
' .. py:method:: Class.inheritedstaticmeth(cls)',
' .. py:method:: Class.meth()',
' .. py:method:: Class.moore(a, e, f) -> happiness',
' .. py:method:: Class.skipmeth()'
] ]
@ -755,10 +622,12 @@ def test_autodoc_special_members(app):
actual = do_autodoc(app, 'class', 'target.Class', options) actual = do_autodoc(app, 'class', 'target.Class', options)
assert list(filter(lambda l: '::' in l, actual)) == [ assert list(filter(lambda l: '::' in l, actual)) == [
'.. py:class:: Class(arg)', '.. py:class:: Class(arg)',
' .. py:attribute:: Class.__dict__',
' .. py:method:: Class.__init__(arg)', ' .. py:method:: Class.__init__(arg)',
' .. py:attribute:: Class.__module__', ' .. py:attribute:: Class.__module__',
' .. py:method:: Class.__special1__()', ' .. py:method:: Class.__special1__()',
' .. py:method:: Class.__special2__()', ' .. py:method:: Class.__special2__()',
' .. py:attribute:: Class.__weakref__',
' .. py:attribute:: Class.attr', ' .. py:attribute:: Class.attr',
' .. py:attribute:: Class.docattr', ' .. py:attribute:: Class.docattr',
' .. py:method:: Class.excludemeth()', ' .. py:method:: Class.excludemeth()',
@ -812,12 +681,12 @@ def test_autodoc_noindex(app):
# TODO: :noindex: should be propagated to children of target item. # TODO: :noindex: should be propagated to children of target item.
actual = do_autodoc(app, 'class', 'target.Base', options) actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:class:: Base', '.. py:class:: Base',
' :noindex:', ' :noindex:',
' :module: target', ' :module: target.inheritance',
'' ''
] ]
@ -885,11 +754,11 @@ def test_autodoc_inner_class(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_classmethod(app): def test_autodoc_classmethod(app):
actual = do_autodoc(app, 'method', 'target.Base.inheritedclassmeth') actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedclassmeth')
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:method:: Base.inheritedclassmeth()', '.. py:method:: Base.inheritedclassmeth()',
' :module: target', ' :module: target.inheritance',
' :classmethod:', ' :classmethod:',
'', '',
' Inherited class method.', ' Inherited class method.',
@ -899,11 +768,11 @@ def test_autodoc_classmethod(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_staticmethod(app): def test_autodoc_staticmethod(app):
actual = do_autodoc(app, 'method', 'target.Base.inheritedstaticmeth') actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedstaticmeth')
assert list(actual) == [ assert list(actual) == [
'', '',
'.. py:method:: Base.inheritedstaticmeth(cls)', '.. py:method:: Base.inheritedstaticmeth(cls)',
' :module: target', ' :module: target.inheritance',
' :staticmethod:', ' :staticmethod:',
'', '',
' Inherited static method.', ' Inherited static method.',

View File

@ -18,6 +18,180 @@ from test_autodoc import do_autodoc
IS_PYPY = platform.python_implementation() == 'PyPy' IS_PYPY = platform.python_implementation() == 'PyPy'
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_class(app):
app.config.autoclass_content = 'class'
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.autoclass_content', options)
assert list(actual) == [
'',
'.. py:module:: target.autoclass_content',
'',
'',
'.. py:class:: A',
' :module: target.autoclass_content',
'',
' A class having no __init__, no __new__',
' ',
'',
'.. py:class:: B()',
' :module: target.autoclass_content',
'',
' A class having __init__(no docstring), no __new__',
' ',
'',
'.. py:class:: C()',
' :module: target.autoclass_content',
'',
' A class having __init__, no __new__',
' ',
'',
'.. py:class:: D',
' :module: target.autoclass_content',
'',
' A class having no __init__, __new__(no docstring)',
' ',
'',
'.. py:class:: E',
' :module: target.autoclass_content',
'',
' A class having no __init__, __new__',
' ',
'',
'.. py:class:: F()',
' :module: target.autoclass_content',
'',
' A class having both __init__ and __new__',
' '
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_init(app):
app.config.autoclass_content = 'init'
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.autoclass_content', options)
assert list(actual) == [
'',
'.. py:module:: target.autoclass_content',
'',
'',
'.. py:class:: A',
' :module: target.autoclass_content',
'',
' A class having no __init__, no __new__',
' ',
'',
'.. py:class:: B()',
' :module: target.autoclass_content',
'',
' A class having __init__(no docstring), no __new__',
' ',
'',
'.. py:class:: C()',
' :module: target.autoclass_content',
'',
' __init__ docstring',
' ',
'',
'.. py:class:: D',
' :module: target.autoclass_content',
'',
' A class having no __init__, __new__(no docstring)',
' ',
'',
'.. py:class:: E',
' :module: target.autoclass_content',
'',
' __new__ docstring',
' ',
'',
'.. py:class:: F()',
' :module: target.autoclass_content',
'',
' __init__ docstring',
' '
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_both(app):
app.config.autoclass_content = 'both'
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.autoclass_content', options)
assert list(actual) == [
'',
'.. py:module:: target.autoclass_content',
'',
'',
'.. py:class:: A',
' :module: target.autoclass_content',
'',
' A class having no __init__, no __new__',
' ',
'',
'.. py:class:: B()',
' :module: target.autoclass_content',
'',
' A class having __init__(no docstring), no __new__',
' ',
'',
'.. py:class:: C()',
' :module: target.autoclass_content',
'',
' A class having __init__, no __new__',
' ',
' __init__ docstring',
' ',
'',
'.. py:class:: D',
' :module: target.autoclass_content',
'',
' A class having no __init__, __new__(no docstring)',
' ',
'',
'.. py:class:: E',
' :module: target.autoclass_content',
'',
' A class having no __init__, __new__',
' ',
' __new__ docstring',
' ',
'',
'.. py:class:: F()',
' :module: target.autoclass_content',
'',
' A class having both __init__ and __new__',
' ',
' __init__ docstring',
' '
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_inherit_docstrings(app):
assert app.config.autodoc_inherit_docstrings is True # default
actual = do_autodoc(app, 'method', 'target.inheritance.Derived.inheritedmeth')
assert list(actual) == [
'',
'.. py:method:: Derived.inheritedmeth()',
' :module: target.inheritance',
'',
' Inherited function.',
' '
]
# disable autodoc_inherit_docstrings
app.config.autodoc_inherit_docstrings = False
actual = do_autodoc(app, 'method', 'target.inheritance.Derived.inheritedmeth')
assert list(actual) == [
'',
'.. py:method:: Derived.inheritedmeth()',
' :module: target.inheritance',
''
]
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_docstring_signature(app): def test_autodoc_docstring_signature(app):
options = {"members": None} options = {"members": None}
@ -107,6 +281,97 @@ def test_autodoc_docstring_signature(app):
] ]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_and_docstring_signature_class(app):
app.config.autoclass_content = 'class'
options = {"members": None,
"undoc-members": None}
actual = do_autodoc(app, 'module', 'target.docstring_signature', options)
assert list(actual) == [
'',
'.. py:module:: target.docstring_signature',
'',
'',
'.. py:class:: A(foo, bar)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: B(foo, bar)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: C(foo, bar)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: D()',
' :module: target.docstring_signature',
''
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_and_docstring_signature_init(app):
app.config.autoclass_content = 'init'
options = {"members": None,
"undoc-members": None}
actual = do_autodoc(app, 'module', 'target.docstring_signature', options)
assert list(actual) == [
'',
'.. py:module:: target.docstring_signature',
'',
'',
'.. py:class:: A(foo, bar)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: B(foo, bar, baz)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: C(foo, bar, baz)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: D(foo, bar, baz)',
' :module: target.docstring_signature',
''
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autoclass_content_and_docstring_signature_both(app):
app.config.autoclass_content = 'both'
options = {"members": None,
"undoc-members": None}
actual = do_autodoc(app, 'module', 'target.docstring_signature', options)
assert list(actual) == [
'',
'.. py:module:: target.docstring_signature',
'',
'',
'.. py:class:: A(foo, bar)',
' :module: target.docstring_signature',
'',
'',
'.. py:class:: B(foo, bar)',
' :module: target.docstring_signature',
'',
' B(foo, bar, baz)',
' ',
'',
'.. py:class:: C(foo, bar)',
' :module: target.docstring_signature',
'',
' C(foo, bar, baz)',
' ',
'',
'.. py:class:: D(foo, bar, baz)',
' :module: target.docstring_signature',
'',
]
@pytest.mark.sphinx('html', testroot='ext-autodoc') @pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_mocked_module_imports(app, warning): def test_mocked_module_imports(app, warning):
# no autodoc_mock_imports # no autodoc_mock_imports