From f3bcce8b3ce0fa671e7e029e1cf9a17f9a9c27d9 Mon Sep 17 00:00:00 2001 From: Tomas R Date: Thu, 13 Mar 2025 19:40:40 +0100 Subject: [PATCH] [3.13] gh-85012: Properly reset msgctxt when compiling messages with msgfmt (GH-130525) Add also human-readable snapshots for tests. (cherry picked from commit 7ea6e88eb490635518c63c3305c03baf3e151555) Co-authored-by: Tomas R. --- Lib/test/test_tools/msgfmt_data/fuzzy.json | 1 + Lib/test/test_tools/msgfmt_data/general.json | 58 ++++++++++++++++++ Lib/test/test_tools/msgfmt_data/general.mo | Bin 728 -> 712 bytes Lib/test/test_tools/test_msgfmt.py | 33 ++++++++++ ...5-02-24-21-36-23.gh-issue-85012.9K1U0E.rst | 1 + Tools/i18n/msgfmt.py | 1 + 6 files changed, 94 insertions(+) create mode 100644 Lib/test/test_tools/msgfmt_data/fuzzy.json create mode 100644 Lib/test/test_tools/msgfmt_data/general.json create mode 100644 Misc/NEWS.d/next/Tools-Demos/2025-02-24-21-36-23.gh-issue-85012.9K1U0E.rst diff --git a/Lib/test/test_tools/msgfmt_data/fuzzy.json b/Lib/test/test_tools/msgfmt_data/fuzzy.json new file mode 100644 index 00000000000000..fe51488c7066f6 --- /dev/null +++ b/Lib/test/test_tools/msgfmt_data/fuzzy.json @@ -0,0 +1 @@ +[] diff --git a/Lib/test/test_tools/msgfmt_data/general.json b/Lib/test/test_tools/msgfmt_data/general.json new file mode 100644 index 00000000000000..8ceb34cd17fb07 --- /dev/null +++ b/Lib/test/test_tools/msgfmt_data/general.json @@ -0,0 +1,58 @@ +[ + [ + "", + "Project-Id-Version: PACKAGE VERSION\nPOT-Creation-Date: 2024-10-26 18:06+0200\nPO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\nLast-Translator: FULL NAME \nLanguage-Team: LANGUAGE \nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\n" + ], + [ + "\n newlines \n", + "\n translated \n" + ], + [ + "\"escapes\"", + "\"translated\"" + ], + [ + "Multilinestring", + "Multilinetranslation" + ], + [ + "abc\u0004foo", + "bar" + ], + [ + "bar", + "baz" + ], + [ + "xyz\u0004foo", + "bar" + ], + [ + [ + "One email sent.", + 0 + ], + "One email sent." + ], + [ + [ + "One email sent.", + 1 + ], + "%d emails sent." + ], + [ + [ + "abc\u0004One email sent.", + 0 + ], + "One email sent." + ], + [ + [ + "abc\u0004One email sent.", + 1 + ], + "%d emails sent." + ] +] diff --git a/Lib/test/test_tools/msgfmt_data/general.mo b/Lib/test/test_tools/msgfmt_data/general.mo index bc0683a62d0ddaecbc751b9a59eb1fe19bb7619c..44b7363071a98bfe61eadc6adb0b434f1fd36125 100644 GIT binary patch delta 215 zcmcb?dV+O=N<9w)1H)P%<^wU}Rum2GR;Z8pKxt z(sDqo1H^nlzBdyC1IWB6AT0u<(}6U|oEj)S2S|hT?}5?>m>3Mf0!M%X3|tC%spUDD zd8x$;TntL7#mR{Usl`eRzNI-OnPB0PqRhN>hKUO1&}z1H)P%W(VSnK+FupH-T6Hi0=Y1FA%>2VqqZu1H>Tp0*ny#CO}#a zh;4va9w;8o1kqm&rR#w-A5gp*Nb>;cNkCczNY4k-AoW|AfYKlfuK)!Y5|ffyCf6`2 zOqO62Fy>OoOD)gI%u6j+;9{t#tYT40Ely4>NG(0mLC-pwkE U>Wq`;FlkKoW(s6UN-Sak05L!){{R30 diff --git a/Lib/test/test_tools/test_msgfmt.py b/Lib/test/test_tools/test_msgfmt.py index e3e3035c4f4395..8cd31680f76424 100644 --- a/Lib/test/test_tools/test_msgfmt.py +++ b/Lib/test/test_tools/test_msgfmt.py @@ -1,5 +1,6 @@ """Tests for the Tools/i18n/msgfmt.py tool.""" +import json import sys import unittest from gettext import GNUTranslations @@ -39,6 +40,28 @@ def test_compilation(self): self.assertDictEqual(actual._catalog, expected._catalog) + def test_translations(self): + with open(data_dir / 'general.mo', 'rb') as f: + t = GNUTranslations(f) + + self.assertEqual(t.gettext('foo'), 'foo') + self.assertEqual(t.gettext('bar'), 'baz') + self.assertEqual(t.pgettext('abc', 'foo'), 'bar') + self.assertEqual(t.pgettext('xyz', 'foo'), 'bar') + self.assertEqual(t.gettext('Multilinestring'), 'Multilinetranslation') + self.assertEqual(t.gettext('"escapes"'), '"translated"') + self.assertEqual(t.gettext('\n newlines \n'), '\n translated \n') + self.assertEqual(t.ngettext('One email sent.', '%d emails sent.', 1), + 'One email sent.') + self.assertEqual(t.ngettext('One email sent.', '%d emails sent.', 2), + '%d emails sent.') + self.assertEqual(t.npgettext('abc', 'One email sent.', + '%d emails sent.', 1), + 'One email sent.') + self.assertEqual(t.npgettext('abc', 'One email sent.', + '%d emails sent.', 2), + '%d emails sent.') + def test_invalid_msgid_plural(self): with temp_cwd(): Path('invalid.po').write_text('''\ @@ -117,6 +140,16 @@ def update_catalog_snapshots(): for po_file in data_dir.glob('*.po'): mo_file = po_file.with_suffix('.mo') compile_messages(po_file, mo_file) + # Create a human-readable JSON file which is + # easier to review than the binary .mo file. + with open(mo_file, 'rb') as f: + translations = GNUTranslations(f) + catalog_file = po_file.with_suffix('.json') + with open(catalog_file, 'w') as f: + data = translations._catalog.items() + data = sorted(data, key=lambda x: (isinstance(x[0], tuple), x[0])) + json.dump(data, f, indent=4) + f.write('\n') if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/Tools-Demos/2025-02-24-21-36-23.gh-issue-85012.9K1U0E.rst b/Misc/NEWS.d/next/Tools-Demos/2025-02-24-21-36-23.gh-issue-85012.9K1U0E.rst new file mode 100644 index 00000000000000..5ec20583527367 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2025-02-24-21-36-23.gh-issue-85012.9K1U0E.rst @@ -0,0 +1 @@ +Correctly reset ``msgctxt`` when compiling messages in :program:`msgfmt`. diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py index 3f731e941eafe7..c0da976979848a 100755 --- a/Tools/i18n/msgfmt.py +++ b/Tools/i18n/msgfmt.py @@ -149,6 +149,7 @@ def make(filename, outfile): elif l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgctxt, msgid, msgstr, fuzzy) + msgctxt = None if not msgid: # See whether there is an encoding declaration p = HeaderParser()