From f246104a3ae77f5e250f4a222142565e2a72f1d2 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Fri, 20 May 2022 10:02:03 -0400 Subject: [PATCH] logging: always show source locations as absolute paths Nodes attached to the parse tree via the `include` directive have their `source` attribute set to the relative path of the included file. Other nodes in the tree use the full absolute path. For consistent logging, ensure that the node location is always expressed as an absolute path, when the filename is known. See https://github.com/sphinx-contrib/spelling/issues/153 for an example of the effect of the original problem. --- sphinx/util/logging.py | 3 +++ tests/test_util_logging.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py index 37fa672afbf..4c6cb29018e 100644 --- a/sphinx/util/logging.py +++ b/sphinx/util/logging.py @@ -12,6 +12,7 @@ from sphinx.errors import SphinxWarning from sphinx.util.console import colorize +from sphinx.util.osutil import abspath if TYPE_CHECKING: from sphinx.application import Sphinx @@ -514,6 +515,8 @@ class WarningLogRecordTranslator(SphinxLogRecordTranslator): def get_node_location(node: Node) -> Optional[str]: (source, line) = get_source_line(node) + if source: + source = abspath(source) if source and line: return "%s:%s" % (source, line) elif source: diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py index 49cd2c11e0c..b9756f9470c 100644 --- a/tests/test_util_logging.py +++ b/tests/test_util_logging.py @@ -2,13 +2,14 @@ import codecs import os +import os.path import pytest from docutils import nodes from sphinx.errors import SphinxWarning from sphinx.testing.util import strip_escseq -from sphinx.util import logging +from sphinx.util import logging, osutil from sphinx.util.console import colorize from sphinx.util.logging import is_suppressed_warning, prefixed_warnings from sphinx.util.parallel import ParallelTasks @@ -379,3 +380,18 @@ def test_prefixed_warnings(app, status, warning): assert 'WARNING: Another PREFIX: message3' in warning.getvalue() assert 'WARNING: PREFIX: message4' in warning.getvalue() assert 'WARNING: message5' in warning.getvalue() + + +def test_get_node_location_abspath(): + # Ensure that node locations are reported as an absolute path, + # even if the source attribute is a relative path. + + relative_filename = os.path.join('relative', 'path.txt') + absolute_filename = osutil.abspath(relative_filename) + + n = nodes.Node() + n.source = relative_filename + + location = logging.get_node_location(n) + + assert location == absolute_filename + ':'