diff --git a/CHANGES b/CHANGES index b56b22d643..36177d28ba 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,8 @@ Bugs fixed ``autodoc_typehints="description"`` * #8180: autodoc: Docstring metadata ignored for attributes * #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.