summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2016-12-27 02:13:56 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2017-01-02 12:59:51 +0900
commit15b46598e21c05fae6064b8f64e9dd00a73ed9d9 (patch)
tree0b60c8a3e387ad34ee1460893cdf2532ddee9e91
parente755a8c004291faa27e511205d2c365e8461bf9f (diff)
downloadsphinx-git-15b46598e21c05fae6064b8f64e9dd00a73ed9d9.tar.gz
logger.warning() supports node as location parameter
-rw-r--r--sphinx/builders/__init__.py4
-rw-r--r--sphinx/domains/cpp.py2
-rw-r--r--sphinx/domains/python.py7
-rw-r--r--sphinx/domains/std.py20
-rw-r--r--sphinx/environment/__init__.py29
-rw-r--r--sphinx/environment/managers/indexentries.py2
-rw-r--r--sphinx/environment/managers/toctree.py12
-rw-r--r--sphinx/ext/autosectionlabel.py5
-rw-r--r--sphinx/ext/todo.py3
-rw-r--r--sphinx/transforms/__init__.py2
-rw-r--r--sphinx/transforms/i18n.py13
-rw-r--r--sphinx/util/logging.py28
-rw-r--r--sphinx/util/nodes.py4
-rw-r--r--sphinx/writers/html.py6
-rw-r--r--tests/test_util_logging.py24
15 files changed, 77 insertions, 84 deletions
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index 7448e2682..3a592a257 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -161,8 +161,8 @@ class Builder(object):
if candidate:
break
else:
- logger.warn_node('no matching candidate for image URI %r' % node['uri'],
- node)
+ logger.warning('no matching candidate for image URI %r', node['uri'],
+ location=node)
continue
node['uri'] = candidate
else:
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 52d520a05..cfdbc99d9 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -4885,7 +4885,7 @@ class CPPDomain(Domain):
class Warner(object):
def warn(self, msg):
if emitWarnings:
- logger.warn_node(msg, node)
+ logger.warning(msg, location=node)
warner = Warner()
parser = DefinitionParser(target, warner, env.config)
try:
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 1da874ea2..886b1f863 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -787,10 +787,9 @@ class PythonDomain(Domain):
if not matches:
return None
elif len(matches) > 1:
- logger.warn_node(
- 'more than one target found for cross-reference '
- '%r: %s' % (target, ', '.join(match[0] for match in matches)),
- node)
+ logger.warning('more than one target found for cross-reference %r: %s',
+ target, ', '.join(match[0] for match in matches),
+ location=node)
name, obj = matches[0]
if obj[1] == 'module':
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index eb355ecf2..c351a15af 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -573,8 +573,8 @@ class StandardDomain(Domain):
label = node[0].astext()
if label in self.data['citations']:
path = env.doc2path(self.data['citations'][label][0])
- logger.warn_node('duplicate citation %s, other instance in %s' %
- (label, path), node)
+ logger.warning('duplicate citation %s, other instance in %s', label, path,
+ location=node)
self.data['citations'][label] = (docname, node['ids'][0])
def note_labels(self, env, docname, document):
@@ -596,8 +596,9 @@ class StandardDomain(Domain):
# link and object descriptions
continue
if name in labels:
- logger.warn_node('duplicate label %s, ' % name + 'other instance '
- 'in ' + env.doc2path(labels[name][0]), node)
+ logger.warning('duplicate label %s, ' % name + 'other instance '
+ 'in ' + env.doc2path(labels[name][0]),
+ location=node)
anonlabels[name] = docname, labelid
if node.tagname == 'section':
sectname = clean_astext(node[0]) # node[0] == title node
@@ -688,7 +689,7 @@ class StandardDomain(Domain):
return None
if env.config.numfig is False:
- logger.warn_node('numfig is disabled. :numref: is ignored.', node)
+ logger.warning('numfig is disabled. :numref: is ignored.', location=node)
return contnode
target_node = env.get_doctree(docname).ids.get(labelid)
@@ -701,7 +702,8 @@ class StandardDomain(Domain):
if fignumber is None:
return contnode
except ValueError:
- logger.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node)
+ logger.warning("no number is assigned for %s: %s", figtype, labelid,
+ location=node)
return contnode
try:
@@ -711,7 +713,7 @@ class StandardDomain(Domain):
title = env.config.numfig_format.get(figtype, '')
if figname is None and '%{name}' in title:
- logger.warn_node('the link has no caption: %s' % title, node)
+ logger.warning('the link has no caption: %s', title, location=node)
return contnode
else:
fignum = '.'.join(map(str, fignumber))
@@ -725,10 +727,10 @@ class StandardDomain(Domain):
# old style format (cf. "Fig.%s")
newtitle = title % fignum
except KeyError as exc:
- logger.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node)
+ logger.warning('invalid numfig_format: %s (%r)', title, exc, location=node)
return contnode
except TypeError:
- logger.warn_node('invalid numfig_format: %s' % title, node)
+ logger.warning('invalid numfig_format: %s', title, location=node)
return contnode
return self.build_reference_node(fromdocname, builder,
diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py
index 4b6e9bf31..1fb9ec19e 100644
--- a/sphinx/environment/__init__.py
+++ b/sphinx/environment/__init__.py
@@ -902,8 +902,8 @@ class BuildEnvironment(object):
rel_filename, filename = self.relfn2path(targetname, docname)
self.dependencies[docname].add(rel_filename)
if not os.access(filename, os.R_OK):
- logger.warn_node('download file not readable: %s' % filename,
- node)
+ logger.warning('download file not readable: %s', filename,
+ location=node)
continue
uniquename = self.dlfiles.add_file(docname, filename)
node['filename'] = uniquename
@@ -921,8 +921,8 @@ class BuildEnvironment(object):
if mimetype not in candidates:
globbed.setdefault(mimetype, []).append(new_imgpath)
except (OSError, IOError) as err:
- logger.warn_node('image file %s not readable: %s' %
- (filename, err), node)
+ logger.warning('image file %s not readable: %s', filename, err,
+ location=node)
for key, files in iteritems(globbed):
candidates[key] = sorted(files, key=len)[0] # select by similarity
@@ -934,13 +934,13 @@ class BuildEnvironment(object):
node['candidates'] = candidates = {}
imguri = node['uri']
if imguri.startswith('data:'):
- logger.warn_node('image data URI found. some builders might not support', node,
- type='image', subtype='data_uri')
+ logger.warning('image data URI found. some builders might not support',
+ location=node, type='image', subtype='data_uri')
candidates['?'] = imguri
continue
elif imguri.find('://') != -1:
- logger.warn_node('nonlocal image URI found: %s' % imguri, node,
- type='image', subtype='nonlocal_uri')
+ logger.warning('nonlocal image URI found: %s', imguri,
+ location=node, type='image', subtype='nonlocal_uri')
candidates['?'] = imguri
continue
rel_imgpath, full_imgpath = self.relfn2path(imguri, docname)
@@ -969,8 +969,8 @@ class BuildEnvironment(object):
for imgpath in itervalues(candidates):
self.dependencies[docname].add(imgpath)
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
- logger.warn_node('image file not readable: %s' % imgpath,
- node)
+ logger.warning('image file not readable: %s', imgpath,
+ location=node)
continue
self.images.add_file(docname, imgpath)
@@ -1183,7 +1183,8 @@ class BuildEnvironment(object):
(node['refdomain'], typ)
else:
msg = '%r reference target not found: %%(target)s' % typ
- logger.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)
+ logger.warning(msg % {'target': target},
+ location=node, type='ref', subtype=typ)
def _resolve_doc_reference(self, builder, refdoc, node, contnode):
# type: (Builder, unicode, nodes.Node, nodes.Node) -> nodes.Node
@@ -1234,9 +1235,9 @@ class BuildEnvironment(object):
return None
if len(results) > 1:
nice_results = ' or '.join(':%s:' % r[0] for r in results)
- logger.warn_node('more than one target found for \'any\' cross-'
- 'reference %r: could be %s' % (target, nice_results),
- node)
+ logger.warning('more than one target found for \'any\' cross-'
+ 'reference %r: could be %s', target, nice_results,
+ location=node)
res_role, newnode = results[0]
# Override "any" class with the actual role type to get the styling
# approximately correct.
diff --git a/sphinx/environment/managers/indexentries.py b/sphinx/environment/managers/indexentries.py
index 43e3b4c83..ef9c84d02 100644
--- a/sphinx/environment/managers/indexentries.py
+++ b/sphinx/environment/managers/indexentries.py
@@ -55,7 +55,7 @@ class IndexEntries(EnvironmentManager):
for entry in node['entries']:
split_index_msg(entry[0], entry[1])
except ValueError as exc:
- logger.warn_node(str(exc), node)
+ logger.warning(str(exc), location=node)
node.parent.remove(node)
else:
for entry in node['entries']:
diff --git a/sphinx/environment/managers/toctree.py b/sphinx/environment/managers/toctree.py
index 64937b7fa..1df3f0999 100644
--- a/sphinx/environment/managers/toctree.py
+++ b/sphinx/environment/managers/toctree.py
@@ -317,15 +317,13 @@ class Toctree(EnvironmentManager):
refnode.children = [nodes.Text(title)]
if not toc.children:
# empty toc means: no titles will show up in the toctree
- logger.warn_node(
- 'toctree contains reference to document %r that '
- 'doesn\'t have a title: no link will be generated'
- % ref, toctreenode)
+ logger.warning('toctree contains reference to document %r that '
+ 'doesn\'t have a title: no link will be generated',
+ ref, location=toctreenode)
except KeyError:
# this is raised if the included file does not exist
- logger.warn_node(
- 'toctree contains reference to nonexisting document %r'
- % ref, toctreenode)
+ logger.warning('toctree contains reference to nonexisting document %r',
+ ref, location=toctreenode)
else:
# if titles_only is given, only keep the main title and
# sub-toctrees
diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py
index 78cb3c042..d45ba66a6 100644
--- a/sphinx/ext/autosectionlabel.py
+++ b/sphinx/ext/autosectionlabel.py
@@ -26,8 +26,9 @@ def register_sections_as_label(app, document):
sectname = clean_astext(node[0])
if name in labels:
- logger.warn_node('duplicate label %s, ' % name + 'other instance '
- 'in ' + app.env.doc2path(labels[name][0]), node)
+ logger.warning('duplicate label %s, ' % name + 'other instance '
+ 'in ' + app.env.doc2path(labels[name][0]),
+ location=node)
anonlabels[name] = docname, labelid
labels[name] = docname, labelid, sectname
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index e8d8201df..f575e7462 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -100,7 +100,8 @@ def process_todos(app, doctree):
})
if env.config.todo_emit_warnings:
- logger.warn_node("TODO entry found: %s" % node[1].astext(), node)
+ logger.warning("TODO entry found: %s", node[1].astext(),
+ location=node)
class TodoList(Directive):
diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py
index fad0d0038..4eb65af6e 100644
--- a/sphinx/transforms/__init__.py
+++ b/sphinx/transforms/__init__.py
@@ -181,7 +181,7 @@ class AutoIndexUpgrader(Transform):
if 'entries' in node and any(len(entry) == 4 for entry in node['entries']):
msg = ('4 column based index found. '
'It might be a bug of extensions you use: %r' % node['entries'])
- logger.warn_node(msg, node)
+ logger.warning(msg, location=node)
for i, entry in enumerate(node['entries']):
if len(entry) == 4:
node['entries'][i] = entry + (None,)
diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py
index addd617d4..8663c573d 100644
--- a/sphinx/transforms/i18n.py
+++ b/sphinx/transforms/i18n.py
@@ -274,8 +274,8 @@ class Locale(Transform):
old_foot_refs = node.traverse(is_autonumber_footnote_ref)
new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
if len(old_foot_refs) != len(new_foot_refs):
- logger.warn_node('inconsistent footnote references in '
- 'translated message', node)
+ logger.warning('inconsistent footnote references in translated message',
+ location=node)
old_foot_namerefs = {} # type: Dict[unicode, List[nodes.footnote_reference]]
for r in old_foot_refs:
old_foot_namerefs.setdefault(r.get('refname'), []).append(r)
@@ -309,7 +309,8 @@ class Locale(Transform):
old_refs = node.traverse(is_refnamed_ref)
new_refs = patch.traverse(is_refnamed_ref)
if len(old_refs) != len(new_refs):
- logger.warn_node('inconsistent references in translated message', node)
+ logger.warning('inconsistent references in translated message',
+ location=node)
old_ref_names = [r['refname'] for r in old_refs]
new_ref_names = [r['refname'] for r in new_refs]
orphans = list(set(old_ref_names) - set(new_ref_names))
@@ -337,7 +338,8 @@ class Locale(Transform):
new_refs = patch.traverse(is_refnamed_footnote_ref)
refname_ids_map = {}
if len(old_refs) != len(new_refs):
- logger.warn_node('inconsistent references in translated message', node)
+ logger.warning('inconsistent references in translated message',
+ location=node)
for old in old_refs:
refname_ids_map[old["refname"]] = old["ids"]
for new in new_refs:
@@ -352,7 +354,8 @@ class Locale(Transform):
new_refs = patch.traverse(addnodes.pending_xref)
xref_reftarget_map = {}
if len(old_refs) != len(new_refs):
- logger.warn_node('inconsistent term references in translated message', node)
+ logger.warning('inconsistent term references in translated message',
+ location=node)
def get_ref_key(node):
# type: (nodes.Node) -> Tuple[unicode, unicode, unicode]
diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py
index 95b14be9a..ecec2649a 100644
--- a/sphinx/util/logging.py
+++ b/sphinx/util/logging.py
@@ -16,6 +16,7 @@ from contextlib import contextmanager
from collections import defaultdict
from six import PY2, StringIO
+from docutils import nodes
from docutils.utils import get_source_line
from sphinx.errors import SphinxWarning
@@ -92,23 +93,6 @@ class SphinxWarningLogRecord(logging.LogRecord):
class SphinxLoggerAdapter(logging.LoggerAdapter):
"""LoggerAdapter allowing ``type`` and ``subtype`` keywords."""
- def warn_node(self, message, node, **kwargs):
- # type: (unicode, nodes.Node, Any) -> None
- """Emit a warning for specific node.
-
- :param message: a message of warning
- :param node: a node related with the warning
- """
- (source, line) = get_source_line(node)
- if source and line:
- kwargs['location'] = "%s:%s" % (source, line)
- elif source:
- kwargs['location'] = "%s:" % source
- elif line:
- kwargs['location'] = "<unknown>:%s" % line
-
- self.warning(message, **kwargs)
-
def log(self, level, msg, *args, **kwargs):
# type: (Union[int, str], unicode, Any, Any) -> None
if isinstance(level, int):
@@ -374,6 +358,16 @@ class WarningLogRecordTranslator(logging.Filter):
record.location = '%s' % self.app.env.doc2path(docname)
else:
record.location = None
+ elif isinstance(location, nodes.Node):
+ (source, line) = get_source_line(location)
+ if source and line:
+ record.location = "%s:%s" % (source, line)
+ elif source:
+ record.location = "%s:" % source
+ elif line:
+ record.location = "<unknown>:%s" % line
+ else:
+ record.location = None
elif location and ':' not in location:
record.location = '%s' % self.app.env.doc2path(location)
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index a5aa58444..4c574c242 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -362,8 +362,8 @@ def process_only_nodes(doctree, tags):
try:
ret = tags.eval_condition(node['expr'])
except Exception as err:
- logger.warn_node('exception while evaluating only '
- 'directive expression: %s' % err, node)
+ logger.warning('exception while evaluating only directive expression: %s', err,
+ location=node)
node.replace_self(node.children or nodes.comment())
else:
if ret:
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 0daaffd82..6a455cdb4 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -302,7 +302,7 @@ class HTMLTranslator(BaseTranslator):
if figtype:
if len(node['ids']) == 0:
msg = 'Any IDs not assigned for %s node' % node.tagname
- logger.warn_node(msg, node)
+ logger.warning(msg, location=node)
else:
append_fignumber(figtype, node['ids'][0])
@@ -525,8 +525,8 @@ class HTMLTranslator(BaseTranslator):
if not ('width' in node and 'height' in node):
size = get_image_size(os.path.join(self.builder.srcdir, olduri))
if size is None:
- logger.warn_node('Could not obtain image size. '
- ':scale: option is ignored.', node)
+ logger.warning('Could not obtain image size. :scale: option is ignored.',
+ location=node)
else:
if 'width' not in node:
node['width'] = str(size[0])
diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py
index 59c899369..0fc7277a7 100644
--- a/tests/test_util_logging.py
+++ b/tests/test_util_logging.py
@@ -199,30 +199,24 @@ def test_warning_location(app, status, warning):
assert 'index.txt:10: WARNING: message2' in warning.getvalue()
logger.warning('message3', location=None)
- assert '\x1b[31mWARNING: message3' in warning.getvalue() # \x1b[31m = darkred
-
-
-@with_app()
-def test_warn_node(app, status, warning):
- logging.setup(app, status, warning)
- logger = logging.getLogger(__name__)
+ assert colorize('darkred', 'WARNING: message3') in warning.getvalue()
node = nodes.Node()
node.source, node.line = ('index.txt', 10)
- logger.warn_node('message1', node)
- assert 'index.txt:10: WARNING: message1' in warning.getvalue()
+ logger.warning('message4', location=node)
+ assert 'index.txt:10: WARNING: message4' in warning.getvalue()
node.source, node.line = ('index.txt', None)
- logger.warn_node('message2', node)
- assert 'index.txt:: WARNING: message2' in warning.getvalue()
+ logger.warning('message5', location=node)
+ assert 'index.txt:: WARNING: message5' in warning.getvalue()
node.source, node.line = (None, 10)
- logger.warn_node('message3', node)
- assert '<unknown>:10: WARNING: message3' in warning.getvalue()
+ logger.warning('message6', location=node)
+ assert '<unknown>:10: WARNING: message6' in warning.getvalue()
node.source, node.line = (None, None)
- logger.warn_node('message4', node)
- assert '\x1b[31mWARNING: message4' in warning.getvalue() # \x1b[31m = darkred
+ logger.warning('message7', location=node)
+ assert colorize('darkred', 'WARNING: message7') in warning.getvalue()
@with_app()