https://github.com/python/cpython/commit/78f75d330a51effc3c3b17c867cb55088beaa891
commit: 78f75d330a51effc3c3b17c867cb55088beaa891
branch: 3.13
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2025-03-13T19:15:28Z
summary:

[3.13] gh-85012: Properly reset msgctxt when compiling messages with msgfmt 
(GH-130525) (GH-131205)

Add also human-readable snapshots for tests.
(cherry picked from commit 7ea6e88eb490635518c63c3305c03baf3e151555)

Co-authored-by: Tomas R <tomas.ro...@gmail.com>

files:
A Lib/test/test_tools/msgfmt_data/fuzzy.json
A Lib/test/test_tools/msgfmt_data/general.json
A Misc/NEWS.d/next/Tools-Demos/2025-02-24-21-36-23.gh-issue-85012.9K1U0E.rst
M Lib/test/test_tools/msgfmt_data/general.mo
M Lib/test/test_tools/test_msgfmt.py
M Tools/i18n/msgfmt.py

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 
<EMAIL@ADDRESS>\nLanguage-Team: LANGUAGE <l...@li.org>\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 bc0683a62d0dda..44b7363071a98b 100644
Binary files a/Lib/test/test_tools/msgfmt_data/general.mo and 
b/Lib/test/test_tools/msgfmt_data/general.mo differ
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()

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to