From 51c84e041f8e581eb04a041fb410341d152deafb 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 | 3 ++- tests/test_build_gettext.py | 20 ++++++++++++++++++++ 3 files changed, 24 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..0d7d0ac11d 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -57,7 +57,8 @@ 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.