bpo-2504: Add pgettext() and variants to gettext. (GH-7253)

This commit is contained in:
Cheryl Sabella 2018-11-07 09:12:20 -05:00 committed by Serhiy Storchaka
parent 5598cc90c7
commit 637a33b996
7 changed files with 304 additions and 52 deletions

View file

@ -15,23 +15,27 @@ from test import support
# - Tests should have only one assert.
GNU_MO_DATA = b'''\
3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
3hIElQAAAAAJAAAAHAAAAGQAAAAAAAAArAAAAAAAAACsAAAAFQAAAK0AAAAjAAAAwwAAAKEAAADn
AAAAMAAAAIkBAAAHAAAAugEAABYAAADCAQAAHAAAANkBAAALAAAA9gEAAEIBAAACAgAAFgAAAEUD
AAAeAAAAXAMAAKEAAAB7AwAAMgAAAB0EAAAFAAAAUAQAABsAAABWBAAAIQAAAHIEAAAJAAAAlAQA
AABSYXltb25kIEx1eHVyeSBZYWNoLXQAVGhlcmUgaXMgJXMgZmlsZQBUaGVyZSBhcmUgJXMgZmls
ZXMAVGhpcyBtb2R1bGUgcHJvdmlkZXMgaW50ZXJuYXRpb25hbGl6YXRpb24gYW5kIGxvY2FsaXph
dGlvbgpzdXBwb3J0IGZvciB5b3VyIFB5dGhvbiBwcm9ncmFtcyBieSBwcm92aWRpbmcgYW4gaW50
ZXJmYWNlIHRvIHRoZSBHTlUKZ2V0dGV4dCBtZXNzYWdlIGNhdGFsb2cgbGlicmFyeS4AV2l0aCBj
b250ZXh0BFRoZXJlIGlzICVzIGZpbGUAVGhlcmUgYXJlICVzIGZpbGVzAG11bGx1c2sAbXkgY29u
dGV4dARudWRnZSBudWRnZQBteSBvdGhlciBjb250ZXh0BG51ZGdlIG51ZGdlAG51ZGdlIG51ZGdl
AFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDMtMDQtMTEgMTQ6
MzItMDQwMApMYXN0LVRyYW5zbGF0b3I6IEouIERhdmlkIEliYW5leiA8ai1kYXZpZEBub29zLmZy
PgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246
IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4NTktMQpDb250ZW50
LVRyYW5zZmVyLUVuY29kaW5nOiA4Yml0CkdlbmVyYXRlZC1CeTogcHlnZXR0ZXh0LnB5IDEuMQpQ
bHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0d29iYmxlciBNYW5n
cm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFoeXIgY2ViaXZxcmYg
dmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVnIHNiZSBsYmhlIENs
Z3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1ciBUQUgKdHJnZ3Jr
ZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4ASGF5ICVzIGZpY2hlcm8gKGNvbnRleHQpAEhheSAl
cyBmaWNoZXJvcyAoY29udGV4dCkAYmFjb24Ad2luayB3aW5rIChpbiAibXkgY29udGV4dCIpAHdp
bmsgd2luayAoaW4gIm15IG90aGVyIGNvbnRleHQiKQB3aW5rIHdpbmsA
'''
# This data contains an invalid major version number (5)
@ -84,13 +88,13 @@ ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
UMO_DATA = b'''\
3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
ZC1CeTogbWFudWFsbHkKAMKkeXoA
3hIElQAAAAADAAAAHAAAADQAAAAAAAAAAAAAAAAAAABMAAAABAAAAE0AAAAQAAAAUgAAAA8BAABj
AAAABAAAAHMBAAAWAAAAeAEAAABhYsOeAG15Y29udGV4dMOeBGFiw54AUHJvamVjdC1JZC1WZXJz
aW9uOiAyLjAKUE8tUmV2aXNpb24tRGF0ZTogMjAwMy0wNC0xMSAxMjo0Mi0wNDAwCkxhc3QtVHJh
bnNsYXRvcjogQmFycnkgQS4gV0Fyc2F3IDxiYXJyeUBweXRob24ub3JnPgpMYW5ndWFnZS1UZWFt
OiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5
cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzog
N2JpdApHZW5lcmF0ZWQtQnk6IG1hbnVhbGx5CgDCpHl6AMKkeXogKGNvbnRleHQgdmVyc2lvbikA
'''
MMO_DATA = b'''\
@ -147,7 +151,7 @@ class GettextTestCase1(GettextBaseTest):
GettextBaseTest.setUp(self)
self.localedir = os.curdir
self.mofile = MOFILE
gettext.install('gettext', self.localedir)
gettext.install('gettext', self.localedir, names=['pgettext'])
def test_some_translations(self):
eq = self.assertEqual
@ -157,6 +161,13 @@ class GettextTestCase1(GettextBaseTest):
eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
eq(_(r'nudge nudge'), 'wink wink')
def test_some_translations_with_context(self):
eq = self.assertEqual
eq(pgettext('my context', 'nudge nudge'),
'wink wink (in "my context")')
eq(pgettext('my other context', 'nudge nudge'),
'wink wink (in "my other context")')
def test_double_quotes(self):
eq = self.assertEqual
# double quotes
@ -251,6 +262,20 @@ class GettextTestCase2(GettextBaseTest):
eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
eq(self._(r'nudge nudge'), 'wink wink')
def test_some_translations_with_context(self):
eq = self.assertEqual
eq(gettext.pgettext('my context', 'nudge nudge'),
'wink wink (in "my context")')
eq(gettext.pgettext('my other context', 'nudge nudge'),
'wink wink (in "my other context")')
def test_some_translations_with_context_and_domain(self):
eq = self.assertEqual
eq(gettext.dpgettext('gettext', 'my context', 'nudge nudge'),
'wink wink (in "my context")')
eq(gettext.dpgettext('gettext', 'my other context', 'nudge nudge'),
'wink wink (in "my other context")')
def test_double_quotes(self):
eq = self.assertEqual
# double quotes
@ -298,6 +323,15 @@ class PluralFormsTestCase(GettextBaseTest):
x = gettext.ngettext('There is %s file', 'There are %s files', 2)
eq(x, 'Hay %s ficheros')
def test_plural_context_forms1(self):
eq = self.assertEqual
x = gettext.npgettext('With context',
'There is %s file', 'There are %s files', 1)
eq(x, 'Hay %s fichero (context)')
x = gettext.npgettext('With context',
'There is %s file', 'There are %s files', 2)
eq(x, 'Hay %s ficheros (context)')
def test_plural_forms2(self):
eq = self.assertEqual
with open(self.mofile, 'rb') as fp:
@ -307,6 +341,17 @@ class PluralFormsTestCase(GettextBaseTest):
x = t.ngettext('There is %s file', 'There are %s files', 2)
eq(x, 'Hay %s ficheros')
def test_plural_context_forms2(self):
eq = self.assertEqual
with open(self.mofile, 'rb') as fp:
t = gettext.GNUTranslations(fp)
x = t.npgettext('With context',
'There is %s file', 'There are %s files', 1)
eq(x, 'Hay %s fichero (context)')
x = t.npgettext('With context',
'There is %s file', 'There are %s files', 2)
eq(x, 'Hay %s ficheros (context)')
# Examples from http://www.gnu.org/software/gettext/manual/gettext.html
def test_ja(self):
@ -646,6 +691,7 @@ class UnicodeTranslationsTest(GettextBaseTest):
with open(UMOFILE, 'rb') as fp:
self.t = gettext.GNUTranslations(fp)
self._ = self.t.gettext
self.pgettext = self.t.pgettext
def test_unicode_msgid(self):
self.assertIsInstance(self._(''), str)
@ -653,6 +699,53 @@ class UnicodeTranslationsTest(GettextBaseTest):
def test_unicode_msgstr(self):
self.assertEqual(self._('ab\xde'), '\xa4yz')
def test_unicode_context_msgstr(self):
t = self.pgettext('mycontext\xde', 'ab\xde')
self.assertTrue(isinstance(t, str))
self.assertEqual(t, '\xa4yz (context version)')
class UnicodeTranslationsPluralTest(GettextBaseTest):
def setUp(self):
GettextBaseTest.setUp(self)
with open(MOFILE, 'rb') as fp:
self.t = gettext.GNUTranslations(fp)
self.ngettext = self.t.ngettext
self.npgettext = self.t.npgettext
def test_unicode_msgid(self):
unless = self.assertTrue
unless(isinstance(self.ngettext('', '', 1), str))
unless(isinstance(self.ngettext('', '', 2), str))
def test_unicode_context_msgid(self):
unless = self.assertTrue
unless(isinstance(self.npgettext('', '', '', 1), str))
unless(isinstance(self.npgettext('', '', '', 2), str))
def test_unicode_msgstr(self):
eq = self.assertEqual
unless = self.assertTrue
t = self.ngettext("There is %s file", "There are %s files", 1)
unless(isinstance(t, str))
eq(t, "Hay %s fichero")
unless(isinstance(t, str))
t = self.ngettext("There is %s file", "There are %s files", 5)
unless(isinstance(t, str))
eq(t, "Hay %s ficheros")
def test_unicode_msgstr_with_context(self):
eq = self.assertEqual
unless = self.assertTrue
t = self.npgettext("With context",
"There is %s file", "There are %s files", 1)
unless(isinstance(t, str))
eq(t, "Hay %s fichero (context)")
t = self.npgettext("With context",
"There is %s file", "There are %s files", 5)
unless(isinstance(t, str))
eq(t, "Hay %s ficheros (context)")
class WeirdMetadataTest(GettextBaseTest):
def setUp(self):
@ -750,6 +843,14 @@ msgstr ""
msgid "nudge nudge"
msgstr "wink wink"
msgctxt "my context"
msgid "nudge nudge"
msgstr "wink wink (in \"my context\")"
msgctxt "my other context"
msgid "nudge nudge"
msgstr "wink wink (in \"my other context\")"
#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
msgid "albatross"
@ -782,6 +883,14 @@ msgid "There is %s file"
msgid_plural "There are %s files"
msgstr[0] "Hay %s fichero"
msgstr[1] "Hay %s ficheros"
# Manually added, as neither pygettext nor xgettext support plural forms
# and context in Python.
msgctxt "With context"
msgid "There is %s file"
msgid_plural "There are %s files"
msgstr[0] "Hay %s fichero (context)"
msgstr[1] "Hay %s ficheros (context)"
'''
# Here's the second example po file example, used to generate the UMO_DATA
@ -806,6 +915,11 @@ msgstr ""
#: nofile:0
msgid "ab\xc3\x9e"
msgstr "\xc2\xa4yz"
#: nofile:1
msgctxt "mycontext\xc3\x9e"
msgid "ab\xc3\x9e"
msgstr "\xc2\xa4yz (context version)"
'''
# Here's the third example po file, used to generate MMO_DATA