mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Use standard `file:line: warning: message` format for warning messages.
This commit is contained in:
@@ -134,16 +134,17 @@ class Sphinx(object):
|
||||
self.emit('build-finished', None)
|
||||
self.builder.cleanup()
|
||||
|
||||
def warn(self, message):
|
||||
def warn(self, message, location=None, prefix='warning: '):
|
||||
warntext = location and '%s: %s%s\n' % (location, prefix, message) or \
|
||||
'%s%s\n' % (prefix, message)
|
||||
if self.warningiserror:
|
||||
raise SphinxWarning('WARNING: %s\n' % message)
|
||||
raise SphinxWarning(warntext)
|
||||
self._warncount += 1
|
||||
try:
|
||||
self._warning.write('WARNING: %s\n' % message)
|
||||
self._warning.write(warntext)
|
||||
except UnicodeEncodeError:
|
||||
encoding = getattr(self._warning, 'encoding', 'ascii')
|
||||
self._warning.write(('WARNING: %s\n' % message).encode(encoding,
|
||||
'replace'))
|
||||
self._warning.write(warntext.encode(encoding, 'replace'))
|
||||
|
||||
def info(self, message='', nonl=False):
|
||||
try:
|
||||
|
||||
@@ -136,9 +136,9 @@ class Builder(object):
|
||||
if candidate:
|
||||
break
|
||||
else:
|
||||
self.warn('%s:%s: no matching candidate for image URI %r' %
|
||||
(node.source, getattr(node, 'lineno', ''),
|
||||
node['uri']))
|
||||
self.warn(
|
||||
'no matching candidate for image URI %r' % node['uri'],
|
||||
'%s:%s' % (node.source, getattr(node, 'line', '')))
|
||||
continue
|
||||
node['uri'] = candidate
|
||||
else:
|
||||
@@ -249,7 +249,7 @@ class Builder(object):
|
||||
updated_docnames = set()
|
||||
# while reading, collect all warnings from docutils
|
||||
warnings = []
|
||||
self.env.set_warnfunc(warnings.append)
|
||||
self.env.set_warnfunc(lambda *args: warnings.append(args))
|
||||
self.info(bold('updating environment: '), nonl=1)
|
||||
iterator = self.env.update(self.config, self.srcdir,
|
||||
self.doctreedir, self.app)
|
||||
@@ -261,8 +261,7 @@ class Builder(object):
|
||||
# nothing further to do, the environment has already
|
||||
# done the reading
|
||||
for warning in warnings:
|
||||
if warning.strip():
|
||||
self.warn(warning)
|
||||
self.warn(*warning)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
|
||||
doccount = len(updated_docnames)
|
||||
@@ -327,14 +326,13 @@ class Builder(object):
|
||||
|
||||
# write target files
|
||||
warnings = []
|
||||
self.env.set_warnfunc(warnings.append)
|
||||
self.env.set_warnfunc(lambda *args: warnings.append(args))
|
||||
for docname in self.status_iterator(sorted(docnames),
|
||||
'writing output... ', darkgreen):
|
||||
doctree = self.env.get_and_resolve_doctree(docname, self)
|
||||
self.write_doc(docname, doctree)
|
||||
for warning in warnings:
|
||||
if warning.strip():
|
||||
self.warn(warning)
|
||||
self.warn(*warning)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
|
||||
def prepare_writing(self, docnames):
|
||||
|
||||
@@ -657,7 +657,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
finally:
|
||||
f.close()
|
||||
except (IOError, OSError), err:
|
||||
self.warn("Error writing file %s: %s" % (outfilename, err))
|
||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
||||
if self.copysource and ctx.get('sourcename'):
|
||||
# copy the source file for the "show source" link
|
||||
source_name = path.join(self.outdir, '_sources',
|
||||
|
||||
@@ -60,8 +60,8 @@ class LaTeXBuilder(Builder):
|
||||
def init_document_data(self):
|
||||
preliminary_document_data = map(list, self.config.latex_documents)
|
||||
if not preliminary_document_data:
|
||||
self.warn('No "latex_documents" config value found; no documents '
|
||||
'will be written.')
|
||||
self.warn('no "latex_documents" config value found; no documents '
|
||||
'will be written')
|
||||
return
|
||||
# assign subdirs to titles
|
||||
self.titles = []
|
||||
@@ -121,8 +121,9 @@ class LaTeXBuilder(Builder):
|
||||
includefile, self.env.get_doctree(includefile))
|
||||
self.docnames.add(includefile)
|
||||
except Exception:
|
||||
self.warn('%s: toctree contains ref to nonexisting '
|
||||
'file %r' % (docname, includefile))
|
||||
self.warn('toctree contains ref to nonexisting '
|
||||
'file %r' % includefile,
|
||||
self.builder.env.doc2path(docname))
|
||||
else:
|
||||
sof = addnodes.start_of_file(docname=includefile)
|
||||
sof.children = subtree.children
|
||||
|
||||
@@ -87,7 +87,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
self.write_entry('broken', docname, lineno, uri + ': ' + s)
|
||||
self.broken[uri] = (r, s)
|
||||
if self.app.quiet:
|
||||
self.warn('%s:%s: broken link: %s' % (docname, lineno, uri))
|
||||
self.warn('broken link: %s' % uri,
|
||||
'%s:%s' % (self.env.doc2path(docname), lineno))
|
||||
else:
|
||||
self.info(' - ' + purple('redirected') + ' to ' + s)
|
||||
self.write_entry('redirected', docname,
|
||||
@@ -99,7 +100,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
self.warn(uri + ' - ' + red('malformed!'))
|
||||
self.write_entry('malformed', docname, lineno, uri)
|
||||
if self.app.quiet:
|
||||
self.warn('%s:%s: malformed link: %s' % (docname, lineno, uri))
|
||||
self.warn('malformed link: %s' % uri,
|
||||
'%s:%s' % (self.env.doc2path(docname), lineno))
|
||||
self.app.statuscode = 1
|
||||
|
||||
if self.broken:
|
||||
|
||||
@@ -64,7 +64,7 @@ class TextBuilder(Builder):
|
||||
finally:
|
||||
f.close()
|
||||
except (IOError, OSError), err:
|
||||
self.warn("Error writing file %s: %s" % (outfilename, err))
|
||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
|
||||
@@ -71,12 +71,12 @@ default_substitutions = set([
|
||||
dummy_reporter = Reporter('', 4, 4)
|
||||
|
||||
|
||||
class RedirStream(object):
|
||||
def __init__(self, writefunc):
|
||||
self.writefunc = writefunc
|
||||
class WarningStream(object):
|
||||
def __init__(self, warnfunc):
|
||||
self.warnfunc = warnfunc
|
||||
def write(self, text):
|
||||
if text.strip():
|
||||
self.writefunc(text)
|
||||
self.warnfunc(text, None, '')
|
||||
|
||||
|
||||
class NoUri(Exception):
|
||||
@@ -323,15 +323,15 @@ class BuildEnvironment:
|
||||
|
||||
def set_warnfunc(self, func):
|
||||
self._warnfunc = func
|
||||
self.settings['warning_stream'] = RedirStream(func)
|
||||
self.settings['warning_stream'] = WarningStream(func)
|
||||
|
||||
def warn(self, docname, msg, lineno=None):
|
||||
if docname:
|
||||
if lineno is None:
|
||||
lineno = ''
|
||||
self._warnfunc('%s:%s: %s' % (self.doc2path(docname), lineno, msg))
|
||||
self._warnfunc(msg, '%s:%s' % (self.doc2path(docname), lineno))
|
||||
else:
|
||||
self._warnfunc('GLOBAL:: ' + msg)
|
||||
self._warnfunc(msg)
|
||||
|
||||
def clear_doc(self, docname):
|
||||
"""Remove all traces of a source file in the inventory."""
|
||||
@@ -688,7 +688,7 @@ class BuildEnvironment:
|
||||
filepath = path.normpath(path.join(docdir, node['reftarget']))
|
||||
self.dependencies.setdefault(docname, set()).add(filepath)
|
||||
if not os.access(path.join(self.srcdir, filepath), os.R_OK):
|
||||
self.warn(docname, 'Download file not readable: %s' % filepath,
|
||||
self.warn(docname, 'download file not readable: %s' % filepath,
|
||||
getattr(node, 'line', None))
|
||||
continue
|
||||
uniquename = self.dlfiles.add_file(docname, filepath)
|
||||
@@ -707,7 +707,7 @@ class BuildEnvironment:
|
||||
node['candidates'] = candidates = {}
|
||||
imguri = node['uri']
|
||||
if imguri.find('://') != -1:
|
||||
self.warn(docname, 'Nonlocal image URI found: %s' % imguri,
|
||||
self.warn(docname, 'nonlocal image URI found: %s' % imguri,
|
||||
node.line)
|
||||
candidates['?'] = imguri
|
||||
continue
|
||||
@@ -735,7 +735,7 @@ class BuildEnvironment:
|
||||
f.close()
|
||||
except (OSError, IOError):
|
||||
self.warn(docname,
|
||||
'Image file %s not readable' % filename)
|
||||
'image file %s not readable' % filename)
|
||||
if imgtype:
|
||||
candidates['image/' + imgtype] = new_imgpath
|
||||
else:
|
||||
@@ -745,7 +745,7 @@ class BuildEnvironment:
|
||||
for imgpath in candidates.itervalues():
|
||||
self.dependencies.setdefault(docname, set()).add(imgpath)
|
||||
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
|
||||
self.warn(docname, 'Image file not readable: %s' % imgpath,
|
||||
self.warn(docname, 'image file not readable: %s' % imgpath,
|
||||
node.line)
|
||||
continue
|
||||
self.images.add_file(docname, imgpath)
|
||||
@@ -970,7 +970,7 @@ class BuildEnvironment:
|
||||
f.close()
|
||||
doctree.settings.env = self
|
||||
doctree.reporter = Reporter(self.doc2path(docname), 2, 4,
|
||||
stream=RedirStream(self._warnfunc))
|
||||
stream=WarningStream(self._warnfunc))
|
||||
return doctree
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class Theme(object):
|
||||
tname = theme[:-4]
|
||||
tinfo = zfile
|
||||
except Exception:
|
||||
builder.warn('File %r on theme path is not a valid '
|
||||
builder.warn('file %r on theme path is not a valid '
|
||||
'zipfile or contains no theme' % theme)
|
||||
continue
|
||||
else:
|
||||
|
||||
@@ -368,7 +368,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
elif self.this_is_the_title:
|
||||
if len(node.children) != 1 and not isinstance(node.children[0],
|
||||
nodes.Text):
|
||||
self.builder.warn('document title is not a single Text node')
|
||||
self.builder.warn(
|
||||
'document title is not a single Text node',
|
||||
'%s:%s' % (self.builder.env.doc2path(self.curfilestack[-1]),
|
||||
node.line or ''))
|
||||
if not self.elements['title']:
|
||||
# text needs to be escaped since it is inserted into
|
||||
# the output literally
|
||||
@@ -394,8 +397,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.table.caption = self.encode(node.astext())
|
||||
raise nodes.SkipNode
|
||||
else:
|
||||
self.builder.warn('encountered title node not in section, topic, '
|
||||
'table, admonition or sidebar')
|
||||
self.builder.warn(
|
||||
'encountered title node not in section, topic, table, '
|
||||
'admonition or sidebar',
|
||||
'%s:%s' % (self.builder.env.doc2path(self.curfilestack[-1]),
|
||||
node.line or ''))
|
||||
self.body.append('\\textbf{')
|
||||
self.context.append('}\n')
|
||||
self.in_title = 1
|
||||
@@ -1002,7 +1008,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\\grammartoken{')
|
||||
self.context.append('}')
|
||||
else:
|
||||
self.builder.warn('unusable reference target found: %s' % uri)
|
||||
self.builder.warn(
|
||||
'unusable reference target found: %s' % uri,
|
||||
'%s:%s' % (self.builder.env.doc2path(self.curfilestack[-1]),
|
||||
node.line or ''))
|
||||
self.context.append('')
|
||||
def depart_reference(self, node):
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
@@ -53,7 +53,7 @@ def test_output():
|
||||
|
||||
old_count = app._warncount
|
||||
app.warn("Bad news!")
|
||||
assert warnings.getvalue() == "WARNING: Bad news!\n"
|
||||
assert warnings.getvalue() == "warning: Bad news!\n"
|
||||
assert app._warncount == old_count + 1
|
||||
finally:
|
||||
app.cleanup()
|
||||
|
||||
@@ -36,6 +36,7 @@ def setup_module():
|
||||
platform = '',
|
||||
deprecated = False,
|
||||
members = [],
|
||||
member_order = 'alphabetic',
|
||||
)
|
||||
|
||||
directive = Struct(
|
||||
|
||||
@@ -38,24 +38,24 @@ html_warnfile = StringIO()
|
||||
latex_warnfile = StringIO()
|
||||
|
||||
ENV_WARNINGS = """\
|
||||
WARNING: %(root)s/images.txt:9: Image file not readable: foo.png
|
||||
WARNING: %(root)s/images.txt:23: Nonlocal image URI found: \
|
||||
%(root)s/images.txt:9: warning: image file not readable: foo.png
|
||||
%(root)s/images.txt:23: warning: nonlocal image URI found: \
|
||||
http://www.python.org/logo.png
|
||||
WARNING: %(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8' used for reading \
|
||||
%(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8' used for reading \
|
||||
included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option
|
||||
WARNING: %(root)s/includes.txt:56: Download file not readable: nonexisting.png
|
||||
%(root)s/includes.txt:56: warning: download file not readable: nonexisting.png
|
||||
"""
|
||||
|
||||
HTML_WARNINGS = ENV_WARNINGS + """\
|
||||
WARNING: %(root)s/images.txt:: no matching candidate for image URI u'foo.*'
|
||||
WARNING: %(root)s/markup.txt:: invalid index entry u''
|
||||
WARNING: %(root)s/markup.txt:: invalid pair index entry u''
|
||||
WARNING: %(root)s/markup.txt:: invalid pair index entry u'keyword; '
|
||||
%(root)s/images.txt:20: warning: no matching candidate for image URI u'foo.*'
|
||||
%(root)s/markup.txt:: warning: invalid index entry u''
|
||||
%(root)s/markup.txt:: warning: invalid pair index entry u''
|
||||
%(root)s/markup.txt:: warning: invalid pair index entry u'keyword; '
|
||||
"""
|
||||
|
||||
LATEX_WARNINGS = ENV_WARNINGS + """\
|
||||
WARNING: None:: no matching candidate for image URI u'foo.*'
|
||||
WARNING: invalid pair index entry u''
|
||||
None:None: warning: no matching candidate for image URI u'foo.*'
|
||||
warning: invalid pair index entry u''
|
||||
"""
|
||||
|
||||
HTML_XPATH = {
|
||||
|
||||
@@ -22,14 +22,14 @@ def setup_module():
|
||||
global app, env
|
||||
app = TestApp(srcdir='(temp)')
|
||||
env = BuildEnvironment(app.srcdir, app.doctreedir, app.config)
|
||||
env.set_warnfunc(warnings.append)
|
||||
env.set_warnfunc(lambda *args: warnings.append(args))
|
||||
|
||||
def teardown_module():
|
||||
app.cleanup()
|
||||
|
||||
def warning_emitted(file, text):
|
||||
for warning in warnings:
|
||||
if file+':' in warning and text in warning:
|
||||
if len(warning) == 2 and file+':' in warning[1] and text in warning[0]:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -46,8 +46,8 @@ def test_first_update():
|
||||
assert docnames == env.found_docs == set(env.all_docs)
|
||||
|
||||
def test_images():
|
||||
assert warning_emitted('images.txt', 'Image file not readable: foo.png')
|
||||
assert warning_emitted('images.txt', 'Nonlocal image URI found: '
|
||||
assert warning_emitted('images.txt', 'image file not readable: foo.png')
|
||||
assert warning_emitted('images.txt', 'nonlocal image URI found: '
|
||||
'http://www.python.org/logo.png')
|
||||
|
||||
tree = env.get_doctree('images')
|
||||
|
||||
Reference in New Issue
Block a user