diff --git a/CHANGES b/CHANGES index 3d5f028ce1..29d6e98f29 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,9 @@ Bugs fixed ---------- * #9487: autodoc: typehint for cached_property is not shown +* #9481: autosummary: some warnings contain non-existing filenames +* #9481: c domain: some warnings contain non-existing filenames +* #9481: cpp domain: some warnings contain non-existing filenames Testing -------- diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 94677e2bd0..d79172b058 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -3388,13 +3388,13 @@ def run(self) -> List[Node]: stack: List[Symbol] = [] else: parser = DefinitionParser(self.arguments[0], - location=self.get_source_info(), + location=self.get_location(), config=self.env.config) try: name = parser.parse_namespace_object() parser.assert_end() except DefinitionError as e: - logger.warning(e, location=self.get_source_info()) + logger.warning(e, location=self.get_location()) name = _make_phony_error_name() symbol = rootSymbol.add_name(name) stack = [symbol] @@ -3415,13 +3415,13 @@ def run(self) -> List[Node]: if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): return [] parser = DefinitionParser(self.arguments[0], - location=self.get_source_info(), + location=self.get_location(), config=self.env.config) try: name = parser.parse_namespace_object() parser.assert_end() except DefinitionError as e: - logger.warning(e, location=self.get_source_info()) + logger.warning(e, location=self.get_location()) name = _make_phony_error_name() oldParent = self.env.temp_data.get('c:parent_symbol', None) if not oldParent: @@ -3446,7 +3446,7 @@ def run(self) -> List[Node]: stack = self.env.temp_data.get('c:namespace_stack', None) if not stack or len(stack) == 0: logger.warning("C namespace pop on empty stack. Defaulting to gobal scope.", - location=self.get_source_info()) + location=self.get_location()) stack = [] else: stack.pop() @@ -3628,7 +3628,7 @@ def run(self) -> List[Node]: " Requested 'noroot' but 'maxdepth' 1." " When skipping the root declaration," " need 'maxdepth' 0 for infinite or at least 2.", - location=self.get_source_info()) + location=self.get_location()) signatures = self.get_signatures() for i, sig in enumerate(signatures): node.append(AliasNode(sig, aliasOptions, self.state.document, env=self.env)) @@ -3661,7 +3661,7 @@ def run(self) -> Tuple[List[Node], List[system_message]]: return super().run() text = self.text.replace('\n', ' ') - parser = DefinitionParser(text, location=self.get_source_info(), + parser = DefinitionParser(text, location=self.get_location(), config=self.env.config) try: parser.parse_xref_object() @@ -3686,7 +3686,7 @@ def run(self) -> Tuple[List[Node], List[system_message]]: msg = "{}: Pre-v3 C type role ':c:type:`{}`' converted to ':c:expr:`{}`'." msg += "\nThe original parsing error was:\n{}" msg = msg.format(RemovedInSphinx50Warning.__name__, text, text, eOrig) - logger.warning(msg, location=self.get_source_info()) + logger.warning(msg, location=self.get_location()) return [signode], [] @@ -3702,14 +3702,14 @@ def __init__(self, asCode: bool) -> None: def run(self) -> Tuple[List[Node], List[system_message]]: text = self.text.replace('\n', ' ') - parser = DefinitionParser(text, location=self.get_source_info(), + parser = DefinitionParser(text, location=self.get_location(), config=self.env.config) # attempt to mimic XRefRole classes, except that... try: ast = parser.parse_expression() except DefinitionError as ex: logger.warning('Unparseable C expression: %r\n%s', text, ex, - location=self.get_source_info()) + location=self.get_location()) # see below return [addnodes.desc_inline('c', text, text, classes=[self.class_type])], [] parentSymbol = self.env.temp_data.get('c:parent_symbol', None) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index ca88ddc0d8..ee54d92568 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -7005,7 +7005,7 @@ def add_target_and_index(self, ast: ASTDeclaration, sig: str, if not re.compile(r'^[a-zA-Z0-9_]*$').match(newestId): logger.warning('Index id generation for C++ object "%s" failed, please ' 'report as bug (id=%s).', ast, newestId, - location=self.get_source_info()) + location=self.get_location()) name = ast.symbol.get_full_nested_name().get_display_string().lstrip(':') # Add index entry, but not if it's a declaration inside a concept @@ -7088,7 +7088,7 @@ def run(self) -> List[Node]: logger.warning(msg.format( str(parentSymbol.get_full_nested_name()), self.name, self.arguments[0] - ), location=self.get_source_info()) + ), location=self.get_location()) name = _make_phony_error_name() symbol = parentSymbol.add_name(name) env.temp_data['cpp:last_symbol'] = symbol @@ -7216,13 +7216,13 @@ def run(self) -> List[Node]: stack: List[Symbol] = [] else: parser = DefinitionParser(self.arguments[0], - location=self.get_source_info(), + location=self.get_location(), config=self.config) try: ast = parser.parse_namespace_object() parser.assert_end() except DefinitionError as e: - logger.warning(e, location=self.get_source_info()) + logger.warning(e, location=self.get_location()) name = _make_phony_error_name() ast = ASTNamespace(name, None) symbol = rootSymbol.add_name(ast.nestedName, ast.templatePrefix) @@ -7244,13 +7244,13 @@ def run(self) -> List[Node]: if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): return [] parser = DefinitionParser(self.arguments[0], - location=self.get_source_info(), + location=self.get_location(), config=self.config) try: ast = parser.parse_namespace_object() parser.assert_end() except DefinitionError as e: - logger.warning(e, location=self.get_source_info()) + logger.warning(e, location=self.get_location()) name = _make_phony_error_name() ast = ASTNamespace(name, None) oldParent = self.env.temp_data.get('cpp:parent_symbol', None) @@ -7276,7 +7276,7 @@ def run(self) -> List[Node]: stack = self.env.temp_data.get('cpp:namespace_stack', None) if not stack or len(stack) == 0: logger.warning("C++ namespace pop on empty stack. Defaulting to gobal scope.", - location=self.get_source_info()) + location=self.get_location()) stack = [] else: stack.pop() @@ -7480,7 +7480,7 @@ def run(self) -> List[Node]: " Requested 'noroot' but 'maxdepth' 1." " When skipping the root declaration," " need 'maxdepth' 0 for infinite or at least 2.", - location=self.get_source_info()) + location=self.get_location()) signatures = self.get_signatures() for i, sig in enumerate(signatures): node.append(AliasNode(sig, aliasOptions, env=self.env)) @@ -7537,14 +7537,14 @@ def __init__(self, asCode: bool) -> None: def run(self) -> Tuple[List[Node], List[system_message]]: text = self.text.replace('\n', ' ') parser = DefinitionParser(text, - location=self.get_source_info(), + location=self.get_location(), config=self.config) # attempt to mimic XRefRole classes, except that... try: ast = parser.parse_expression() except DefinitionError as ex: logger.warning('Unparseable C++ expression: %r\n%s', text, ex, - location=self.get_source_info()) + location=self.get_location()) # see below return [addnodes.desc_inline('cpp', text, text, classes=[self.class_type])], [] parentSymbol = self.env.temp_data.get('cpp:parent_symbol', None) diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 2e5bc7323a..379fd48ad0 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -280,7 +280,7 @@ def run(self) -> List[Node]: msg = __('autosummary: stub file not found %r. ' 'Check your autosummary_generate setting.') - logger.warning(msg, real_name, location=self.get_source_info()) + logger.warning(msg, real_name, location=self.get_location()) continue docnames.append(docname) @@ -344,7 +344,7 @@ def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str]]: real_name, obj, parent, modname = self.import_by_name(name, prefixes=prefixes) except ImportError: logger.warning(__('autosummary: failed to import %s'), name, - location=self.get_source_info()) + location=self.get_location()) continue self.bridge.result = StringList() # initialize for each documenter @@ -358,12 +358,12 @@ def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str]]: documenter = self.create_documenter(self.env.app, obj, parent, full_name) if not documenter.parse_name(): logger.warning(__('failed to parse name %s'), real_name, - location=self.get_source_info()) + location=self.get_location()) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): logger.warning(__('failed to import object %s'), real_name, - location=self.get_source_info()) + location=self.get_location()) items.append((display_name, '', '', real_name)) continue if documenter.options.members and not documenter.check_module(): diff --git a/sphinx/util/cfamily.py b/sphinx/util/cfamily.py index 8d08966244..3aa22c6258 100644 --- a/sphinx/util/cfamily.py +++ b/sphinx/util/cfamily.py @@ -216,7 +216,7 @@ class DefinitionError(Exception): class BaseParser: def __init__(self, definition: str, *, - location: Union[nodes.Node, Tuple[str, int]], + location: Union[nodes.Node, Tuple[str, int], str], config: "Config") -> None: self.definition = definition.strip() self.location = location # for warnings diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index c2e12e1525..5a27320271 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -339,6 +339,10 @@ def set_source_info(self, node: Node) -> None: """Set source and line number to the node.""" node.source, node.line = self.get_source_info() + def get_location(self) -> str: + """Get current location info for logging.""" + return ':'.join(str(s) for s in self.get_source_info()) + class SphinxRole: """A base class for Sphinx roles. @@ -401,6 +405,10 @@ def get_source_info(self, lineno: int = None) -> Tuple[str, int]: def set_source_info(self, node: Node, lineno: int = None) -> None: node.source, node.line = self.get_source_info(lineno) + def get_location(self) -> str: + """Get current location info for logging.""" + return ':'.join(str(s) for s in self.get_source_info()) + class ReferenceRole(SphinxRole): """A base class for reference roles.