From e3b79370446f5cd02a369a43dcc32f43e50f5775 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 23 May 2022 00:37:45 +0900 Subject: [PATCH] Fix #10104: gettext: Duplicated locations are output to pot file When 3rd party extension does not provide line number for each message, duplicated locations are output to pot file unexpectedly. This filters duplicated locations before generationg pot file. --- CHANGES | 2 ++ sphinx/builders/gettext.py | 2 +- tests/test_build_gettext.py | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index ed47709e53..69e6fdd097 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,8 @@ Bugs fixed * #9648: autodoc: ``*args`` and ``**kwargs`` entries are duplicated when ``autodoc_typehints="description"`` * #10443: epub: EPUB builder can't detect the mimetype of .webp file +* #10104: gettext: Duplicated locations are shown if 3rd party extension does + not provide correct information * #10456: py domain: ``:meta:`` fields are displayed if docstring contains two or more meta-field * #9096: sphinx-build: the value of progress bar for paralle build is wrong diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index e8bc547b77..3f78120471 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -57,7 +57,7 @@ def add(self, msg: str, origin: Union[Element, "MsgOrigin"]) -> None: def __iter__(self) -> Generator[Message, None, None]: for message in self.messages: - positions = [(source, line) for source, line, uuid in self.metadata[message]] + positions = sorted(set((source, line) for source, line, uuid in self.metadata[message])) uuids = [uuid for source, line, uuid in self.metadata[message]] yield Message(message, positions, uuids) diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py index 3c4617e849..cca6fab929 100644 --- a/tests/test_build_gettext.py +++ b/tests/test_build_gettext.py @@ -8,9 +8,29 @@ import pytest +from sphinx.builders.gettext import Catalog, MsgOrigin from sphinx.util.osutil import cd +def test_Catalog_duplicated_message(): + catalog = Catalog() + catalog.add('hello', MsgOrigin('/path/to/filename', 1)) + catalog.add('hello', MsgOrigin('/path/to/filename', 1)) + catalog.add('hello', MsgOrigin('/path/to/filename', 2)) + catalog.add('hello', MsgOrigin('/path/to/yetanother', 1)) + catalog.add('world', MsgOrigin('/path/to/filename', 1)) + + assert len(list(catalog)) == 2 + + msg1, msg2 = list(catalog) + assert msg1.text == 'hello' + assert msg1.locations == [('/path/to/filename', 1), + ('/path/to/filename', 2), + ('/path/to/yetanother', 1)] + assert msg2.text == 'world' + assert msg2.locations == [('/path/to/filename', 1)] + + @pytest.mark.sphinx('gettext', srcdir='root-gettext') def test_build_gettext(app): # Generic build; should fail only when the builder is horribly broken.