diff options
Diffstat (limited to 'tests/test_autodoc.py')
-rw-r--r-- | tests/test_autodoc.py | 176 |
1 files changed, 108 insertions, 68 deletions
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index c9a342f94..f469a6be3 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -17,11 +17,10 @@ from warnings import catch_warnings import pytest from docutils.statemachine import ViewList -from six import PY3 from sphinx.ext.autodoc import ( - AutoDirective, ModuleLevelDocumenter, cut_lines, between, ALL, - merge_autodoc_default_flags + ModuleLevelDocumenter, cut_lines, between, ALL, + merge_autodoc_default_flags, Options ) from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options from sphinx.testing.util import SphinxTestApp, Struct # NOQA @@ -30,11 +29,6 @@ from sphinx.util.docutils import LoggingReporter app = None -if PY3: - ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)' -else: - ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, e=5, f=6)' - IS_PYPY = platform.python_implementation() == 'PyPy' @@ -79,7 +73,7 @@ def setup_test(): global options, directive global processed_docstrings, processed_signatures - options = Struct( + options = Options( inherited_members = False, undoc_members = False, private_members = False, @@ -112,7 +106,7 @@ def setup_test(): yield - AutoDirective._special_attrgetters.clear() + app.registry.autodoc_attrgettrs.clear() processed_docstrings = [] @@ -216,7 +210,7 @@ def test_format_signature(): class D: pass - class E(object): + class E: pass # no signature for classes without __init__ for C in (D, E): @@ -226,7 +220,7 @@ def test_format_signature(): def __init__(self, a, b=None): pass - class G(F, object): + class G(F): pass for C in (F, G): assert formatsig('class', 'C', C, None, None) == '(a, b=None)' @@ -243,7 +237,7 @@ def test_format_signature(): some docstring for __init__. ''' - class G2(F2, object): + class G2(F2): pass assert formatsig('class', 'F2', F2, None, None) == \ @@ -399,7 +393,7 @@ def test_get_doc(): assert getdocl('class', E) == ['Class docstring', '', 'Init docstring'] # class does not have __init__ method - class F(object): + class F: """Class docstring""" # docstring in the __init__ method of base class will be discard @@ -413,7 +407,7 @@ def test_get_doc(): assert getdocl('class', F) == ['Class docstring'] # class has __init__ method with no docstring - class G(object): + class G: """Class docstring""" def __init__(self): pass @@ -566,7 +560,7 @@ def test_attrgetter_using(): getattr_spy.append((obj, name)) return None return getattr(obj, name, *defargs) - AutoDirective._special_attrgetters[type] = special_getattr + app.add_autodoc_attrgetter(type, special_getattr) del getattr_spy[:] inst = app.registry.documenters[objtype](directive, name) @@ -722,7 +716,7 @@ def test_autodoc_undoc_members(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -752,49 +746,45 @@ def test_autodoc_imported_members(app): "imported-members": None, "ignore-module-all": None} actual = do_autodoc(app, 'module', 'target', options) - assert '.. py:function:: add_documenter(cls)' in actual + assert '.. py:function:: save_traceback(app)' in actual @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_special_members(app): - # all special methods - options = {"members": None, + # specific special methods + options = {"undoc-members": None, + "special-members": "__init__,__special1__"} + actual = do_autodoc(app, 'class', 'target.Class', options) + assert list(filter(lambda l: '::' in l, actual)) == [ + '.. py:class:: Class(arg)', + ' .. py:method:: Class.__init__(arg)', + ' .. py:method:: Class.__special1__()', + ] + + # combination with specific members + options = {"members": "attr,docattr", "undoc-members": None, - "special-members": None} + "special-members": "__init__,__special1__"} actual = do_autodoc(app, 'class', 'target.Class', options) assert list(filter(lambda l: '::' in l, actual)) == [ '.. py:class:: Class(arg)', ' .. py:method:: Class.__init__(arg)', - ' .. py:attribute:: Class.__module__', ' .. py:method:: Class.__special1__()', - ' .. py:method:: Class.__special2__()', ' .. py:attribute:: Class.attr', - ' .. py:attribute:: Class.descr', ' .. py:attribute:: Class.docattr', - ' .. py:method:: Class.excludemeth()', - ' .. py:attribute:: Class.inst_attr_comment', - ' .. py:attribute:: Class.inst_attr_inline', - ' .. py:attribute:: Class.inst_attr_string', - ' .. py:attribute:: Class.mdocattr', - ' .. py:method:: Class.meth()', - ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', - ' .. py:attribute:: Class.prop', - ROGER_METHOD, - ' .. py:attribute:: Class.skipattr', - ' .. py:method:: Class.skipmeth()', - ' .. py:attribute:: Class.udocattr', - ' .. py:method:: Class.undocmeth()' ] - # specific special methods + # all special methods options = {"members": None, "undoc-members": None, - "special-members": "__init__,__special1__"} + "special-members": None} actual = do_autodoc(app, 'class', 'target.Class', options) assert list(filter(lambda l: '::' in l, actual)) == [ '.. py:class:: Class(arg)', ' .. py:method:: Class.__init__(arg)', + ' .. py:attribute:: Class.__module__', ' .. py:method:: Class.__special1__()', + ' .. py:method:: Class.__special2__()', ' .. py:attribute:: Class.attr', ' .. py:attribute:: Class.descr', ' .. py:attribute:: Class.docattr', @@ -806,7 +796,7 @@ def test_autodoc_special_members(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -833,7 +823,6 @@ def test_autodoc_ignore_module_all(app): '.. py:class:: CustomDataDescriptor2(doc)', '.. py:class:: CustomDataDescriptorMeta', '.. py:class:: CustomDict', - '.. py:class:: EnumCls', '.. py:class:: InstAttCls()', '.. py:class:: Outer', ' .. py:class:: Outer.Inner', @@ -880,11 +869,6 @@ def test_autodoc_subclass_of_builtin_class(app): @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_inner_class(app): - if PY3: - builtins = ' alias of :class:`builtins.dict`' - else: - builtins = ' alias of :class:`__builtin__.dict`' - options = {"members": None} actual = do_autodoc(app, 'class', 'target.Outer', options) assert list(actual) == [ @@ -910,7 +894,7 @@ def test_autodoc_inner_class(app): ' .. py:attribute:: Outer.factory', ' :module: target', ' ', - builtins + ' alias of :class:`builtins.dict`' ] actual = do_autodoc(app, 'class', 'target.Outer.Inner', options) @@ -979,7 +963,7 @@ def test_autodoc_member_order(app): ' .. py:attribute:: Class.docattr', ' .. py:attribute:: Class.udocattr', ' .. py:attribute:: Class.mdocattr', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.inst_attr_inline', ' .. py:attribute:: Class.inst_attr_comment', @@ -998,7 +982,7 @@ def test_autodoc_member_order(app): ' .. py:method:: Class.excludemeth()', ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:method:: Class.skipmeth()', ' .. py:method:: Class.undocmeth()', ' .. py:attribute:: Class._private_inst_attr', @@ -1033,7 +1017,7 @@ def test_autodoc_member_order(app): ' .. py:method:: Class.meth()', ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.prop', - ROGER_METHOD, + ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)', ' .. py:attribute:: Class.skipattr', ' .. py:method:: Class.skipmeth()', ' .. py:attribute:: Class.udocattr', @@ -1267,48 +1251,54 @@ def test_instance_attributes(app): def test_enum_class(app): options = {"members": None, "undoc-members": True} - actual = do_autodoc(app, 'class', 'target.EnumCls', options) + actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options) assert list(actual) == [ '', '.. py:class:: EnumCls', - ' :module: target', + ' :module: target.enum', '', ' this is enum class', ' ', ' ', + ' .. py:method:: EnumCls.say_hello()', + ' :module: target.enum', + ' ', + ' a method says hello to you.', + ' ', + ' ', ' .. py:attribute:: EnumCls.val1', - ' :module: target', + ' :module: target.enum', ' :annotation: = 12', ' ', ' doc for val1', ' ', ' ', ' .. py:attribute:: EnumCls.val2', - ' :module: target', + ' :module: target.enum', ' :annotation: = 23', ' ', ' doc for val2', ' ', ' ', ' .. py:attribute:: EnumCls.val3', - ' :module: target', + ' :module: target.enum', ' :annotation: = 34', ' ', ' doc for val3', ' ', ' ', ' .. py:attribute:: EnumCls.val4', - ' :module: target', + ' :module: target.enum', ' :annotation: = 34', ' ' ] # 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) == [ '', '.. py:attribute:: EnumCls.val1', - ' :module: target', + ' :module: target.enum', ' :annotation: = 12', '', ' doc for val1', @@ -1345,6 +1335,19 @@ def test_descriptor_class(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autofunction_for_callable(app): + actual = do_autodoc(app, 'function', 'target.callable.function') + assert list(actual) == [ + '', + '.. py:function:: function(arg1, arg2, **kwargs)', + ' :module: target.callable', + '', + ' A callable object that behaves like a function.', + ' ' + ] + + @pytest.mark.sphinx('html', testroot='root') def test_mocked_module_imports(app): options = {"members": 'TestAutodoc,decoratedFunction'} @@ -1412,8 +1415,24 @@ def test_partialfunction(): assert call_autodoc('module', 'target.partialfunction') == expected -@pytest.mark.skipif(sys.version_info < (3, 4), - reason='functools.partialmethod is available on py34 or above') +@pytest.mark.usefixtures('setup_test') +def test_coroutine(): + options = {"members": None} + actual = do_autodoc(app, 'class', 'target.coroutine.AsyncClass', options) + assert list(actual) == [ + '', + '.. py:class:: AsyncClass', + ' :module: target.coroutine', + '', + ' ', + ' .. py:method:: AsyncClass.do_coroutine()', + ' :module: target.coroutine', + ' ', + ' A documented coroutine function', + ' ' + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_partialmethod(app): expected = [ @@ -1477,7 +1496,7 @@ def test_merge_autodoc_default_flags2(app): @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_default_options(app): # 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.val4' not in actual actual = do_autodoc(app, 'class', 'target.CustomIter') @@ -1485,7 +1504,7 @@ def test_autodoc_default_options(app): # with :members: 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.val4' not in actual @@ -1494,7 +1513,7 @@ def test_autodoc_default_options(app): '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.val4' in actual @@ -1520,7 +1539,7 @@ def test_autodoc_default_options(app): '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.val4' not in actual app.config.autodoc_default_options = { @@ -1544,16 +1563,14 @@ def test_autodoc_default_options(app): def test_autodoc_default_options_with_values(app): # with :members: 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.val2' in actual assert ' .. py:attribute:: EnumCls.val3' not in actual assert ' .. py:attribute:: EnumCls.val4' not in actual # with :special-members: - # Note that :members: must be *on* for :special-members: to work. app.config.autodoc_default_options = { - 'members': None, 'special-members': '__init__,__iter__', } actual = do_autodoc(app, 'class', 'target.CustomIter') @@ -1570,7 +1587,7 @@ def test_autodoc_default_options_with_values(app): 'members': None, '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.val2' in actual assert ' .. py:attribute:: EnumCls.val3' in actual @@ -1590,3 +1607,26 @@ def test_autodoc_default_options_with_values(app): assert ' list of weak references to the object (if defined)' not in actual assert ' .. py:method:: CustomIter.snafucate()' not in actual assert ' Makes this snafucated.' not in actual + + +@pytest.mark.sphinx('html', testroot='pycode-egg') +def test_autodoc_for_egged_code(app): + options = {"members": None, + "undoc-members": None} + actual = do_autodoc(app, 'module', 'sample', options) + assert list(actual) == [ + '', + '.. py:module:: sample', + '', + '', + '.. py:data:: CONSTANT', + ' :module: sample', + ' :annotation: = 1', + '', + ' constant on sample.py', + ' ', + '', + '.. py:function:: hello(s)', + ' :module: sample', + '' + ] |