summaryrefslogtreecommitdiff
path: root/tests/test_autodoc.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_autodoc.py')
-rw-r--r--tests/test_autodoc.py176
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',
+ ''
+ ]