blob: baf300b057249578032d40c8d9bab33a1edfc56f [file] [log] [blame]
Barry Warsaw9e035922000-08-25 19:14:25 +00001import os
Barry Warsawff6d8132000-08-25 19:50:38 +00002import base64
Serhiy Storchakafec35c92018-10-27 08:00:41 +03003import contextlib
Barry Warsaw9e035922000-08-25 19:14:25 +00004import gettext
Martin v. Löwisd8996052002-11-21 21:45:32 +00005import unittest
Barry Warsawa1ce93f2003-04-11 18:36:43 +00006
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Barry Warsawa1ce93f2003-04-11 18:36:43 +00008
Fred Drake004d5e62000-10-23 17:22:08 +00009
Martin v. Löwisd8996052002-11-21 21:45:32 +000010# TODO:
11# - Add new tests, for example for "dgettext"
12# - Remove dummy tests, for example testing for single and double quotes
13# has no sense, it would have if we were testing a parser (i.e. pygettext)
14# - Tests should have only one assert.
Barry Warsaw64dab462000-08-30 03:32:07 +000015
Guido van Rossum39478e82007-08-27 17:23:59 +000016GNU_MO_DATA = b'''\
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500173hIElQAAAAAJAAAAHAAAAGQAAAAAAAAArAAAAAAAAACsAAAAFQAAAK0AAAAjAAAAwwAAAKEAAADn
18AAAAMAAAAIkBAAAHAAAAugEAABYAAADCAQAAHAAAANkBAAALAAAA9gEAAEIBAAACAgAAFgAAAEUD
19AAAeAAAAXAMAAKEAAAB7AwAAMgAAAB0EAAAFAAAAUAQAABsAAABWBAAAIQAAAHIEAAAJAAAAlAQA
20AABSYXltb25kIEx1eHVyeSBZYWNoLXQAVGhlcmUgaXMgJXMgZmlsZQBUaGVyZSBhcmUgJXMgZmls
21ZXMAVGhpcyBtb2R1bGUgcHJvdmlkZXMgaW50ZXJuYXRpb25hbGl6YXRpb24gYW5kIGxvY2FsaXph
22dGlvbgpzdXBwb3J0IGZvciB5b3VyIFB5dGhvbiBwcm9ncmFtcyBieSBwcm92aWRpbmcgYW4gaW50
23ZXJmYWNlIHRvIHRoZSBHTlUKZ2V0dGV4dCBtZXNzYWdlIGNhdGFsb2cgbGlicmFyeS4AV2l0aCBj
24b250ZXh0BFRoZXJlIGlzICVzIGZpbGUAVGhlcmUgYXJlICVzIGZpbGVzAG11bGx1c2sAbXkgY29u
25dGV4dARudWRnZSBudWRnZQBteSBvdGhlciBjb250ZXh0BG51ZGdlIG51ZGdlAG51ZGdlIG51ZGdl
26AFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDMtMDQtMTEgMTQ6
27MzItMDQwMApMYXN0LVRyYW5zbGF0b3I6IEouIERhdmlkIEliYW5leiA8ai1kYXZpZEBub29zLmZy
28PgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246
29IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4NTktMQpDb250ZW50
30LVRyYW5zZmVyLUVuY29kaW5nOiA4Yml0CkdlbmVyYXRlZC1CeTogcHlnZXR0ZXh0LnB5IDEuMQpQ
31bHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0d29iYmxlciBNYW5n
32cm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFoeXIgY2ViaXZxcmYg
33dmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVnIHNiZSBsYmhlIENs
34Z3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1ciBUQUgKdHJnZ3Jr
35ZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4ASGF5ICVzIGZpY2hlcm8gKGNvbnRleHQpAEhheSAl
36cyBmaWNoZXJvcyAoY29udGV4dCkAYmFjb24Ad2luayB3aW5rIChpbiAibXkgY29udGV4dCIpAHdp
37bmsgd2luayAoaW4gIm15IG90aGVyIGNvbnRleHQiKQB3aW5rIHdpbmsA
Barry Warsawff6d8132000-08-25 19:50:38 +000038'''
39
Antoine Pitroube8d06f2014-10-28 20:17:51 +010040# This data contains an invalid major version number (5)
41# An unexpected major version number should be treated as an error when
42# parsing a .mo file
43
44GNU_MO_DATA_BAD_MAJOR_VERSION = b'''\
453hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
46AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
47AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
48eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
49aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
50CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
51Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
52ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
53MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
54YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
55SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
56NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
57ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
58d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
59eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
60IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
61ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
62'''
63
64# This data contains an invalid minor version number (7)
65# An unexpected minor version number only indicates that some of the file's
66# contents may not be able to be read. It does not indicate an error.
67
68GNU_MO_DATA_BAD_MINOR_VERSION = b'''\
693hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
70AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
71AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
72eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
73aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
74CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
75Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
76ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
77MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
78YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
79SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
80NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
81ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
82d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
83eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
84IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
85ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
86'''
87
88
Guido van Rossum39478e82007-08-27 17:23:59 +000089UMO_DATA = b'''\
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500903hIElQAAAAADAAAAHAAAADQAAAAAAAAAAAAAAAAAAABMAAAABAAAAE0AAAAQAAAAUgAAAA8BAABj
91AAAABAAAAHMBAAAWAAAAeAEAAABhYsOeAG15Y29udGV4dMOeBGFiw54AUHJvamVjdC1JZC1WZXJz
92aW9uOiAyLjAKUE8tUmV2aXNpb24tRGF0ZTogMjAwMy0wNC0xMSAxMjo0Mi0wNDAwCkxhc3QtVHJh
93bnNsYXRvcjogQmFycnkgQS4gV0Fyc2F3IDxiYXJyeUBweXRob24ub3JnPgpMYW5ndWFnZS1UZWFt
94OiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5
95cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzog
96N2JpdApHZW5lcmF0ZWQtQnk6IG1hbnVhbGx5CgDCpHl6AMKkeXogKGNvbnRleHQgdmVyc2lvbikA
Barry Warsawa1ce93f2003-04-11 18:36:43 +000097'''
Fred Drake004d5e62000-10-23 17:22:08 +000098
Guido van Rossum39478e82007-08-27 17:23:59 +000099MMO_DATA = b'''\
Barry Warsawe960e222003-05-20 17:28:54 +00001003hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
101UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
102IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
103NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
104ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
105cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
106c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
107bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
108'''
109
Barry Warsawff6d8132000-08-25 19:50:38 +0000110LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
111MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100112MOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo')
113MOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000114UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
Barry Warsawe960e222003-05-20 17:28:54 +0000115MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
Barry Warsawff6d8132000-08-25 19:50:38 +0000116
117
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000118class GettextBaseTest(unittest.TestCase):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000119 def setUp(self):
Neal Norwitza0e0cd32004-07-19 00:08:59 +0000120 if not os.path.isdir(LOCALEDIR):
121 os.makedirs(LOCALEDIR)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000122 with open(MOFILE, 'wb') as fp:
123 fp.write(base64.decodebytes(GNU_MO_DATA))
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100124 with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp:
125 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION))
126 with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp:
127 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION))
Éric Araujo7fa886d2010-11-06 04:11:59 +0000128 with open(UMOFILE, 'wb') as fp:
129 fp.write(base64.decodebytes(UMO_DATA))
130 with open(MMOFILE, 'wb') as fp:
131 fp.write(base64.decodebytes(MMO_DATA))
Walter Dörwald155374d2009-05-01 19:58:58 +0000132 self.env = support.EnvironmentVarGuard()
133 self.env['LANGUAGE'] = 'xx'
Éric Araujo37a89332010-11-06 04:09:29 +0000134 gettext._translations.clear()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000135
136 def tearDown(self):
Walter Dörwald155374d2009-05-01 19:58:58 +0000137 self.env.__exit__()
138 del self.env
Victor Stinnercdb2c602014-07-24 12:07:45 +0200139 support.rmtree(os.path.split(LOCALEDIR)[0])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000140
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400141GNU_MO_DATA_ISSUE_17898 = b'''\
1423hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z
143OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk
144WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU
145Ri04CgA=
146'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000147
148class GettextTestCase1(GettextBaseTest):
149 def setUp(self):
150 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000151 self.localedir = os.curdir
152 self.mofile = MOFILE
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500153 gettext.install('gettext', self.localedir, names=['pgettext'])
Martin v. Löwisd8996052002-11-21 21:45:32 +0000154
Martin v. Löwisd8996052002-11-21 21:45:32 +0000155 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000156 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000157 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000158 eq(_('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000159 eq(_('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000160 eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000161 eq(_(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000162
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500163 def test_some_translations_with_context(self):
164 eq = self.assertEqual
165 eq(pgettext('my context', 'nudge nudge'),
166 'wink wink (in "my context")')
167 eq(pgettext('my other context', 'nudge nudge'),
168 'wink wink (in "my other context")')
169
Martin v. Löwisd8996052002-11-21 21:45:32 +0000170 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000171 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000172 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000173 eq(_("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000174 eq(_("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000175 eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000176 eq(_(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000177
178 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000179 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000180 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000181 eq(_('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000182 eq(_('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000183 eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000184 eq(_(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000185
186 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000187 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000188 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000189 eq(_("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000190 eq(_("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000191 eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000192 eq(_(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000193
194 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000195 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000196 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000197 eq(_('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000198support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000199gettext message catalog library.'''),
200 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000201fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000202trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000203
204 def test_the_alternative_interface(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000205 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000206 # test the alternative interface
Éric Araujo7fa886d2010-11-06 04:11:59 +0000207 with open(self.mofile, 'rb') as fp:
208 t = gettext.GNUTranslations(fp)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000209 # Install the translation object
Martin v. Löwisd8996052002-11-21 21:45:32 +0000210 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000211 eq(_('nudge nudge'), 'wink wink')
212 # Try unicode return type
Benjamin Peterson801844d2008-07-14 14:32:15 +0000213 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000214 eq(_('mullusk'), 'bacon')
Georg Brandl602b9ba2006-02-19 13:26:36 +0000215 # Test installation of other methods
Georg Brandl1a3284e2007-12-02 09:40:06 +0000216 import builtins
Benjamin Peterson801844d2008-07-14 14:32:15 +0000217 t.install(names=["gettext", "lgettext"])
218 eq(_, t.gettext)
219 eq(builtins.gettext, t.gettext)
Georg Brandl602b9ba2006-02-19 13:26:36 +0000220 eq(lgettext, t.lgettext)
Georg Brandl1a3284e2007-12-02 09:40:06 +0000221 del builtins.gettext
222 del builtins.lgettext
Martin v. Löwisd8996052002-11-21 21:45:32 +0000223
224
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000225class GettextTestCase2(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000226 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000227 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000228 self.localedir = os.curdir
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000229 # Set up the bindings
Martin v. Löwisd8996052002-11-21 21:45:32 +0000230 gettext.bindtextdomain('gettext', self.localedir)
231 gettext.textdomain('gettext')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000232 # For convenience
Martin v. Löwisd8996052002-11-21 21:45:32 +0000233 self._ = gettext.gettext
234
Martin v. Löwisd8996052002-11-21 21:45:32 +0000235 def test_bindtextdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000236 self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000237
238 def test_textdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000239 self.assertEqual(gettext.textdomain(), 'gettext')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000240
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100241 def test_bad_major_version(self):
242 with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp:
243 with self.assertRaises(OSError) as cm:
244 gettext.GNUTranslations(fp)
245
246 exception = cm.exception
247 self.assertEqual(exception.errno, 0)
248 self.assertEqual(exception.strerror, "Bad version number 5")
249 self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION)
250
251 def test_bad_minor_version(self):
252 with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp:
253 # Check that no error is thrown with a bad minor version number
254 gettext.GNUTranslations(fp)
255
Martin v. Löwisd8996052002-11-21 21:45:32 +0000256 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000257 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000258 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000259 eq(self._('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000260 eq(self._('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000261 eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000262 eq(self._(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000263
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500264 def test_some_translations_with_context(self):
265 eq = self.assertEqual
266 eq(gettext.pgettext('my context', 'nudge nudge'),
267 'wink wink (in "my context")')
268 eq(gettext.pgettext('my other context', 'nudge nudge'),
269 'wink wink (in "my other context")')
270
271 def test_some_translations_with_context_and_domain(self):
272 eq = self.assertEqual
273 eq(gettext.dpgettext('gettext', 'my context', 'nudge nudge'),
274 'wink wink (in "my context")')
275 eq(gettext.dpgettext('gettext', 'my other context', 'nudge nudge'),
276 'wink wink (in "my other context")')
277
Martin v. Löwisd8996052002-11-21 21:45:32 +0000278 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000279 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000280 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000281 eq(self._("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000282 eq(self._("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000283 eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000284 eq(self._(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000285
286 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000287 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000288 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000289 eq(self._('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000290 eq(self._('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000291 eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000292 eq(self._(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000293
294 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000295 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000296 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000297 eq(self._("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000298 eq(self._("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000299 eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000300 eq(self._(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000301
302 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000303 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000304 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000305 eq(self._('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000306support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000307gettext message catalog library.'''),
308 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000309fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000310trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000311
312
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000313class PluralFormsTestCase(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000314 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000315 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000316 self.mofile = MOFILE
317
318 def test_plural_forms1(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000319 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000320 x = gettext.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000321 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000322 x = gettext.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000323 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000324
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500325 def test_plural_context_forms1(self):
326 eq = self.assertEqual
327 x = gettext.npgettext('With context',
328 'There is %s file', 'There are %s files', 1)
329 eq(x, 'Hay %s fichero (context)')
330 x = gettext.npgettext('With context',
331 'There is %s file', 'There are %s files', 2)
332 eq(x, 'Hay %s ficheros (context)')
333
Martin v. Löwisd8996052002-11-21 21:45:32 +0000334 def test_plural_forms2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000335 eq = self.assertEqual
Éric Araujo7fa886d2010-11-06 04:11:59 +0000336 with open(self.mofile, 'rb') as fp:
337 t = gettext.GNUTranslations(fp)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000338 x = t.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000339 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000340 x = t.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000341 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000342
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500343 def test_plural_context_forms2(self):
344 eq = self.assertEqual
345 with open(self.mofile, 'rb') as fp:
346 t = gettext.GNUTranslations(fp)
347 x = t.npgettext('With context',
348 'There is %s file', 'There are %s files', 1)
349 eq(x, 'Hay %s fichero (context)')
350 x = t.npgettext('With context',
351 'There is %s file', 'There are %s files', 2)
352 eq(x, 'Hay %s ficheros (context)')
353
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200354 # Examples from http://www.gnu.org/software/gettext/manual/gettext.html
355
356 def test_ja(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000357 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000358 f = gettext.c2py('0')
359 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000360 eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000361
362 def test_de(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000363 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000364 f = gettext.c2py('n != 1')
365 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000366 eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000367
368 def test_fr(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000369 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000370 f = gettext.c2py('n>1')
371 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000372 eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000373
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200374 def test_lv(self):
375 eq = self.assertEqual
376 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2')
377 s = ''.join([ str(f(x)) for x in range(200) ])
378 eq(s, "20111111111111111111101111111110111111111011111111101111111110111111111011111111101111111110111111111011111111111111111110111111111011111111101111111110111111111011111111101111111110111111111011111111")
379
Martin v. Löwisd8996052002-11-21 21:45:32 +0000380 def test_gd(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000381 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000382 f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
383 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000384 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000385
386 def test_gd2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000387 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000388 # Tests the combination of parentheses and "?:"
389 f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
390 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000391 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000392
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200393 def test_ro(self):
394 eq = self.assertEqual
395 f = gettext.c2py('n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2')
396 s = ''.join([ str(f(x)) for x in range(200) ])
397 eq(s, "10111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222")
398
Martin v. Löwisd8996052002-11-21 21:45:32 +0000399 def test_lt(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000400 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000401 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
402 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000403 eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000404
405 def test_ru(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000406 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000407 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
408 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000409 eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000410
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200411 def test_cs(self):
412 eq = self.assertEqual
413 f = gettext.c2py('(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2')
414 s = ''.join([ str(f(x)) for x in range(200) ])
415 eq(s, "20111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
416
Martin v. Löwisd8996052002-11-21 21:45:32 +0000417 def test_pl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000418 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000419 f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
420 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000421 eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000422
423 def test_sl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000424 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000425 f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
426 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000427 eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000428
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200429 def test_ar(self):
430 eq = self.assertEqual
431 f = gettext.c2py('n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5')
432 s = ''.join([ str(f(x)) for x in range(200) ])
433 eq(s, "01233333333444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445553333333344444444444444444444444444444444444444444444444444444444444444444444444444444444444444444")
434
Martin v. Löwisd8996052002-11-21 21:45:32 +0000435 def test_security(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000436 raises = self.assertRaises
Martin v. Löwisd8996052002-11-21 21:45:32 +0000437 # Test for a dangerous expression
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000438 raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200439 # issue28563
440 raises(ValueError, gettext.c2py, '"(eval(foo) && ""')
441 raises(ValueError, gettext.c2py, 'f"{os.system(\'sh\')}"')
442 # Maximum recursion depth exceeded during compilation
443 raises(ValueError, gettext.c2py, 'n+'*10000 + 'n')
444 self.assertEqual(gettext.c2py('n+'*100 + 'n')(1), 101)
445 # MemoryError during compilation
446 raises(ValueError, gettext.c2py, '('*100 + 'n' + ')'*100)
447 # Maximum recursion depth exceeded in C to Python translator
448 raises(ValueError, gettext.c2py, '('*10000 + 'n' + ')'*10000)
449 self.assertEqual(gettext.c2py('('*20 + 'n' + ')'*20)(1), 1)
450
451 def test_chained_comparison(self):
452 # C doesn't chain comparison as Python so 2 == 2 == 2 gets different results
453 f = gettext.c2py('n == n == n')
454 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
455 f = gettext.c2py('1 < n == n')
456 self.assertEqual(''.join(str(f(x)) for x in range(3)), '100')
457 f = gettext.c2py('n == n < 2')
458 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
459 f = gettext.c2py('0 < n < 2')
460 self.assertEqual(''.join(str(f(x)) for x in range(3)), '111')
461
462 def test_decimal_number(self):
463 self.assertEqual(gettext.c2py('0123')(1), 123)
464
465 def test_invalid_syntax(self):
466 invalid_expressions = [
467 'x>1', '(n>1', 'n>1)', '42**42**42', '0xa', '1.0', '1e2',
468 'n>0x1', '+n', '-n', 'n()', 'n(1)', '1+', 'nn', 'n n',
469 ]
470 for expr in invalid_expressions:
471 with self.assertRaises(ValueError):
472 gettext.c2py(expr)
473
474 def test_nested_condition_operator(self):
475 self.assertEqual(gettext.c2py('n?1?2:3:4')(0), 4)
476 self.assertEqual(gettext.c2py('n?1?2:3:4')(1), 2)
477 self.assertEqual(gettext.c2py('n?1:3?4:5')(0), 4)
478 self.assertEqual(gettext.c2py('n?1:3?4:5')(1), 1)
479
480 def test_division(self):
481 f = gettext.c2py('2/n*3')
482 self.assertEqual(f(1), 6)
483 self.assertEqual(f(2), 3)
484 self.assertEqual(f(3), 0)
485 self.assertEqual(f(-1), -6)
486 self.assertRaises(ZeroDivisionError, f, 0)
487
488 def test_plural_number(self):
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200489 f = gettext.c2py('n != 1')
490 self.assertEqual(f(1), 0)
491 self.assertEqual(f(2), 1)
Serhiy Storchakaf6595982017-03-12 13:15:01 +0200492 with self.assertWarns(DeprecationWarning):
493 self.assertEqual(f(1.0), 0)
494 with self.assertWarns(DeprecationWarning):
495 self.assertEqual(f(2.0), 1)
496 with self.assertWarns(DeprecationWarning):
497 self.assertEqual(f(1.1), 1)
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200498 self.assertRaises(TypeError, f, '2')
499 self.assertRaises(TypeError, f, b'2')
500 self.assertRaises(TypeError, f, [])
501 self.assertRaises(TypeError, f, object())
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200502
Martin v. Löwisd8996052002-11-21 21:45:32 +0000503
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300504class LGettextTestCase(GettextBaseTest):
505 def setUp(self):
506 GettextBaseTest.setUp(self)
507 self.mofile = MOFILE
508
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300509 @contextlib.contextmanager
510 def assertDeprecated(self, name):
511 with self.assertWarnsRegex(DeprecationWarning,
512 fr'^{name}\(\) is deprecated'):
513 yield
514
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300515 def test_lgettext(self):
516 lgettext = gettext.lgettext
517 ldgettext = gettext.ldgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300518 with self.assertDeprecated('lgettext'):
519 self.assertEqual(lgettext('mullusk'), b'bacon')
520 with self.assertDeprecated('lgettext'):
521 self.assertEqual(lgettext('spam'), b'spam')
522 with self.assertDeprecated('ldgettext'):
523 self.assertEqual(ldgettext('gettext', 'mullusk'), b'bacon')
524 with self.assertDeprecated('ldgettext'):
525 self.assertEqual(ldgettext('gettext', 'spam'), b'spam')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300526
527 def test_lgettext_2(self):
528 with open(self.mofile, 'rb') as fp:
529 t = gettext.GNUTranslations(fp)
530 lgettext = t.lgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300531 with self.assertDeprecated('lgettext'):
532 self.assertEqual(lgettext('mullusk'), b'bacon')
533 with self.assertDeprecated('lgettext'):
534 self.assertEqual(lgettext('spam'), b'spam')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300535
536 def test_lgettext_bind_textdomain_codeset(self):
537 lgettext = gettext.lgettext
538 ldgettext = gettext.ldgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300539 with self.assertDeprecated('bind_textdomain_codeset'):
540 saved_codeset = gettext.bind_textdomain_codeset('gettext')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300541 try:
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300542 with self.assertDeprecated('bind_textdomain_codeset'):
543 gettext.bind_textdomain_codeset('gettext', 'utf-16')
544 with self.assertDeprecated('lgettext'):
545 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
546 with self.assertDeprecated('lgettext'):
547 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
548 with self.assertDeprecated('ldgettext'):
549 self.assertEqual(ldgettext('gettext', 'mullusk'), 'bacon'.encode('utf-16'))
550 with self.assertDeprecated('ldgettext'):
551 self.assertEqual(ldgettext('gettext', 'spam'), 'spam'.encode('utf-16'))
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300552 finally:
553 del gettext._localecodesets['gettext']
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300554 with self.assertDeprecated('bind_textdomain_codeset'):
555 gettext.bind_textdomain_codeset('gettext', saved_codeset)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300556
557 def test_lgettext_output_encoding(self):
558 with open(self.mofile, 'rb') as fp:
559 t = gettext.GNUTranslations(fp)
560 lgettext = t.lgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300561 with self.assertDeprecated('set_output_charset'):
562 t.set_output_charset('utf-16')
563 with self.assertDeprecated('lgettext'):
564 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
565 with self.assertDeprecated('lgettext'):
566 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300567
568 def test_lngettext(self):
569 lngettext = gettext.lngettext
570 ldngettext = gettext.ldngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300571 with self.assertDeprecated('lngettext'):
572 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300573 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300574 with self.assertDeprecated('lngettext'):
575 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300576 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300577 with self.assertDeprecated('lngettext'):
578 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300579 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300580 with self.assertDeprecated('lngettext'):
581 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300582 self.assertEqual(x, b'There are %s directories')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300583 with self.assertDeprecated('ldngettext'):
584 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300585 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300586 with self.assertDeprecated('ldngettext'):
587 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300588 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300589 with self.assertDeprecated('ldngettext'):
590 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300591 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300592 with self.assertDeprecated('ldngettext'):
593 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300594 self.assertEqual(x, b'There are %s directories')
595
596 def test_lngettext_2(self):
597 with open(self.mofile, 'rb') as fp:
598 t = gettext.GNUTranslations(fp)
599 lngettext = t.lngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300600 with self.assertDeprecated('lngettext'):
601 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300602 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300603 with self.assertDeprecated('lngettext'):
604 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300605 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300606 with self.assertDeprecated('lngettext'):
607 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300608 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300609 with self.assertDeprecated('lngettext'):
610 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300611 self.assertEqual(x, b'There are %s directories')
612
613 def test_lngettext_bind_textdomain_codeset(self):
614 lngettext = gettext.lngettext
615 ldngettext = gettext.ldngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300616 with self.assertDeprecated('bind_textdomain_codeset'):
617 saved_codeset = gettext.bind_textdomain_codeset('gettext')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300618 try:
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300619 with self.assertDeprecated('bind_textdomain_codeset'):
620 gettext.bind_textdomain_codeset('gettext', 'utf-16')
621 with self.assertDeprecated('lngettext'):
622 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300623 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300624 with self.assertDeprecated('lngettext'):
625 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300626 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300627 with self.assertDeprecated('lngettext'):
628 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300629 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300630 with self.assertDeprecated('lngettext'):
631 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300632 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300633 with self.assertDeprecated('ldngettext'):
634 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300635 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300636 with self.assertDeprecated('ldngettext'):
637 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300638 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300639 with self.assertDeprecated('ldngettext'):
640 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300641 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300642 with self.assertDeprecated('ldngettext'):
643 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300644 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
645 finally:
646 del gettext._localecodesets['gettext']
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300647 with self.assertDeprecated('bind_textdomain_codeset'):
648 gettext.bind_textdomain_codeset('gettext', saved_codeset)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300649
650 def test_lngettext_output_encoding(self):
651 with open(self.mofile, 'rb') as fp:
652 t = gettext.GNUTranslations(fp)
653 lngettext = t.lngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300654 with self.assertDeprecated('set_output_charset'):
655 t.set_output_charset('utf-16')
656 with self.assertDeprecated('lngettext'):
657 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300658 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300659 with self.assertDeprecated('lngettext'):
660 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300661 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300662 with self.assertDeprecated('lngettext'):
663 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300664 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300665 with self.assertDeprecated('lngettext'):
666 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300667 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
668
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300669 def test_output_encoding(self):
670 with open(self.mofile, 'rb') as fp:
671 t = gettext.GNUTranslations(fp)
672 with self.assertDeprecated('set_output_charset'):
673 t.set_output_charset('utf-16')
674 with self.assertDeprecated('output_charset'):
675 self.assertEqual(t.output_charset(), 'utf-16')
676
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300677
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400678class GNUTranslationParsingTest(GettextBaseTest):
679 def test_plural_form_error_issue17898(self):
680 with open(MOFILE, 'wb') as fp:
681 fp.write(base64.decodebytes(GNU_MO_DATA_ISSUE_17898))
682 with open(MOFILE, 'rb') as fp:
683 # If this runs cleanly, the bug is fixed.
684 t = gettext.GNUTranslations(fp)
685
Julien Palardafd1e6d2019-05-09 16:22:15 +0200686 def test_ignore_comments_in_headers_issue36239(self):
687 """Checks that comments like:
688
689 #-#-#-#-# messages.po (EdX Studio) #-#-#-#-#
690
691 are ignored.
692 """
693 with open(MOFILE, 'wb') as fp:
694 fp.write(base64.decodebytes(GNU_MO_DATA_ISSUE_17898))
695 with open(MOFILE, 'rb') as fp:
696 t = gettext.GNUTranslations(fp)
697 self.assertEqual(t.info()["plural-forms"], "nplurals=2; plural=(n != 1);")
698
Martin v. Löwisd8996052002-11-21 21:45:32 +0000699
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000700class UnicodeTranslationsTest(GettextBaseTest):
701 def setUp(self):
702 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000703 with open(UMOFILE, 'rb') as fp:
Barry Warsawedb155f2003-04-24 18:08:13 +0000704 self.t = gettext.GNUTranslations(fp)
Benjamin Peterson801844d2008-07-14 14:32:15 +0000705 self._ = self.t.gettext
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500706 self.pgettext = self.t.pgettext
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000707
708 def test_unicode_msgid(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300709 self.assertIsInstance(self._(''), str)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000710
711 def test_unicode_msgstr(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300712 self.assertEqual(self._('ab\xde'), '\xa4yz')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000713
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500714 def test_unicode_context_msgstr(self):
715 t = self.pgettext('mycontext\xde', 'ab\xde')
716 self.assertTrue(isinstance(t, str))
717 self.assertEqual(t, '\xa4yz (context version)')
718
719
720class UnicodeTranslationsPluralTest(GettextBaseTest):
721 def setUp(self):
722 GettextBaseTest.setUp(self)
723 with open(MOFILE, 'rb') as fp:
724 self.t = gettext.GNUTranslations(fp)
725 self.ngettext = self.t.ngettext
726 self.npgettext = self.t.npgettext
727
728 def test_unicode_msgid(self):
729 unless = self.assertTrue
730 unless(isinstance(self.ngettext('', '', 1), str))
731 unless(isinstance(self.ngettext('', '', 2), str))
732
733 def test_unicode_context_msgid(self):
734 unless = self.assertTrue
735 unless(isinstance(self.npgettext('', '', '', 1), str))
736 unless(isinstance(self.npgettext('', '', '', 2), str))
737
738 def test_unicode_msgstr(self):
739 eq = self.assertEqual
740 unless = self.assertTrue
741 t = self.ngettext("There is %s file", "There are %s files", 1)
742 unless(isinstance(t, str))
743 eq(t, "Hay %s fichero")
744 unless(isinstance(t, str))
745 t = self.ngettext("There is %s file", "There are %s files", 5)
746 unless(isinstance(t, str))
747 eq(t, "Hay %s ficheros")
748
749 def test_unicode_msgstr_with_context(self):
750 eq = self.assertEqual
751 unless = self.assertTrue
752 t = self.npgettext("With context",
753 "There is %s file", "There are %s files", 1)
754 unless(isinstance(t, str))
755 eq(t, "Hay %s fichero (context)")
756 t = self.npgettext("With context",
757 "There is %s file", "There are %s files", 5)
758 unless(isinstance(t, str))
759 eq(t, "Hay %s ficheros (context)")
760
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000761
Barry Warsawe960e222003-05-20 17:28:54 +0000762class WeirdMetadataTest(GettextBaseTest):
763 def setUp(self):
764 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000765 with open(MMOFILE, 'rb') as fp:
Barry Warsawe960e222003-05-20 17:28:54 +0000766 try:
767 self.t = gettext.GNUTranslations(fp)
768 except:
769 self.tearDown()
770 raise
Barry Warsawe960e222003-05-20 17:28:54 +0000771
772 def test_weird_metadata(self):
773 info = self.t.info()
Christian Heimes6ae5d7f2007-10-31 18:53:44 +0000774 self.assertEqual(len(info), 9)
Barry Warsawe960e222003-05-20 17:28:54 +0000775 self.assertEqual(info['last-translator'],
776 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
777
778
Éric Araujo6108bf52010-10-04 23:52:37 +0000779class DummyGNUTranslations(gettext.GNUTranslations):
780 def foo(self):
781 return 'foo'
782
783
784class GettextCacheTestCase(GettextBaseTest):
785 def test_cache(self):
786 self.localedir = os.curdir
787 self.mofile = MOFILE
788
789 self.assertEqual(len(gettext._translations), 0)
790
791 t = gettext.translation('gettext', self.localedir)
792
793 self.assertEqual(len(gettext._translations), 1)
794
795 t = gettext.translation('gettext', self.localedir,
796 class_=DummyGNUTranslations)
797
798 self.assertEqual(len(gettext._translations), 2)
799 self.assertEqual(t.__class__, DummyGNUTranslations)
800
801 # Calling it again doesn't add to the cache
802
803 t = gettext.translation('gettext', self.localedir,
804 class_=DummyGNUTranslations)
805
806 self.assertEqual(len(gettext._translations), 2)
807 self.assertEqual(t.__class__, DummyGNUTranslations)
808
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300809 # Test deprecated parameter codeset
810 with self.assertWarnsRegex(DeprecationWarning, 'parameter codeset'):
811 t = gettext.translation('gettext', self.localedir,
812 class_=DummyGNUTranslations,
813 codeset='utf-16')
814 self.assertEqual(len(gettext._translations), 2)
815 self.assertEqual(t.__class__, DummyGNUTranslations)
816 with self.assertWarns(DeprecationWarning):
817 self.assertEqual(t.output_charset(), 'utf-16')
818
Éric Araujo6108bf52010-10-04 23:52:37 +0000819
Martin Panterd226d302015-11-14 11:47:00 +0000820class MiscTestCase(unittest.TestCase):
821 def test__all__(self):
822 blacklist = {'c2py', 'ENOENT'}
823 support.check__all__(self, gettext, blacklist=blacklist)
824
825
Martin v. Löwisd8996052002-11-21 21:45:32 +0000826if __name__ == '__main__':
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300827 unittest.main()
Martin v. Löwisd8996052002-11-21 21:45:32 +0000828
Barry Warsawff6d8132000-08-25 19:50:38 +0000829
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000830# For reference, here's the .po file used to created the GNU_MO_DATA above.
Martin v. Löwisd8996052002-11-21 21:45:32 +0000831#
832# The original version was automatically generated from the sources with
833# pygettext. Later it was manually modified to add plural forms support.
Barry Warsawff6d8132000-08-25 19:50:38 +0000834
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300835b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000836# Dummy translation for the Python test_gettext.py module.
Barry Warsaw19148732001-08-24 19:11:57 +0000837# Copyright (C) 2001 Python Software Foundation
838# Barry Warsaw <barry@python.org>, 2000.
Barry Warsaw64dab462000-08-30 03:32:07 +0000839#
840msgid ""
841msgstr ""
842"Project-Id-Version: 2.0\n"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000843"PO-Revision-Date: 2003-04-11 14:32-0400\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000844"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000845"Language-Team: XX <python-dev@python.org>\n"
846"MIME-Version: 1.0\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000847"Content-Type: text/plain; charset=iso-8859-1\n"
848"Content-Transfer-Encoding: 8bit\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000849"Generated-By: pygettext.py 1.1\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000850"Plural-Forms: nplurals=2; plural=n!=1;\n"
Barry Warsawff6d8132000-08-25 19:50:38 +0000851
Barry Warsaw64dab462000-08-30 03:32:07 +0000852#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
853#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
854#: test_gettext.py:98
855msgid "nudge nudge"
856msgstr "wink wink"
Barry Warsawff6d8132000-08-25 19:50:38 +0000857
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500858msgctxt "my context"
859msgid "nudge nudge"
860msgstr "wink wink (in \"my context\")"
861
862msgctxt "my other context"
863msgid "nudge nudge"
864msgstr "wink wink (in \"my other context\")"
865
Barry Warsaw64dab462000-08-30 03:32:07 +0000866#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
867#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
868msgid "albatross"
869msgstr ""
Barry Warsawff6d8132000-08-25 19:50:38 +0000870
Barry Warsaw64dab462000-08-30 03:32:07 +0000871#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
872#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
873msgid "Raymond Luxury Yach-t"
874msgstr "Throatwobbler Mangrove"
Barry Warsawff6d8132000-08-25 19:50:38 +0000875
Barry Warsaw64dab462000-08-30 03:32:07 +0000876#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
877#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
878#: test_gettext.py:96
879msgid "mullusk"
880msgstr "bacon"
Barry Warsawff6d8132000-08-25 19:50:38 +0000881
Barry Warsaw64dab462000-08-30 03:32:07 +0000882#: test_gettext.py:40 test_gettext.py:101
883msgid ""
884"This module provides internationalization and localization\n"
885"support for your Python programs by providing an interface to the GNU\n"
886"gettext message catalog library."
887msgstr ""
888"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
889"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
890"trggrkg zrffntr pngnybt yvoenel."
Martin v. Löwisd8996052002-11-21 21:45:32 +0000891
892# Manually added, as neither pygettext nor xgettext support plural forms
893# in Python.
894msgid "There is %s file"
895msgid_plural "There are %s files"
896msgstr[0] "Hay %s fichero"
897msgstr[1] "Hay %s ficheros"
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500898
899# Manually added, as neither pygettext nor xgettext support plural forms
900# and context in Python.
901msgctxt "With context"
902msgid "There is %s file"
903msgid_plural "There are %s files"
904msgstr[0] "Hay %s fichero (context)"
905msgstr[1] "Hay %s ficheros (context)"
Barry Warsaw64dab462000-08-30 03:32:07 +0000906'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000907
908# Here's the second example po file example, used to generate the UMO_DATA
909# containing utf-8 encoded Unicode strings
910
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300911b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000912# Dummy translation for the Python test_gettext.py module.
913# Copyright (C) 2001 Python Software Foundation
914# Barry Warsaw <barry@python.org>, 2000.
915#
916msgid ""
917msgstr ""
918"Project-Id-Version: 2.0\n"
919"PO-Revision-Date: 2003-04-11 12:42-0400\n"
920"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
921"Language-Team: XX <python-dev@python.org>\n"
922"MIME-Version: 1.0\n"
923"Content-Type: text/plain; charset=utf-8\n"
924"Content-Transfer-Encoding: 7bit\n"
925"Generated-By: manually\n"
926
927#: nofile:0
928msgid "ab\xc3\x9e"
929msgstr "\xc2\xa4yz"
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500930
931#: nofile:1
932msgctxt "mycontext\xc3\x9e"
933msgid "ab\xc3\x9e"
934msgstr "\xc2\xa4yz (context version)"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000935'''
Barry Warsawe960e222003-05-20 17:28:54 +0000936
937# Here's the third example po file, used to generate MMO_DATA
938
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300939b'''
Barry Warsawe960e222003-05-20 17:28:54 +0000940msgid ""
941msgstr ""
942"Project-Id-Version: No Project 0.0\n"
943"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
944"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
945"Last-Translator: John Doe <jdoe@example.com>\n"
946"Jane Foobar <jfoobar@example.com>\n"
947"Language-Team: xx <xx@example.com>\n"
948"MIME-Version: 1.0\n"
949"Content-Type: text/plain; charset=iso-8859-15\n"
950"Content-Transfer-Encoding: quoted-printable\n"
951"Generated-By: pygettext.py 1.3\n"
952'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400953
954#
955# messages.po, used for bug 17898
956#
957
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300958b'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400959# test file for http://bugs.python.org/issue17898
960msgid ""
961msgstr ""
962"Plural-Forms: nplurals=2; plural=(n != 1);\n"
963"#-#-#-#-# messages.po (EdX Studio) #-#-#-#-#\n"
964"Content-Type: text/plain; charset=UTF-8\n"
965'''