From 6853e581db2d823995d30de289de27026c24022d 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 | 3 +++ sphinx/builders/gettext.py | 2 +- tests/test_build_gettext.py | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 424a12eaae..111360da2d 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,9 @@ Features added Bugs fixed ---------- +* #10104: gettext: Duplicated locations are shown if 3rd party extension does + not provide correct information + Testing -------- 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.