blob: 9d1a96b8b0d1c8c3d4f0e6a7e00da8251ab1f435 [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
Serhiy Storchaka26cb4652017-06-20 17:13:29 +03005import locale
Martin v. Löwisd8996052002-11-21 21:45:32 +00006import unittest
Barry Warsawa1ce93f2003-04-11 18:36:43 +00007
Benjamin Petersonee8712c2008-05-20 21:35:26 +00008from test import support
Barry Warsawa1ce93f2003-04-11 18:36:43 +00009
Fred Drake004d5e62000-10-23 17:22:08 +000010
Martin v. Löwisd8996052002-11-21 21:45:32 +000011# TODO:
12# - Add new tests, for example for "dgettext"
13# - Remove dummy tests, for example testing for single and double quotes
14# has no sense, it would have if we were testing a parser (i.e. pygettext)
15# - Tests should have only one assert.
Barry Warsaw64dab462000-08-30 03:32:07 +000016
Guido van Rossum39478e82007-08-27 17:23:59 +000017GNU_MO_DATA = b'''\
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500183hIElQAAAAAJAAAAHAAAAGQAAAAAAAAArAAAAAAAAACsAAAAFQAAAK0AAAAjAAAAwwAAAKEAAADn
19AAAAMAAAAIkBAAAHAAAAugEAABYAAADCAQAAHAAAANkBAAALAAAA9gEAAEIBAAACAgAAFgAAAEUD
20AAAeAAAAXAMAAKEAAAB7AwAAMgAAAB0EAAAFAAAAUAQAABsAAABWBAAAIQAAAHIEAAAJAAAAlAQA
21AABSYXltb25kIEx1eHVyeSBZYWNoLXQAVGhlcmUgaXMgJXMgZmlsZQBUaGVyZSBhcmUgJXMgZmls
22ZXMAVGhpcyBtb2R1bGUgcHJvdmlkZXMgaW50ZXJuYXRpb25hbGl6YXRpb24gYW5kIGxvY2FsaXph
23dGlvbgpzdXBwb3J0IGZvciB5b3VyIFB5dGhvbiBwcm9ncmFtcyBieSBwcm92aWRpbmcgYW4gaW50
24ZXJmYWNlIHRvIHRoZSBHTlUKZ2V0dGV4dCBtZXNzYWdlIGNhdGFsb2cgbGlicmFyeS4AV2l0aCBj
25b250ZXh0BFRoZXJlIGlzICVzIGZpbGUAVGhlcmUgYXJlICVzIGZpbGVzAG11bGx1c2sAbXkgY29u
26dGV4dARudWRnZSBudWRnZQBteSBvdGhlciBjb250ZXh0BG51ZGdlIG51ZGdlAG51ZGdlIG51ZGdl
27AFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDMtMDQtMTEgMTQ6
28MzItMDQwMApMYXN0LVRyYW5zbGF0b3I6IEouIERhdmlkIEliYW5leiA8ai1kYXZpZEBub29zLmZy
29PgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246
30IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4NTktMQpDb250ZW50
31LVRyYW5zZmVyLUVuY29kaW5nOiA4Yml0CkdlbmVyYXRlZC1CeTogcHlnZXR0ZXh0LnB5IDEuMQpQ
32bHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0d29iYmxlciBNYW5n
33cm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFoeXIgY2ViaXZxcmYg
34dmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVnIHNiZSBsYmhlIENs
35Z3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1ciBUQUgKdHJnZ3Jr
36ZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4ASGF5ICVzIGZpY2hlcm8gKGNvbnRleHQpAEhheSAl
37cyBmaWNoZXJvcyAoY29udGV4dCkAYmFjb24Ad2luayB3aW5rIChpbiAibXkgY29udGV4dCIpAHdp
38bmsgd2luayAoaW4gIm15IG90aGVyIGNvbnRleHQiKQB3aW5rIHdpbmsA
Barry Warsawff6d8132000-08-25 19:50:38 +000039'''
40
Antoine Pitroube8d06f2014-10-28 20:17:51 +010041# This data contains an invalid major version number (5)
42# An unexpected major version number should be treated as an error when
43# parsing a .mo file
44
45GNU_MO_DATA_BAD_MAJOR_VERSION = b'''\
463hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
47AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
48AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
49eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
50aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
51CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
52Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
53ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
54MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
55YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
56SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
57NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
58ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
59d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
60eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
61IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
62ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
63'''
64
65# This data contains an invalid minor version number (7)
66# An unexpected minor version number only indicates that some of the file's
67# contents may not be able to be read. It does not indicate an error.
68
69GNU_MO_DATA_BAD_MINOR_VERSION = b'''\
703hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
71AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
72AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
73eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
74aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
75CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
76Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
77ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
78MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
79YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
80SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
81NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
82ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
83d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
84eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
85IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
86ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
87'''
88
89
Guido van Rossum39478e82007-08-27 17:23:59 +000090UMO_DATA = b'''\
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500913hIElQAAAAADAAAAHAAAADQAAAAAAAAAAAAAAAAAAABMAAAABAAAAE0AAAAQAAAAUgAAAA8BAABj
92AAAABAAAAHMBAAAWAAAAeAEAAABhYsOeAG15Y29udGV4dMOeBGFiw54AUHJvamVjdC1JZC1WZXJz
93aW9uOiAyLjAKUE8tUmV2aXNpb24tRGF0ZTogMjAwMy0wNC0xMSAxMjo0Mi0wNDAwCkxhc3QtVHJh
94bnNsYXRvcjogQmFycnkgQS4gV0Fyc2F3IDxiYXJyeUBweXRob24ub3JnPgpMYW5ndWFnZS1UZWFt
95OiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpNSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5
96cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzog
97N2JpdApHZW5lcmF0ZWQtQnk6IG1hbnVhbGx5CgDCpHl6AMKkeXogKGNvbnRleHQgdmVyc2lvbikA
Barry Warsawa1ce93f2003-04-11 18:36:43 +000098'''
Fred Drake004d5e62000-10-23 17:22:08 +000099
Guido van Rossum39478e82007-08-27 17:23:59 +0000100MMO_DATA = b'''\
Barry Warsawe960e222003-05-20 17:28:54 +00001013hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
102UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
103IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
104NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
105ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
106cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
107c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
108bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
109'''
110
Barry Warsawff6d8132000-08-25 19:50:38 +0000111LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
112MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100113MOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo')
114MOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000115UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
Barry Warsawe960e222003-05-20 17:28:54 +0000116MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
Barry Warsawff6d8132000-08-25 19:50:38 +0000117
118
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000119class GettextBaseTest(unittest.TestCase):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000120 def setUp(self):
Neal Norwitza0e0cd32004-07-19 00:08:59 +0000121 if not os.path.isdir(LOCALEDIR):
122 os.makedirs(LOCALEDIR)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000123 with open(MOFILE, 'wb') as fp:
124 fp.write(base64.decodebytes(GNU_MO_DATA))
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100125 with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp:
126 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION))
127 with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp:
128 fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION))
Éric Araujo7fa886d2010-11-06 04:11:59 +0000129 with open(UMOFILE, 'wb') as fp:
130 fp.write(base64.decodebytes(UMO_DATA))
131 with open(MMOFILE, 'wb') as fp:
132 fp.write(base64.decodebytes(MMO_DATA))
Walter Dörwald155374d2009-05-01 19:58:58 +0000133 self.env = support.EnvironmentVarGuard()
134 self.env['LANGUAGE'] = 'xx'
Éric Araujo37a89332010-11-06 04:09:29 +0000135 gettext._translations.clear()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000136
137 def tearDown(self):
Walter Dörwald155374d2009-05-01 19:58:58 +0000138 self.env.__exit__()
139 del self.env
Victor Stinnercdb2c602014-07-24 12:07:45 +0200140 support.rmtree(os.path.split(LOCALEDIR)[0])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000141
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400142GNU_MO_DATA_ISSUE_17898 = b'''\
1433hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z
144OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk
145WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU
146Ri04CgA=
147'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000148
149class GettextTestCase1(GettextBaseTest):
150 def setUp(self):
151 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000152 self.localedir = os.curdir
153 self.mofile = MOFILE
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500154 gettext.install('gettext', self.localedir, names=['pgettext'])
Martin v. Löwisd8996052002-11-21 21:45:32 +0000155
Martin v. Löwisd8996052002-11-21 21:45:32 +0000156 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000157 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000158 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000159 eq(_('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000160 eq(_('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000161 eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000162 eq(_(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000163
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500164 def test_some_translations_with_context(self):
165 eq = self.assertEqual
166 eq(pgettext('my context', 'nudge nudge'),
167 'wink wink (in "my context")')
168 eq(pgettext('my other context', 'nudge nudge'),
169 'wink wink (in "my other context")')
170
Martin v. Löwisd8996052002-11-21 21:45:32 +0000171 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000172 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000173 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000174 eq(_("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000175 eq(_("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000176 eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000177 eq(_(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000178
179 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000180 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000181 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000182 eq(_('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000183 eq(_('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000184 eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000185 eq(_(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000186
187 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000188 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000189 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000190 eq(_("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000191 eq(_("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000192 eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000193 eq(_(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000194
195 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000196 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000197 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000198 eq(_('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000199support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000200gettext message catalog library.'''),
201 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000202fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000203trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000204
205 def test_the_alternative_interface(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000206 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000207 # test the alternative interface
Éric Araujo7fa886d2010-11-06 04:11:59 +0000208 with open(self.mofile, 'rb') as fp:
209 t = gettext.GNUTranslations(fp)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000210 # Install the translation object
Martin v. Löwisd8996052002-11-21 21:45:32 +0000211 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000212 eq(_('nudge nudge'), 'wink wink')
213 # Try unicode return type
Benjamin Peterson801844d2008-07-14 14:32:15 +0000214 t.install()
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000215 eq(_('mullusk'), 'bacon')
Georg Brandl602b9ba2006-02-19 13:26:36 +0000216 # Test installation of other methods
Georg Brandl1a3284e2007-12-02 09:40:06 +0000217 import builtins
Benjamin Peterson801844d2008-07-14 14:32:15 +0000218 t.install(names=["gettext", "lgettext"])
219 eq(_, t.gettext)
220 eq(builtins.gettext, t.gettext)
Georg Brandl602b9ba2006-02-19 13:26:36 +0000221 eq(lgettext, t.lgettext)
Georg Brandl1a3284e2007-12-02 09:40:06 +0000222 del builtins.gettext
223 del builtins.lgettext
Martin v. Löwisd8996052002-11-21 21:45:32 +0000224
225
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000226class GettextTestCase2(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000227 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000228 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000229 self.localedir = os.curdir
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000230 # Set up the bindings
Martin v. Löwisd8996052002-11-21 21:45:32 +0000231 gettext.bindtextdomain('gettext', self.localedir)
232 gettext.textdomain('gettext')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000233 # For convenience
Martin v. Löwisd8996052002-11-21 21:45:32 +0000234 self._ = gettext.gettext
235
Martin v. Löwisd8996052002-11-21 21:45:32 +0000236 def test_bindtextdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000237 self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000238
239 def test_textdomain(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000240 self.assertEqual(gettext.textdomain(), 'gettext')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000241
Antoine Pitroube8d06f2014-10-28 20:17:51 +0100242 def test_bad_major_version(self):
243 with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp:
244 with self.assertRaises(OSError) as cm:
245 gettext.GNUTranslations(fp)
246
247 exception = cm.exception
248 self.assertEqual(exception.errno, 0)
249 self.assertEqual(exception.strerror, "Bad version number 5")
250 self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION)
251
252 def test_bad_minor_version(self):
253 with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp:
254 # Check that no error is thrown with a bad minor version number
255 gettext.GNUTranslations(fp)
256
Martin v. Löwisd8996052002-11-21 21:45:32 +0000257 def test_some_translations(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000258 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000259 # test some translations
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000260 eq(self._('albatross'), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000261 eq(self._('mullusk'), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000262 eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000263 eq(self._(r'nudge nudge'), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000264
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500265 def test_some_translations_with_context(self):
266 eq = self.assertEqual
267 eq(gettext.pgettext('my context', 'nudge nudge'),
268 'wink wink (in "my context")')
269 eq(gettext.pgettext('my other context', 'nudge nudge'),
270 'wink wink (in "my other context")')
271
272 def test_some_translations_with_context_and_domain(self):
273 eq = self.assertEqual
274 eq(gettext.dpgettext('gettext', 'my context', 'nudge nudge'),
275 'wink wink (in "my context")')
276 eq(gettext.dpgettext('gettext', 'my other context', 'nudge nudge'),
277 'wink wink (in "my other context")')
278
Martin v. Löwisd8996052002-11-21 21:45:32 +0000279 def test_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000280 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000281 # double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000282 eq(self._("albatross"), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000283 eq(self._("mullusk"), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000284 eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000285 eq(self._(r"nudge nudge"), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000286
287 def test_triple_single_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000288 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000289 # triple single quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000290 eq(self._('''albatross'''), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000291 eq(self._('''mullusk'''), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000292 eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000293 eq(self._(r'''nudge nudge'''), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000294
295 def test_triple_double_quotes(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000296 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000297 # triple double quotes
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000298 eq(self._("""albatross"""), 'albatross')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000299 eq(self._("""mullusk"""), 'bacon')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000300 eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000301 eq(self._(r"""nudge nudge"""), 'wink wink')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000302
303 def test_multiline_strings(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000304 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000305 # multiline strings
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000306 eq(self._('''This module provides internationalization and localization
Martin v. Löwisd8996052002-11-21 21:45:32 +0000307support for your Python programs by providing an interface to the GNU
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000308gettext message catalog library.'''),
309 '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
Martin v. Löwisd8996052002-11-21 21:45:32 +0000310fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000311trggrkg zrffntr pngnybt yvoenel.''')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000312
313
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000314class PluralFormsTestCase(GettextBaseTest):
Martin v. Löwisd8996052002-11-21 21:45:32 +0000315 def setUp(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000316 GettextBaseTest.setUp(self)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000317 self.mofile = MOFILE
318
319 def test_plural_forms1(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000320 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000321 x = gettext.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000322 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000323 x = gettext.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000324 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000325
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500326 def test_plural_context_forms1(self):
327 eq = self.assertEqual
328 x = gettext.npgettext('With context',
329 'There is %s file', 'There are %s files', 1)
330 eq(x, 'Hay %s fichero (context)')
331 x = gettext.npgettext('With context',
332 'There is %s file', 'There are %s files', 2)
333 eq(x, 'Hay %s ficheros (context)')
334
Martin v. Löwisd8996052002-11-21 21:45:32 +0000335 def test_plural_forms2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000336 eq = self.assertEqual
Éric Araujo7fa886d2010-11-06 04:11:59 +0000337 with open(self.mofile, 'rb') as fp:
338 t = gettext.GNUTranslations(fp)
Martin v. Löwisd8996052002-11-21 21:45:32 +0000339 x = t.ngettext('There is %s file', 'There are %s files', 1)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000340 eq(x, 'Hay %s fichero')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000341 x = t.ngettext('There is %s file', 'There are %s files', 2)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000342 eq(x, 'Hay %s ficheros')
Martin v. Löwisd8996052002-11-21 21:45:32 +0000343
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500344 def test_plural_context_forms2(self):
345 eq = self.assertEqual
346 with open(self.mofile, 'rb') as fp:
347 t = gettext.GNUTranslations(fp)
348 x = t.npgettext('With context',
349 'There is %s file', 'There are %s files', 1)
350 eq(x, 'Hay %s fichero (context)')
351 x = t.npgettext('With context',
352 'There is %s file', 'There are %s files', 2)
353 eq(x, 'Hay %s ficheros (context)')
354
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200355 # Examples from http://www.gnu.org/software/gettext/manual/gettext.html
356
357 def test_ja(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000358 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000359 f = gettext.c2py('0')
360 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000361 eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000362
363 def test_de(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000364 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000365 f = gettext.c2py('n != 1')
366 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000367 eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000368
369 def test_fr(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000370 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000371 f = gettext.c2py('n>1')
372 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000373 eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000374
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200375 def test_lv(self):
376 eq = self.assertEqual
377 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2')
378 s = ''.join([ str(f(x)) for x in range(200) ])
379 eq(s, "20111111111111111111101111111110111111111011111111101111111110111111111011111111101111111110111111111011111111111111111110111111111011111111101111111110111111111011111111101111111110111111111011111111")
380
Martin v. Löwisd8996052002-11-21 21:45:32 +0000381 def test_gd(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000382 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000383 f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
384 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000385 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000386
387 def test_gd2(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000388 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000389 # Tests the combination of parentheses and "?:"
390 f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
391 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000392 eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000393
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200394 def test_ro(self):
395 eq = self.assertEqual
396 f = gettext.c2py('n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2')
397 s = ''.join([ str(f(x)) for x in range(200) ])
398 eq(s, "10111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222")
399
Martin v. Löwisd8996052002-11-21 21:45:32 +0000400 def test_lt(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000401 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000402 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
403 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000404 eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000405
406 def test_ru(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000407 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000408 f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
409 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000410 eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000411
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200412 def test_cs(self):
413 eq = self.assertEqual
414 f = gettext.c2py('(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2')
415 s = ''.join([ str(f(x)) for x in range(200) ])
416 eq(s, "20111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
417
Martin v. Löwisd8996052002-11-21 21:45:32 +0000418 def test_pl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000419 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000420 f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
421 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000422 eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000423
424 def test_sl(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000425 eq = self.assertEqual
Martin v. Löwisd8996052002-11-21 21:45:32 +0000426 f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
427 s = ''.join([ str(f(x)) for x in range(200) ])
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000428 eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
Martin v. Löwisd8996052002-11-21 21:45:32 +0000429
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200430 def test_ar(self):
431 eq = self.assertEqual
432 f = gettext.c2py('n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5')
433 s = ''.join([ str(f(x)) for x in range(200) ])
434 eq(s, "01233333333444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445553333333344444444444444444444444444444444444444444444444444444444444444444444444444444444444444444")
435
Martin v. Löwisd8996052002-11-21 21:45:32 +0000436 def test_security(self):
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000437 raises = self.assertRaises
Martin v. Löwisd8996052002-11-21 21:45:32 +0000438 # Test for a dangerous expression
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000439 raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200440 # issue28563
441 raises(ValueError, gettext.c2py, '"(eval(foo) && ""')
442 raises(ValueError, gettext.c2py, 'f"{os.system(\'sh\')}"')
443 # Maximum recursion depth exceeded during compilation
444 raises(ValueError, gettext.c2py, 'n+'*10000 + 'n')
445 self.assertEqual(gettext.c2py('n+'*100 + 'n')(1), 101)
446 # MemoryError during compilation
447 raises(ValueError, gettext.c2py, '('*100 + 'n' + ')'*100)
448 # Maximum recursion depth exceeded in C to Python translator
449 raises(ValueError, gettext.c2py, '('*10000 + 'n' + ')'*10000)
450 self.assertEqual(gettext.c2py('('*20 + 'n' + ')'*20)(1), 1)
451
452 def test_chained_comparison(self):
453 # C doesn't chain comparison as Python so 2 == 2 == 2 gets different results
454 f = gettext.c2py('n == n == n')
455 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
456 f = gettext.c2py('1 < n == n')
457 self.assertEqual(''.join(str(f(x)) for x in range(3)), '100')
458 f = gettext.c2py('n == n < 2')
459 self.assertEqual(''.join(str(f(x)) for x in range(3)), '010')
460 f = gettext.c2py('0 < n < 2')
461 self.assertEqual(''.join(str(f(x)) for x in range(3)), '111')
462
463 def test_decimal_number(self):
464 self.assertEqual(gettext.c2py('0123')(1), 123)
465
466 def test_invalid_syntax(self):
467 invalid_expressions = [
468 'x>1', '(n>1', 'n>1)', '42**42**42', '0xa', '1.0', '1e2',
469 'n>0x1', '+n', '-n', 'n()', 'n(1)', '1+', 'nn', 'n n',
470 ]
471 for expr in invalid_expressions:
472 with self.assertRaises(ValueError):
473 gettext.c2py(expr)
474
475 def test_nested_condition_operator(self):
476 self.assertEqual(gettext.c2py('n?1?2:3:4')(0), 4)
477 self.assertEqual(gettext.c2py('n?1?2:3:4')(1), 2)
478 self.assertEqual(gettext.c2py('n?1:3?4:5')(0), 4)
479 self.assertEqual(gettext.c2py('n?1:3?4:5')(1), 1)
480
481 def test_division(self):
482 f = gettext.c2py('2/n*3')
483 self.assertEqual(f(1), 6)
484 self.assertEqual(f(2), 3)
485 self.assertEqual(f(3), 0)
486 self.assertEqual(f(-1), -6)
487 self.assertRaises(ZeroDivisionError, f, 0)
488
489 def test_plural_number(self):
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200490 f = gettext.c2py('n != 1')
491 self.assertEqual(f(1), 0)
492 self.assertEqual(f(2), 1)
Serhiy Storchakaf6595982017-03-12 13:15:01 +0200493 with self.assertWarns(DeprecationWarning):
494 self.assertEqual(f(1.0), 0)
495 with self.assertWarns(DeprecationWarning):
496 self.assertEqual(f(2.0), 1)
497 with self.assertWarns(DeprecationWarning):
498 self.assertEqual(f(1.1), 1)
Serhiy Storchaka60ac9892016-11-14 19:22:12 +0200499 self.assertRaises(TypeError, f, '2')
500 self.assertRaises(TypeError, f, b'2')
501 self.assertRaises(TypeError, f, [])
502 self.assertRaises(TypeError, f, object())
Serhiy Storchaka07bcf052016-11-08 21:17:46 +0200503
Martin v. Löwisd8996052002-11-21 21:45:32 +0000504
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300505class LGettextTestCase(GettextBaseTest):
506 def setUp(self):
507 GettextBaseTest.setUp(self)
508 self.mofile = MOFILE
509
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300510 @contextlib.contextmanager
511 def assertDeprecated(self, name):
512 with self.assertWarnsRegex(DeprecationWarning,
513 fr'^{name}\(\) is deprecated'):
514 yield
515
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300516 def test_lgettext(self):
517 lgettext = gettext.lgettext
518 ldgettext = gettext.ldgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300519 with self.assertDeprecated('lgettext'):
520 self.assertEqual(lgettext('mullusk'), b'bacon')
521 with self.assertDeprecated('lgettext'):
522 self.assertEqual(lgettext('spam'), b'spam')
523 with self.assertDeprecated('ldgettext'):
524 self.assertEqual(ldgettext('gettext', 'mullusk'), b'bacon')
525 with self.assertDeprecated('ldgettext'):
526 self.assertEqual(ldgettext('gettext', 'spam'), b'spam')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300527
528 def test_lgettext_2(self):
529 with open(self.mofile, 'rb') as fp:
530 t = gettext.GNUTranslations(fp)
531 lgettext = t.lgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300532 with self.assertDeprecated('lgettext'):
533 self.assertEqual(lgettext('mullusk'), b'bacon')
534 with self.assertDeprecated('lgettext'):
535 self.assertEqual(lgettext('spam'), b'spam')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300536
537 def test_lgettext_bind_textdomain_codeset(self):
538 lgettext = gettext.lgettext
539 ldgettext = gettext.ldgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300540 with self.assertDeprecated('bind_textdomain_codeset'):
541 saved_codeset = gettext.bind_textdomain_codeset('gettext')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300542 try:
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300543 with self.assertDeprecated('bind_textdomain_codeset'):
544 gettext.bind_textdomain_codeset('gettext', 'utf-16')
545 with self.assertDeprecated('lgettext'):
546 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
547 with self.assertDeprecated('lgettext'):
548 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
549 with self.assertDeprecated('ldgettext'):
550 self.assertEqual(ldgettext('gettext', 'mullusk'), 'bacon'.encode('utf-16'))
551 with self.assertDeprecated('ldgettext'):
552 self.assertEqual(ldgettext('gettext', 'spam'), 'spam'.encode('utf-16'))
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300553 finally:
554 del gettext._localecodesets['gettext']
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300555 with self.assertDeprecated('bind_textdomain_codeset'):
556 gettext.bind_textdomain_codeset('gettext', saved_codeset)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300557
558 def test_lgettext_output_encoding(self):
559 with open(self.mofile, 'rb') as fp:
560 t = gettext.GNUTranslations(fp)
561 lgettext = t.lgettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300562 with self.assertDeprecated('set_output_charset'):
563 t.set_output_charset('utf-16')
564 with self.assertDeprecated('lgettext'):
565 self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16'))
566 with self.assertDeprecated('lgettext'):
567 self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16'))
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300568
569 def test_lngettext(self):
570 lngettext = gettext.lngettext
571 ldngettext = gettext.ldngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300572 with self.assertDeprecated('lngettext'):
573 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300574 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300575 with self.assertDeprecated('lngettext'):
576 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300577 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300578 with self.assertDeprecated('lngettext'):
579 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300580 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300581 with self.assertDeprecated('lngettext'):
582 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300583 self.assertEqual(x, b'There are %s directories')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300584 with self.assertDeprecated('ldngettext'):
585 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300586 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300587 with self.assertDeprecated('ldngettext'):
588 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300589 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300590 with self.assertDeprecated('ldngettext'):
591 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300592 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300593 with self.assertDeprecated('ldngettext'):
594 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300595 self.assertEqual(x, b'There are %s directories')
596
597 def test_lngettext_2(self):
598 with open(self.mofile, 'rb') as fp:
599 t = gettext.GNUTranslations(fp)
600 lngettext = t.lngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300601 with self.assertDeprecated('lngettext'):
602 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300603 self.assertEqual(x, b'Hay %s fichero')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300604 with self.assertDeprecated('lngettext'):
605 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300606 self.assertEqual(x, b'Hay %s ficheros')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300607 with self.assertDeprecated('lngettext'):
608 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300609 self.assertEqual(x, b'There is %s directory')
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300610 with self.assertDeprecated('lngettext'):
611 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300612 self.assertEqual(x, b'There are %s directories')
613
614 def test_lngettext_bind_textdomain_codeset(self):
615 lngettext = gettext.lngettext
616 ldngettext = gettext.ldngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300617 with self.assertDeprecated('bind_textdomain_codeset'):
618 saved_codeset = gettext.bind_textdomain_codeset('gettext')
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300619 try:
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300620 with self.assertDeprecated('bind_textdomain_codeset'):
621 gettext.bind_textdomain_codeset('gettext', 'utf-16')
622 with self.assertDeprecated('lngettext'):
623 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300624 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300625 with self.assertDeprecated('lngettext'):
626 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300627 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300628 with self.assertDeprecated('lngettext'):
629 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300630 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300631 with self.assertDeprecated('lngettext'):
632 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300633 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300634 with self.assertDeprecated('ldngettext'):
635 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300636 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300637 with self.assertDeprecated('ldngettext'):
638 x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300639 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300640 with self.assertDeprecated('ldngettext'):
641 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300642 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300643 with self.assertDeprecated('ldngettext'):
644 x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300645 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
646 finally:
647 del gettext._localecodesets['gettext']
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300648 with self.assertDeprecated('bind_textdomain_codeset'):
649 gettext.bind_textdomain_codeset('gettext', saved_codeset)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300650
651 def test_lngettext_output_encoding(self):
652 with open(self.mofile, 'rb') as fp:
653 t = gettext.GNUTranslations(fp)
654 lngettext = t.lngettext
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300655 with self.assertDeprecated('set_output_charset'):
656 t.set_output_charset('utf-16')
657 with self.assertDeprecated('lngettext'):
658 x = lngettext('There is %s file', 'There are %s files', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300659 self.assertEqual(x, 'Hay %s fichero'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300660 with self.assertDeprecated('lngettext'):
661 x = lngettext('There is %s file', 'There are %s files', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300662 self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300663 with self.assertDeprecated('lngettext'):
664 x = lngettext('There is %s directory', 'There are %s directories', 1)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300665 self.assertEqual(x, 'There is %s directory'.encode('utf-16'))
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300666 with self.assertDeprecated('lngettext'):
667 x = lngettext('There is %s directory', 'There are %s directories', 2)
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300668 self.assertEqual(x, 'There are %s directories'.encode('utf-16'))
669
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300670 def test_output_encoding(self):
671 with open(self.mofile, 'rb') as fp:
672 t = gettext.GNUTranslations(fp)
673 with self.assertDeprecated('set_output_charset'):
674 t.set_output_charset('utf-16')
675 with self.assertDeprecated('output_charset'):
676 self.assertEqual(t.output_charset(), 'utf-16')
677
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300678
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400679class GNUTranslationParsingTest(GettextBaseTest):
680 def test_plural_form_error_issue17898(self):
681 with open(MOFILE, 'wb') as fp:
682 fp.write(base64.decodebytes(GNU_MO_DATA_ISSUE_17898))
683 with open(MOFILE, 'rb') as fp:
684 # If this runs cleanly, the bug is fixed.
685 t = gettext.GNUTranslations(fp)
686
Julien Palardafd1e6d2019-05-09 16:22:15 +0200687 def test_ignore_comments_in_headers_issue36239(self):
688 """Checks that comments like:
689
690 #-#-#-#-# messages.po (EdX Studio) #-#-#-#-#
691
692 are ignored.
693 """
694 with open(MOFILE, 'wb') as fp:
695 fp.write(base64.decodebytes(GNU_MO_DATA_ISSUE_17898))
696 with open(MOFILE, 'rb') as fp:
697 t = gettext.GNUTranslations(fp)
698 self.assertEqual(t.info()["plural-forms"], "nplurals=2; plural=(n != 1);")
699
Martin v. Löwisd8996052002-11-21 21:45:32 +0000700
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000701class UnicodeTranslationsTest(GettextBaseTest):
702 def setUp(self):
703 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000704 with open(UMOFILE, 'rb') as fp:
Barry Warsawedb155f2003-04-24 18:08:13 +0000705 self.t = gettext.GNUTranslations(fp)
Benjamin Peterson801844d2008-07-14 14:32:15 +0000706 self._ = self.t.gettext
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500707 self.pgettext = self.t.pgettext
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000708
709 def test_unicode_msgid(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300710 self.assertIsInstance(self._(''), str)
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000711
712 def test_unicode_msgstr(self):
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300713 self.assertEqual(self._('ab\xde'), '\xa4yz')
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000714
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500715 def test_unicode_context_msgstr(self):
716 t = self.pgettext('mycontext\xde', 'ab\xde')
717 self.assertTrue(isinstance(t, str))
718 self.assertEqual(t, '\xa4yz (context version)')
719
720
721class UnicodeTranslationsPluralTest(GettextBaseTest):
722 def setUp(self):
723 GettextBaseTest.setUp(self)
724 with open(MOFILE, 'rb') as fp:
725 self.t = gettext.GNUTranslations(fp)
726 self.ngettext = self.t.ngettext
727 self.npgettext = self.t.npgettext
728
729 def test_unicode_msgid(self):
730 unless = self.assertTrue
731 unless(isinstance(self.ngettext('', '', 1), str))
732 unless(isinstance(self.ngettext('', '', 2), str))
733
734 def test_unicode_context_msgid(self):
735 unless = self.assertTrue
736 unless(isinstance(self.npgettext('', '', '', 1), str))
737 unless(isinstance(self.npgettext('', '', '', 2), str))
738
739 def test_unicode_msgstr(self):
740 eq = self.assertEqual
741 unless = self.assertTrue
742 t = self.ngettext("There is %s file", "There are %s files", 1)
743 unless(isinstance(t, str))
744 eq(t, "Hay %s fichero")
745 unless(isinstance(t, str))
746 t = self.ngettext("There is %s file", "There are %s files", 5)
747 unless(isinstance(t, str))
748 eq(t, "Hay %s ficheros")
749
750 def test_unicode_msgstr_with_context(self):
751 eq = self.assertEqual
752 unless = self.assertTrue
753 t = self.npgettext("With context",
754 "There is %s file", "There are %s files", 1)
755 unless(isinstance(t, str))
756 eq(t, "Hay %s fichero (context)")
757 t = self.npgettext("With context",
758 "There is %s file", "There are %s files", 5)
759 unless(isinstance(t, str))
760 eq(t, "Hay %s ficheros (context)")
761
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000762
Barry Warsawe960e222003-05-20 17:28:54 +0000763class WeirdMetadataTest(GettextBaseTest):
764 def setUp(self):
765 GettextBaseTest.setUp(self)
Éric Araujo7fa886d2010-11-06 04:11:59 +0000766 with open(MMOFILE, 'rb') as fp:
Barry Warsawe960e222003-05-20 17:28:54 +0000767 try:
768 self.t = gettext.GNUTranslations(fp)
769 except:
770 self.tearDown()
771 raise
Barry Warsawe960e222003-05-20 17:28:54 +0000772
773 def test_weird_metadata(self):
774 info = self.t.info()
Christian Heimes6ae5d7f2007-10-31 18:53:44 +0000775 self.assertEqual(len(info), 9)
Barry Warsawe960e222003-05-20 17:28:54 +0000776 self.assertEqual(info['last-translator'],
777 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
778
779
Éric Araujo6108bf52010-10-04 23:52:37 +0000780class DummyGNUTranslations(gettext.GNUTranslations):
781 def foo(self):
782 return 'foo'
783
784
785class GettextCacheTestCase(GettextBaseTest):
786 def test_cache(self):
787 self.localedir = os.curdir
788 self.mofile = MOFILE
789
790 self.assertEqual(len(gettext._translations), 0)
791
792 t = gettext.translation('gettext', self.localedir)
793
794 self.assertEqual(len(gettext._translations), 1)
795
796 t = gettext.translation('gettext', self.localedir,
797 class_=DummyGNUTranslations)
798
799 self.assertEqual(len(gettext._translations), 2)
800 self.assertEqual(t.__class__, DummyGNUTranslations)
801
802 # Calling it again doesn't add to the cache
803
804 t = gettext.translation('gettext', self.localedir,
805 class_=DummyGNUTranslations)
806
807 self.assertEqual(len(gettext._translations), 2)
808 self.assertEqual(t.__class__, DummyGNUTranslations)
809
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300810 # Test deprecated parameter codeset
811 with self.assertWarnsRegex(DeprecationWarning, 'parameter codeset'):
812 t = gettext.translation('gettext', self.localedir,
813 class_=DummyGNUTranslations,
814 codeset='utf-16')
815 self.assertEqual(len(gettext._translations), 2)
816 self.assertEqual(t.__class__, DummyGNUTranslations)
817 with self.assertWarns(DeprecationWarning):
818 self.assertEqual(t.output_charset(), 'utf-16')
819
Éric Araujo6108bf52010-10-04 23:52:37 +0000820
Martin Panterd226d302015-11-14 11:47:00 +0000821class MiscTestCase(unittest.TestCase):
822 def test__all__(self):
823 blacklist = {'c2py', 'ENOENT'}
824 support.check__all__(self, gettext, blacklist=blacklist)
825
826
Martin v. Löwisd8996052002-11-21 21:45:32 +0000827if __name__ == '__main__':
Serhiy Storchakafec35c92018-10-27 08:00:41 +0300828 unittest.main()
Martin v. Löwisd8996052002-11-21 21:45:32 +0000829
Barry Warsawff6d8132000-08-25 19:50:38 +0000830
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000831# For reference, here's the .po file used to created the GNU_MO_DATA above.
Martin v. Löwisd8996052002-11-21 21:45:32 +0000832#
833# The original version was automatically generated from the sources with
834# pygettext. Later it was manually modified to add plural forms support.
Barry Warsawff6d8132000-08-25 19:50:38 +0000835
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300836b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000837# Dummy translation for the Python test_gettext.py module.
Barry Warsaw19148732001-08-24 19:11:57 +0000838# Copyright (C) 2001 Python Software Foundation
839# Barry Warsaw <barry@python.org>, 2000.
Barry Warsaw64dab462000-08-30 03:32:07 +0000840#
841msgid ""
842msgstr ""
843"Project-Id-Version: 2.0\n"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000844"PO-Revision-Date: 2003-04-11 14:32-0400\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000845"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000846"Language-Team: XX <python-dev@python.org>\n"
847"MIME-Version: 1.0\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000848"Content-Type: text/plain; charset=iso-8859-1\n"
849"Content-Transfer-Encoding: 8bit\n"
Barry Warsaw64dab462000-08-30 03:32:07 +0000850"Generated-By: pygettext.py 1.1\n"
Martin v. Löwisd8996052002-11-21 21:45:32 +0000851"Plural-Forms: nplurals=2; plural=n!=1;\n"
Barry Warsawff6d8132000-08-25 19:50:38 +0000852
Barry Warsaw64dab462000-08-30 03:32:07 +0000853#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
854#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
855#: test_gettext.py:98
856msgid "nudge nudge"
857msgstr "wink wink"
Barry Warsawff6d8132000-08-25 19:50:38 +0000858
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500859msgctxt "my context"
860msgid "nudge nudge"
861msgstr "wink wink (in \"my context\")"
862
863msgctxt "my other context"
864msgid "nudge nudge"
865msgstr "wink wink (in \"my other context\")"
866
Barry Warsaw64dab462000-08-30 03:32:07 +0000867#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
868#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
869msgid "albatross"
870msgstr ""
Barry Warsawff6d8132000-08-25 19:50:38 +0000871
Barry Warsaw64dab462000-08-30 03:32:07 +0000872#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
873#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
874msgid "Raymond Luxury Yach-t"
875msgstr "Throatwobbler Mangrove"
Barry Warsawff6d8132000-08-25 19:50:38 +0000876
Barry Warsaw64dab462000-08-30 03:32:07 +0000877#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
878#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
879#: test_gettext.py:96
880msgid "mullusk"
881msgstr "bacon"
Barry Warsawff6d8132000-08-25 19:50:38 +0000882
Barry Warsaw64dab462000-08-30 03:32:07 +0000883#: test_gettext.py:40 test_gettext.py:101
884msgid ""
885"This module provides internationalization and localization\n"
886"support for your Python programs by providing an interface to the GNU\n"
887"gettext message catalog library."
888msgstr ""
889"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
890"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
891"trggrkg zrffntr pngnybt yvoenel."
Martin v. Löwisd8996052002-11-21 21:45:32 +0000892
893# Manually added, as neither pygettext nor xgettext support plural forms
894# in Python.
895msgid "There is %s file"
896msgid_plural "There are %s files"
897msgstr[0] "Hay %s fichero"
898msgstr[1] "Hay %s ficheros"
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500899
900# Manually added, as neither pygettext nor xgettext support plural forms
901# and context in Python.
902msgctxt "With context"
903msgid "There is %s file"
904msgid_plural "There are %s files"
905msgstr[0] "Hay %s fichero (context)"
906msgstr[1] "Hay %s ficheros (context)"
Barry Warsaw64dab462000-08-30 03:32:07 +0000907'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000908
909# Here's the second example po file example, used to generate the UMO_DATA
910# containing utf-8 encoded Unicode strings
911
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300912b'''
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000913# Dummy translation for the Python test_gettext.py module.
914# Copyright (C) 2001 Python Software Foundation
915# Barry Warsaw <barry@python.org>, 2000.
916#
917msgid ""
918msgstr ""
919"Project-Id-Version: 2.0\n"
920"PO-Revision-Date: 2003-04-11 12:42-0400\n"
921"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
922"Language-Team: XX <python-dev@python.org>\n"
923"MIME-Version: 1.0\n"
924"Content-Type: text/plain; charset=utf-8\n"
925"Content-Transfer-Encoding: 7bit\n"
926"Generated-By: manually\n"
927
928#: nofile:0
929msgid "ab\xc3\x9e"
930msgstr "\xc2\xa4yz"
Cheryl Sabella637a33b2018-11-07 09:12:20 -0500931
932#: nofile:1
933msgctxt "mycontext\xc3\x9e"
934msgid "ab\xc3\x9e"
935msgstr "\xc2\xa4yz (context version)"
Barry Warsawa1ce93f2003-04-11 18:36:43 +0000936'''
Barry Warsawe960e222003-05-20 17:28:54 +0000937
938# Here's the third example po file, used to generate MMO_DATA
939
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300940b'''
Barry Warsawe960e222003-05-20 17:28:54 +0000941msgid ""
942msgstr ""
943"Project-Id-Version: No Project 0.0\n"
944"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
945"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
946"Last-Translator: John Doe <jdoe@example.com>\n"
947"Jane Foobar <jfoobar@example.com>\n"
948"Language-Team: xx <xx@example.com>\n"
949"MIME-Version: 1.0\n"
950"Content-Type: text/plain; charset=iso-8859-15\n"
951"Content-Transfer-Encoding: quoted-printable\n"
952"Generated-By: pygettext.py 1.3\n"
953'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400954
955#
956# messages.po, used for bug 17898
957#
958
Serhiy Storchaka26cb4652017-06-20 17:13:29 +0300959b'''
Andrew Kuchling8b963c52015-04-13 10:38:56 -0400960# test file for http://bugs.python.org/issue17898
961msgid ""
962msgstr ""
963"Plural-Forms: nplurals=2; plural=(n != 1);\n"
964"#-#-#-#-# messages.po (EdX Studio) #-#-#-#-#\n"
965"Content-Type: text/plain; charset=UTF-8\n"
966'''