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

Add also human-readable snapshots for tests.
This commit is contained in:
Tomas R. 2025-03-13 19:40:40 +01:00 committed by GitHub
parent c5abded099
commit 7ea6e88eb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1 @@
[]

View File

@ -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 <LL@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."
]
]

View File

@ -1,5 +1,6 @@
"""Tests for the Tools/i18n/msgfmt.py tool.""" """Tests for the Tools/i18n/msgfmt.py tool."""
import json
import sys import sys
import unittest import unittest
from gettext import GNUTranslations from gettext import GNUTranslations
@ -39,6 +40,28 @@ def test_compilation(self):
self.assertDictEqual(actual._catalog, expected._catalog) 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_po_with_bom(self): def test_po_with_bom(self):
with temp_cwd(): with temp_cwd():
Path('bom.po').write_bytes(b'\xef\xbb\xbfmsgid "Python"\nmsgstr "Pioton"\n') Path('bom.po').write_bytes(b'\xef\xbb\xbfmsgid "Python"\nmsgstr "Pioton"\n')
@ -125,6 +148,16 @@ def update_catalog_snapshots():
for po_file in data_dir.glob('*.po'): for po_file in data_dir.glob('*.po'):
mo_file = po_file.with_suffix('.mo') mo_file = po_file.with_suffix('.mo')
compile_messages(po_file, mo_file) 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__': if __name__ == '__main__':

View File

@ -0,0 +1 @@
Correctly reset ``msgctxt`` when compiling messages in :program:`msgfmt`.

View File

@ -159,6 +159,7 @@ def make(filename, outfile):
elif l.startswith('msgid') and not l.startswith('msgid_plural'): elif l.startswith('msgid') and not l.startswith('msgid_plural'):
if section == STR: if section == STR:
add(msgctxt, msgid, msgstr, fuzzy) add(msgctxt, msgid, msgstr, fuzzy)
msgctxt = None
if not msgid: if not msgid:
# See whether there is an encoding declaration # See whether there is an encoding declaration
p = HeaderParser() p = HeaderParser()