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.py251
1 files changed, 140 insertions, 111 deletions
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 1be35eb5b..a25a13639 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
test_autodoc
~~~~~~~~~~~~
@@ -17,10 +16,9 @@ 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,
+ ModuleLevelDocumenter, cut_lines, between, ALL,
merge_autodoc_default_flags, Options
)
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
@@ -30,17 +28,13 @@ 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'
def do_autodoc(app, objtype, name, options=None):
if options is None:
options = {}
+ app.env.temp_data.setdefault('docname', 'index') # set dummy docname
doccls = app.registry.documenters[objtype]
docoptions = process_documenter_options(doccls, app.config, options)
bridge = DocumenterBridge(app.env, LoggingReporter(''), docoptions, 1)
@@ -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) == \
@@ -291,13 +285,13 @@ def test_format_signature():
@pytest.mark.usefixtures('setup_test')
def test_get_doc():
- def getdocl(objtype, obj, encoding=None):
+ def getdocl(objtype, obj):
inst = app.registry.documenters[objtype](directive, 'tmp')
inst.object = obj
inst.objpath = [obj.__name__]
inst.doc_as_attr = False
inst.format_signature() # handle docstring signatures!
- ds = inst.get_doc(encoding)
+ ds = inst.get_doc()
# for testing purposes, concat them and strip the empty line at the end
res = sum(ds, [])[:-1]
print(res)
@@ -330,12 +324,12 @@ def test_get_doc():
# charset guessing (this module is encoded in utf-8)
def f():
"""Döcstring"""
- assert getdocl('function', f) == [u'Döcstring']
+ assert getdocl('function', f) == ['Döcstring']
# already-unicode docstrings must be taken literally
def f():
- u"""Döcstring"""
- assert getdocl('function', f) == [u'Döcstring']
+ """Döcstring"""
+ assert getdocl('function', f) == ['Döcstring']
# class docstring: depends on config value which one is taken
class C:
@@ -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,7 +746,7 @@ 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')
@@ -802,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',
@@ -875,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) == [
@@ -905,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)
@@ -974,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',
@@ -993,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',
@@ -1028,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',
@@ -1038,38 +1027,32 @@ def test_autodoc_member_order(app):
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_module_scope(app):
- def convert(s):
- return re.sub('<.*>', '<FILTERED>', s) # for py2/py3
-
app.env.temp_data['autodoc:module'] = 'target'
actual = do_autodoc(app, 'attribute', 'Class.mdocattr')
- assert list(map(convert, actual)) == [
- u'',
- u'.. py:attribute:: Class.mdocattr',
- u' :module: target',
- u' :annotation: = <FILTERED>',
- u'',
- u' should be documented as well - süß',
- u' '
+ assert list(actual) == [
+ '',
+ '.. py:attribute:: Class.mdocattr',
+ ' :module: target',
+ ' :annotation: = <_io.StringIO object>',
+ '',
+ ' should be documented as well - süß',
+ ' '
]
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_class_scope(app):
- def convert(s):
- return re.sub('<.*>', '<FILTERED>', s) # for py2/py3
-
app.env.temp_data['autodoc:module'] = 'target'
app.env.temp_data['autodoc:class'] = 'Class'
actual = do_autodoc(app, 'attribute', 'mdocattr')
- assert list(map(convert, actual)) == [
- u'',
- u'.. py:attribute:: Class.mdocattr',
- u' :module: target',
- u' :annotation: = <FILTERED>',
- u'',
- u' should be documented as well - süß',
- u' '
+ assert list(actual) == [
+ '',
+ '.. py:attribute:: Class.mdocattr',
+ ' :module: target',
+ ' :annotation: = <_io.StringIO object>',
+ '',
+ ' should be documented as well - süß',
+ ' '
]
@@ -1118,43 +1101,43 @@ def test_autodoc_docstring_signature(app):
app.config.autodoc_docstring_signature = False
actual = do_autodoc(app, 'class', 'target.DocstringSig', options)
assert list(actual) == [
- u'',
- u'.. py:class:: DocstringSig',
- u' :module: target',
- u'',
- u' ',
- u' .. py:method:: DocstringSig.meth()',
- u' :module: target',
- u' ',
- u' meth(FOO, BAR=1) -> BAZ',
- u' First line of docstring',
- u' ',
- u' rest of docstring',
- u' ',
- u' ',
- u' ',
- u' .. py:method:: DocstringSig.meth2()',
- u' :module: target',
- u' ',
- u' First line, no signature',
- u' Second line followed by indentation::',
- u' ',
- u' indented line',
- u' ',
- u' ',
- u' .. py:attribute:: DocstringSig.prop1',
- u' :module: target',
- u' ',
- u' DocstringSig.prop1(self)',
- u' First line of docstring',
- u' ',
- u' ',
- u' .. py:attribute:: DocstringSig.prop2',
- u' :module: target',
- u' ',
- u' First line of docstring',
- u' Second line of docstring',
- u' '
+ '',
+ '.. py:class:: DocstringSig',
+ ' :module: target',
+ '',
+ ' ',
+ ' .. py:method:: DocstringSig.meth()',
+ ' :module: target',
+ ' ',
+ ' meth(FOO, BAR=1) -> BAZ',
+ ' First line of docstring',
+ ' ',
+ ' rest of docstring',
+ ' ',
+ ' ',
+ ' ',
+ ' .. py:method:: DocstringSig.meth2()',
+ ' :module: target',
+ ' ',
+ ' First line, no signature',
+ ' Second line followed by indentation::',
+ ' ',
+ ' indented line',
+ ' ',
+ ' ',
+ ' .. py:attribute:: DocstringSig.prop1',
+ ' :module: target',
+ ' ',
+ ' DocstringSig.prop1(self)',
+ ' First line of docstring',
+ ' ',
+ ' ',
+ ' .. py:attribute:: DocstringSig.prop2',
+ ' :module: target',
+ ' ',
+ ' First line of docstring',
+ ' Second line of docstring',
+ ' '
]
@@ -1359,47 +1342,56 @@ def test_autofunction_for_callable(app):
]
-@pytest.mark.sphinx('html', testroot='root')
-def test_mocked_module_imports(app):
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_mocked_module_imports(app, warning):
+ # no autodoc_mock_imports
options = {"members": 'TestAutodoc,decoratedFunction'}
- actual = do_autodoc(app, 'module', 'autodoc_missing_imports', options)
+ actual = do_autodoc(app, 'module', 'target.need_mocks', options)
+ assert list(actual) == []
+ assert "autodoc: failed to import module 'need_mocks'" in warning.getvalue()
+
+ # with autodoc_mock_imports
+ app.config.autodoc_mock_imports = [
+ 'missing_module',
+ 'missing_package1',
+ 'missing_package2',
+ 'missing_package3',
+ 'sphinx.missing_module4',
+ ]
+
+ warning.truncate(0)
+ actual = do_autodoc(app, 'module', 'target.need_mocks', options)
assert list(actual) == [
'',
- '.. py:module:: autodoc_missing_imports',
+ '.. py:module:: target.need_mocks',
'',
'',
'.. py:class:: TestAutodoc',
- ' :module: autodoc_missing_imports',
+ ' :module: target.need_mocks',
'',
' TestAutodoc docstring.',
' ',
' ',
' .. py:method:: TestAutodoc.decoratedMethod()',
- ' :module: autodoc_missing_imports',
+ ' :module: target.need_mocks',
' ',
' TestAutodoc::decoratedMethod docstring',
' ',
'',
'.. py:function:: decoratedFunction()',
- ' :module: autodoc_missing_imports',
+ ' :module: target.need_mocks',
'',
' decoratedFunction docstring',
' '
]
+ assert warning.getvalue() == ''
@pytest.mark.usefixtures('setup_test')
def test_partialfunction():
- def call_autodoc(objtype, name):
- inst = app.registry.documenters[objtype](directive, name)
- inst.generate()
- result = list(directive.result)
- del directive.result[:]
- return result
-
- options.members = ALL
- #options.undoc_members = True
- expected = [
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.partialfunction', options)
+ assert list(actual) == [
'',
'.. py:module:: target.partialfunction',
'',
@@ -1423,11 +1415,25 @@ def test_partialfunction():
' '
]
- assert call_autodoc('module', 'target.partialfunction') == expected
+
+@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.skipif(sys.version_info < (3, 4),
- reason='functools.partialmethod is available on py34 or above')
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_partialmethod(app):
expected = [
@@ -1566,6 +1572,29 @@ def test_autodoc_default_options_with_values(app):
assert ' .. py:attribute:: EnumCls.val3' not in actual
assert ' .. py:attribute:: EnumCls.val4' not in actual
+ # with :member-order:
+ app.config.autodoc_default_options = {
+ 'members': None,
+ 'member-order': 'bysource',
+ }
+ actual = do_autodoc(app, 'class', 'target.Class')
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Class(arg)',
+ ' .. py:attribute:: Class.descr',
+ ' .. py:method:: Class.meth()',
+ ' .. py:method:: Class.skipmeth()',
+ ' .. py:method:: Class.excludemeth()',
+ ' .. py:attribute:: Class.attr',
+ ' .. py:attribute:: Class.prop',
+ ' .. py:attribute:: Class.docattr',
+ ' .. py:attribute:: Class.udocattr',
+ ' .. py:attribute:: Class.mdocattr',
+ ' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
+ ' .. py:attribute:: Class.inst_attr_inline',
+ ' .. py:attribute:: Class.inst_attr_comment',
+ ' .. py:attribute:: Class.inst_attr_string',
+ ]
+
# with :special-members:
app.config.autodoc_default_options = {
'special-members': '__init__,__iter__',