summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--sphinx/ext/autodoc/__init__.py33
-rw-r--r--sphinx/ext/autodoc/directive.py14
-rw-r--r--tests/py35/test_autodoc_py35.py25
-rw-r--r--tests/test_autodoc.py38
5 files changed, 54 insertions, 58 deletions
diff --git a/CHANGES b/CHANGES
index b555e30ca..3de25c0ee 100644
--- a/CHANGES
+++ b/CHANGES
@@ -14,6 +14,8 @@ Incompatible changes
* #4226: apidoc: Generate new style makefile (make-mode)
* #4274: sphinx-build returns 2 as an exit code on argument error
* #4389: output directory will be created after loading extensions
+* autodoc does not generate warnings messages to the generated document even if
+ :confval:`keep_warnings` is True. They are only emitted to stderr.
Deprecated
----------
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 386245d20..d9e82813d 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -328,8 +328,7 @@ class Documenter(object):
explicit_modname, path, base, args, retann = \
py_ext_sig_re.match(self.name).groups() # type: ignore
except AttributeError:
- self.directive.warn('invalid signature for auto%s (%r)' %
- (self.objtype, self.name))
+ logger.warning('invalid signature for auto%s (%r)' % (self.objtype, self.name))
return False
# support explicit module and class name separation via ::
@@ -366,7 +365,7 @@ class Documenter(object):
self.module, self.parent, self.object_name, self.object = ret
return True
except ImportError as exc:
- self.directive.warn(exc.args[0])
+ logger.warning(exc.args[0])
self.env.note_reread()
return False
@@ -426,8 +425,8 @@ class Documenter(object):
try:
args = self.format_args()
except Exception as err:
- self.directive.warn('error while formatting arguments for '
- '%s: %s' % (self.fullname, err))
+ logger.warning('error while formatting arguments for %s: %s' %
+ (self.fullname, err))
args = None
retann = self.retann
@@ -549,8 +548,8 @@ class Documenter(object):
if name in members:
selected.append((name, members[name].value))
else:
- self.directive.warn('missing attribute %s in object %s' %
- (name, self.fullname))
+ logger.warning('missing attribute %s in object %s' %
+ (name, self.fullname))
return False, sorted(selected)
elif self.options.inherited_members:
return False, sorted((m.name, m.value) for m in itervalues(members))
@@ -719,11 +718,11 @@ class Documenter(object):
"""
if not self.parse_name():
# need a module to import
- self.directive.warn(
+ logger.warning(
'don\'t know which module to import for autodocumenting '
'%r (try placing a "module" or "currentmodule" directive '
- 'in the document, or giving an explicit module name)'
- % self.name)
+ 'in the document, or giving an explicit module name)' %
+ self.name)
return
# now, import the module and get object to document
@@ -809,15 +808,15 @@ class ModuleDocumenter(Documenter):
def resolve_name(self, modname, parents, path, base):
# type: (str, Any, str, Any) -> Tuple[str, List[unicode]]
if modname is not None:
- self.directive.warn('"::" in automodule name doesn\'t make sense')
+ logger.warning('"::" in automodule name doesn\'t make sense')
return (path or '') + base, []
def parse_name(self):
# type: () -> bool
ret = Documenter.parse_name(self)
if self.args or self.retann:
- self.directive.warn('signature arguments or return annotation '
- 'given for automodule %s' % self.fullname)
+ logger.warning('signature arguments or return annotation '
+ 'given for automodule %s' % self.fullname)
return ret
def add_directive_header(self, sig):
@@ -849,7 +848,7 @@ class ModuleDocumenter(Documenter):
# Sometimes __all__ is broken...
if not isinstance(memberlist, (list, tuple)) or not \
all(isinstance(entry, string_types) for entry in memberlist):
- self.directive.warn(
+ logger.warning(
'__all__ should be a list of strings, not %r '
'(in module %s) -- ignoring __all__' %
(memberlist, self.fullname))
@@ -862,10 +861,10 @@ class ModuleDocumenter(Documenter):
try:
ret.append((mname, safe_getattr(self.object, mname)))
except AttributeError:
- self.directive.warn(
+ logger.warning(
'missing attribute mentioned in :members: or __all__: '
- 'module %s, attribute %s' % (
- safe_getattr(self.object, '__name__', '???'), mname))
+ 'module %s, attribute %s' %
+ (safe_getattr(self.object, '__name__', '???'), mname))
return False, ret
diff --git a/sphinx/ext/autodoc/directive.py b/sphinx/ext/autodoc/directive.py
index 5d17481eb..6de6e5517 100644
--- a/sphinx/ext/autodoc/directive.py
+++ b/sphinx/ext/autodoc/directive.py
@@ -63,12 +63,11 @@ class DocumenterBridge(object):
self.genopt = options
self.lineno = lineno
self.filename_set = set() # type: Set[unicode]
- self.warnings = [] # type: List[nodes.Node]
self.result = ViewList()
def warn(self, msg):
# type: (unicode) -> None
- self.warnings.append(self.reporter.warning(msg, line=self.lineno))
+ logger.warning(msg, line=self.lineno)
def process_documenter_options(documenter, config, options):
@@ -134,17 +133,16 @@ class AutodocDirective(Directive):
documenter_options = process_documenter_options(doccls, env.config, self.options)
except (KeyError, ValueError, TypeError) as exc:
# an option is either unknown or has a wrong type
- msg = reporter.error('An option to %s is either unknown or '
- 'has an invalid value: %s' % (self.name, exc),
- line=lineno)
- return [msg]
+ logger.error('An option to %s is either unknown or has an invalid value: %s' %
+ (self.name, exc), line=lineno)
+ return []
# generate the output
params = DocumenterBridge(env, reporter, documenter_options, lineno)
documenter = doccls(params, self.arguments[0])
documenter.generate(more_content=self.content)
if not params.result:
- return params.warnings
+ return []
logger.debug('[autodoc] output:\n%s', '\n'.join(params.result))
@@ -154,4 +152,4 @@ class AutodocDirective(Directive):
self.state.document.settings.record_dependencies.add(fn)
result = parse_generated_content(self.state, params.result, documenter)
- return params.warnings + result
+ return result
diff --git a/tests/py35/test_autodoc_py35.py b/tests/py35/test_autodoc_py35.py
index d13e50d9c..439ebd67a 100644
--- a/tests/py35/test_autodoc_py35.py
+++ b/tests/py35/test_autodoc_py35.py
@@ -21,6 +21,7 @@ from docutils.statemachine import ViewList
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL
+from sphinx.util import logging
app = None
@@ -30,7 +31,7 @@ def setup_module(rootdir, sphinx_test_tempdir):
global app
srcdir = sphinx_test_tempdir / 'autodoc-root'
if not srcdir.exists():
- (rootdir/'test-root').copytree(srcdir)
+ (rootdir / 'test-root').copytree(srcdir)
app = SphinxTestApp(srcdir=srcdir)
app.builder.env.app = app
app.builder.env.temp_data['docname'] = 'dummy'
@@ -47,7 +48,7 @@ directive = options = None
@pytest.fixture
def setup_test():
global options, directive
- global processed_docstrings, processed_signatures, _warnings
+ global processed_docstrings, processed_signatures
options = Struct(
inherited_members = False,
@@ -70,24 +71,17 @@ def setup_test():
env = app.builder.env,
genopt = options,
result = ViewList(),
- warn = warnfunc,
filename_set = set(),
)
processed_docstrings = []
processed_signatures = []
- _warnings = []
-_warnings = []
processed_docstrings = []
processed_signatures = []
-def warnfunc(msg):
- _warnings.append(msg)
-
-
def process_docstring(app, what, name, obj, options, lines):
processed_docstrings.append((what, name))
if name == 'bar':
@@ -111,20 +105,21 @@ def skip_member(app, what, name, obj, skip, options):
@pytest.mark.usefixtures('setup_test')
def test_generate():
+ logging.setup(app, app._status, app._warning)
+
def assert_warns(warn_str, objtype, name, **kw):
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert len(directive.result) == 0, directive.result
- assert len(_warnings) == 1, _warnings
- assert warn_str in _warnings[0], _warnings
- del _warnings[:]
+ assert warn_str in app._warning.getvalue()
+ app._warning.truncate(0)
def assert_works(objtype, name, **kw):
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert directive.result
# print '\n'.join(directive.result)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
del directive.result[:]
def assert_processes(items, objtype, name, **kw):
@@ -137,7 +132,7 @@ def test_generate():
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
assert item in directive.result
del directive.result[:]
@@ -145,7 +140,7 @@ def test_generate():
inst = app.registry.documenters[objtype](directive, name)
inst.options.member_order = member_order
inst.generate(**kw)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
items = list(reversed(items))
lineiter = iter(directive.result)
# for line in directive.result:
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 1abd01b5f..d9c94bc0d 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -20,6 +20,7 @@ from docutils.statemachine import ViewList
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL
+from sphinx.util import logging
app = None
@@ -51,7 +52,7 @@ directive = options = None
@pytest.fixture
def setup_test():
global options, directive
- global processed_docstrings, processed_signatures, _warnings
+ global processed_docstrings, processed_signatures
options = Struct(
inherited_members = False,
@@ -75,28 +76,24 @@ def setup_test():
env = app.builder.env,
genopt = options,
result = ViewList(),
- warn = warnfunc,
filename_set = set(),
)
processed_docstrings = []
processed_signatures = []
- _warnings = []
+
+ app._status.truncate(0)
+ app._warning.truncate(0)
yield
AutoDirective._special_attrgetters.clear()
-_warnings = []
processed_docstrings = []
processed_signatures = []
-def warnfunc(msg):
- _warnings.append(msg)
-
-
def process_docstring(app, what, name, obj, options, lines):
processed_docstrings.append((what, name))
if name == 'bar':
@@ -120,6 +117,8 @@ def skip_member(app, what, name, obj, skip, options):
@pytest.mark.usefixtures('setup_test')
def test_parse_name():
+ logging.setup(app, app._status, app._warning)
+
def verify(objtype, name, result):
inst = app.registry.documenters[objtype](directive, name)
assert inst.parse_name()
@@ -129,8 +128,7 @@ def test_parse_name():
verify('module', 'test_autodoc', ('test_autodoc', [], None, None))
verify('module', 'test.test_autodoc', ('test.test_autodoc', [], None, None))
verify('module', 'test(arg)', ('test', [], 'arg', None))
- assert 'signature arguments' in _warnings[0]
- del _warnings[:]
+ assert 'signature arguments' in app._warning.getvalue()
# for functions/classes
verify('function', 'test_autodoc.raises',
@@ -246,7 +244,6 @@ def test_format_signature():
# test exception handling (exception is caught and args is '')
directive.env.config.autodoc_docstring_signature = False
assert formatsig('function', 'int', int, None, None) == ''
- del _warnings[:]
# test processing by event handler
assert formatsig('method', 'bar', H.foo1, None, None) == '42'
@@ -540,6 +537,8 @@ def test_docstring_property_processing():
@pytest.mark.usefixtures('setup_test')
def test_new_documenter():
+ logging.setup(app, app._status, app._warning)
+
class MyDocumenter(ModuleLevelDocumenter):
objtype = 'integer'
directivetype = 'data'
@@ -555,10 +554,11 @@ def test_new_documenter():
add_documenter(MyDocumenter)
def assert_result_contains(item, objtype, name, **kw):
+ app._warning.truncate(0)
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
assert item in directive.result
del directive.result[:]
@@ -602,20 +602,22 @@ def test_attrgetter_using():
@pytest.mark.usefixtures('setup_test')
def test_generate():
+ logging.setup(app, app._status, app._warning)
+
def assert_warns(warn_str, objtype, name, **kw):
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert len(directive.result) == 0, directive.result
- assert len(_warnings) == 1, _warnings
- assert warn_str in _warnings[0], _warnings
- del _warnings[:]
+
+ assert warn_str in app._warning.getvalue()
+ app._warning.truncate(0)
def assert_works(objtype, name, **kw):
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert directive.result
# print '\n'.join(directive.result)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
del directive.result[:]
def assert_processes(items, objtype, name, **kw):
@@ -628,7 +630,7 @@ def test_generate():
inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
assert item in directive.result
del directive.result[:]
@@ -636,7 +638,7 @@ def test_generate():
inst = app.registry.documenters[objtype](directive, name)
inst.options.member_order = member_order
inst.generate(**kw)
- assert len(_warnings) == 0, _warnings
+ assert app._warning.getvalue() == ''
items = list(reversed(items))
lineiter = iter(directive.result)
# for line in directive.result: