test_gettext.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. import os
  2. import base64
  3. import shutil
  4. import gettext
  5. import unittest
  6. from test import test_support
  7. # TODO:
  8. # - Add new tests, for example for "dgettext"
  9. # - Remove dummy tests, for example testing for single and double quotes
  10. # has no sense, it would have if we were testing a parser (i.e. pygettext)
  11. # - Tests should have only one assert.
  12. GNU_MO_DATA = '''\
  13. 3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
  14. AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
  15. AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
  16. eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
  17. aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
  18. CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
  19. Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
  20. ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
  21. MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
  22. YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
  23. SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
  24. NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
  25. ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
  26. d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
  27. eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
  28. IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
  29. ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
  30. '''
  31. UMO_DATA = '''\
  32. 3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
  33. AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
  34. ZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
  35. eSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
  36. ZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
  37. bjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
  38. ZC1CeTogbWFudWFsbHkKAMKkeXoA
  39. '''
  40. MMO_DATA = '''\
  41. 3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
  42. UHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
  43. IERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
  44. NTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
  45. ZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
  46. cGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
  47. c2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
  48. bGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
  49. '''
  50. LOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
  51. MOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
  52. UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
  53. MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
  54. class GettextBaseTest(unittest.TestCase):
  55. def setUp(self):
  56. if not os.path.isdir(LOCALEDIR):
  57. os.makedirs(LOCALEDIR)
  58. with open(MOFILE, 'wb') as fp:
  59. fp.write(base64.decodestring(GNU_MO_DATA))
  60. with open(UMOFILE, 'wb') as fp:
  61. fp.write(base64.decodestring(UMO_DATA))
  62. with open(MMOFILE, 'wb') as fp:
  63. fp.write(base64.decodestring(MMO_DATA))
  64. self.env = test_support.EnvironmentVarGuard()
  65. self.env['LANGUAGE'] = 'xx'
  66. gettext._translations.clear()
  67. def tearDown(self):
  68. self.env.__exit__()
  69. del self.env
  70. shutil.rmtree(os.path.split(LOCALEDIR)[0])
  71. GNU_MO_DATA_ISSUE_17898 = b'''\
  72. 3hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z
  73. OiBucGx1cmFscz0yOyBwbHVyYWw9KG4gIT0gMSk7CiMtIy0jLSMtIyAgbWVzc2FnZXMucG8gKEVk
  74. WCBTdHVkaW8pICAjLSMtIy0jLSMKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVU
  75. Ri04CgA=
  76. '''
  77. class GettextTestCase1(GettextBaseTest):
  78. def setUp(self):
  79. GettextBaseTest.setUp(self)
  80. self.localedir = os.curdir
  81. self.mofile = MOFILE
  82. gettext.install('gettext', self.localedir)
  83. def test_some_translations(self):
  84. eq = self.assertEqual
  85. # test some translations
  86. eq(_('albatross'), 'albatross')
  87. eq(_(u'mullusk'), 'bacon')
  88. eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
  89. eq(_(ur'nudge nudge'), 'wink wink')
  90. def test_double_quotes(self):
  91. eq = self.assertEqual
  92. # double quotes
  93. eq(_("albatross"), 'albatross')
  94. eq(_(u"mullusk"), 'bacon')
  95. eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
  96. eq(_(ur"nudge nudge"), 'wink wink')
  97. def test_triple_single_quotes(self):
  98. eq = self.assertEqual
  99. # triple single quotes
  100. eq(_('''albatross'''), 'albatross')
  101. eq(_(u'''mullusk'''), 'bacon')
  102. eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
  103. eq(_(ur'''nudge nudge'''), 'wink wink')
  104. def test_triple_double_quotes(self):
  105. eq = self.assertEqual
  106. # triple double quotes
  107. eq(_("""albatross"""), 'albatross')
  108. eq(_(u"""mullusk"""), 'bacon')
  109. eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
  110. eq(_(ur"""nudge nudge"""), 'wink wink')
  111. def test_multiline_strings(self):
  112. eq = self.assertEqual
  113. # multiline strings
  114. eq(_('''This module provides internationalization and localization
  115. support for your Python programs by providing an interface to the GNU
  116. gettext message catalog library.'''),
  117. '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
  118. fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
  119. trggrkg zrffntr pngnybt yvoenel.''')
  120. def test_the_alternative_interface(self):
  121. eq = self.assertEqual
  122. # test the alternative interface
  123. with open(self.mofile, 'rb') as fp:
  124. t = gettext.GNUTranslations(fp)
  125. # Install the translation object
  126. t.install()
  127. eq(_('nudge nudge'), 'wink wink')
  128. # Try unicode return type
  129. t.install(unicode=True)
  130. eq(_('mullusk'), 'bacon')
  131. # Test installation of other methods
  132. import __builtin__
  133. t.install(unicode=True, names=["gettext", "lgettext"])
  134. eq(_, t.ugettext)
  135. eq(__builtin__.gettext, t.ugettext)
  136. eq(lgettext, t.lgettext)
  137. del __builtin__.gettext
  138. del __builtin__.lgettext
  139. class GettextTestCase2(GettextBaseTest):
  140. def setUp(self):
  141. GettextBaseTest.setUp(self)
  142. self.localedir = os.curdir
  143. # Set up the bindings
  144. gettext.bindtextdomain('gettext', self.localedir)
  145. gettext.textdomain('gettext')
  146. # For convenience
  147. self._ = gettext.gettext
  148. def test_bindtextdomain(self):
  149. self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
  150. def test_textdomain(self):
  151. self.assertEqual(gettext.textdomain(), 'gettext')
  152. def test_some_translations(self):
  153. eq = self.assertEqual
  154. # test some translations
  155. eq(self._('albatross'), 'albatross')
  156. eq(self._(u'mullusk'), 'bacon')
  157. eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
  158. eq(self._(ur'nudge nudge'), 'wink wink')
  159. def test_double_quotes(self):
  160. eq = self.assertEqual
  161. # double quotes
  162. eq(self._("albatross"), 'albatross')
  163. eq(self._(u"mullusk"), 'bacon')
  164. eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
  165. eq(self._(ur"nudge nudge"), 'wink wink')
  166. def test_triple_single_quotes(self):
  167. eq = self.assertEqual
  168. # triple single quotes
  169. eq(self._('''albatross'''), 'albatross')
  170. eq(self._(u'''mullusk'''), 'bacon')
  171. eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
  172. eq(self._(ur'''nudge nudge'''), 'wink wink')
  173. def test_triple_double_quotes(self):
  174. eq = self.assertEqual
  175. # triple double quotes
  176. eq(self._("""albatross"""), 'albatross')
  177. eq(self._(u"""mullusk"""), 'bacon')
  178. eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
  179. eq(self._(ur"""nudge nudge"""), 'wink wink')
  180. def test_multiline_strings(self):
  181. eq = self.assertEqual
  182. # multiline strings
  183. eq(self._('''This module provides internationalization and localization
  184. support for your Python programs by providing an interface to the GNU
  185. gettext message catalog library.'''),
  186. '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
  187. fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
  188. trggrkg zrffntr pngnybt yvoenel.''')
  189. class PluralFormsTestCase(GettextBaseTest):
  190. def setUp(self):
  191. GettextBaseTest.setUp(self)
  192. self.mofile = MOFILE
  193. def test_plural_forms1(self):
  194. eq = self.assertEqual
  195. x = gettext.ngettext('There is %s file', 'There are %s files', 1)
  196. eq(x, 'Hay %s fichero')
  197. x = gettext.ngettext('There is %s file', 'There are %s files', 2)
  198. eq(x, 'Hay %s ficheros')
  199. def test_plural_forms2(self):
  200. eq = self.assertEqual
  201. with open(self.mofile, 'rb') as fp:
  202. t = gettext.GNUTranslations(fp)
  203. x = t.ngettext('There is %s file', 'There are %s files', 1)
  204. eq(x, 'Hay %s fichero')
  205. x = t.ngettext('There is %s file', 'There are %s files', 2)
  206. eq(x, 'Hay %s ficheros')
  207. def test_hu(self):
  208. eq = self.assertEqual
  209. f = gettext.c2py('0')
  210. s = ''.join([ str(f(x)) for x in range(200) ])
  211. eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
  212. def test_de(self):
  213. eq = self.assertEqual
  214. f = gettext.c2py('n != 1')
  215. s = ''.join([ str(f(x)) for x in range(200) ])
  216. eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
  217. def test_fr(self):
  218. eq = self.assertEqual
  219. f = gettext.c2py('n>1')
  220. s = ''.join([ str(f(x)) for x in range(200) ])
  221. eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
  222. def test_gd(self):
  223. eq = self.assertEqual
  224. f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
  225. s = ''.join([ str(f(x)) for x in range(200) ])
  226. eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
  227. def test_gd2(self):
  228. eq = self.assertEqual
  229. # Tests the combination of parentheses and "?:"
  230. f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
  231. s = ''.join([ str(f(x)) for x in range(200) ])
  232. eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
  233. def test_lt(self):
  234. eq = self.assertEqual
  235. f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
  236. s = ''.join([ str(f(x)) for x in range(200) ])
  237. eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
  238. def test_ru(self):
  239. eq = self.assertEqual
  240. f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
  241. s = ''.join([ str(f(x)) for x in range(200) ])
  242. eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
  243. def test_pl(self):
  244. eq = self.assertEqual
  245. f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
  246. s = ''.join([ str(f(x)) for x in range(200) ])
  247. eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
  248. def test_sl(self):
  249. eq = self.assertEqual
  250. f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
  251. s = ''.join([ str(f(x)) for x in range(200) ])
  252. eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
  253. def test_security(self):
  254. raises = self.assertRaises
  255. # Test for a dangerous expression
  256. raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
  257. class GNUTranslationParsingTest(GettextBaseTest):
  258. def test_plural_form_error_issue17898(self):
  259. with open(MOFILE, 'wb') as fp:
  260. fp.write(base64.decodestring(GNU_MO_DATA_ISSUE_17898))
  261. with open(MOFILE, 'rb') as fp:
  262. # If this runs cleanly, the bug is fixed.
  263. t = gettext.GNUTranslations(fp)
  264. class UnicodeTranslationsTest(GettextBaseTest):
  265. def setUp(self):
  266. GettextBaseTest.setUp(self)
  267. with open(UMOFILE, 'rb') as fp:
  268. self.t = gettext.GNUTranslations(fp)
  269. self._ = self.t.ugettext
  270. def test_unicode_msgid(self):
  271. unless = self.assertTrue
  272. unless(isinstance(self._(''), unicode))
  273. unless(isinstance(self._(u''), unicode))
  274. def test_unicode_msgstr(self):
  275. eq = self.assertEqual
  276. eq(self._(u'ab\xde'), u'\xa4yz')
  277. class WeirdMetadataTest(GettextBaseTest):
  278. def setUp(self):
  279. GettextBaseTest.setUp(self)
  280. with open(MMOFILE, 'rb') as fp:
  281. try:
  282. self.t = gettext.GNUTranslations(fp)
  283. except:
  284. self.tearDown()
  285. raise
  286. def test_weird_metadata(self):
  287. info = self.t.info()
  288. self.assertEqual(info['last-translator'],
  289. 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
  290. class DummyGNUTranslations(gettext.GNUTranslations):
  291. def foo(self):
  292. return 'foo'
  293. class GettextCacheTestCase(GettextBaseTest):
  294. def test_cache(self):
  295. self.localedir = os.curdir
  296. self.mofile = MOFILE
  297. self.assertEqual(len(gettext._translations), 0)
  298. t = gettext.translation('gettext', self.localedir)
  299. self.assertEqual(len(gettext._translations), 1)
  300. t = gettext.translation('gettext', self.localedir,
  301. class_=DummyGNUTranslations)
  302. self.assertEqual(len(gettext._translations), 2)
  303. self.assertEqual(t.__class__, DummyGNUTranslations)
  304. # Calling it again doesn't add to the cache
  305. t = gettext.translation('gettext', self.localedir,
  306. class_=DummyGNUTranslations)
  307. self.assertEqual(len(gettext._translations), 2)
  308. self.assertEqual(t.__class__, DummyGNUTranslations)
  309. def test_main():
  310. test_support.run_unittest(__name__)
  311. if __name__ == '__main__':
  312. test_main()
  313. # For reference, here's the .po file used to created the GNU_MO_DATA above.
  314. #
  315. # The original version was automatically generated from the sources with
  316. # pygettext. Later it was manually modified to add plural forms support.
  317. '''
  318. # Dummy translation for the Python test_gettext.py module.
  319. # Copyright (C) 2001 Python Software Foundation
  320. # Barry Warsaw <barry@python.org>, 2000.
  321. #
  322. msgid ""
  323. msgstr ""
  324. "Project-Id-Version: 2.0\n"
  325. "PO-Revision-Date: 2003-04-11 14:32-0400\n"
  326. "Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
  327. "Language-Team: XX <python-dev@python.org>\n"
  328. "MIME-Version: 1.0\n"
  329. "Content-Type: text/plain; charset=iso-8859-1\n"
  330. "Content-Transfer-Encoding: 8bit\n"
  331. "Generated-By: pygettext.py 1.1\n"
  332. "Plural-Forms: nplurals=2; plural=n!=1;\n"
  333. #: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
  334. #: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
  335. #: test_gettext.py:98
  336. msgid "nudge nudge"
  337. msgstr "wink wink"
  338. #: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
  339. #: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
  340. msgid "albatross"
  341. msgstr ""
  342. #: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
  343. #: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
  344. msgid "Raymond Luxury Yach-t"
  345. msgstr "Throatwobbler Mangrove"
  346. #: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
  347. #: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
  348. #: test_gettext.py:96
  349. msgid "mullusk"
  350. msgstr "bacon"
  351. #: test_gettext.py:40 test_gettext.py:101
  352. msgid ""
  353. "This module provides internationalization and localization\n"
  354. "support for your Python programs by providing an interface to the GNU\n"
  355. "gettext message catalog library."
  356. msgstr ""
  357. "Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
  358. "fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
  359. "trggrkg zrffntr pngnybt yvoenel."
  360. # Manually added, as neither pygettext nor xgettext support plural forms
  361. # in Python.
  362. msgid "There is %s file"
  363. msgid_plural "There are %s files"
  364. msgstr[0] "Hay %s fichero"
  365. msgstr[1] "Hay %s ficheros"
  366. '''
  367. # Here's the second example po file example, used to generate the UMO_DATA
  368. # containing utf-8 encoded Unicode strings
  369. '''
  370. # Dummy translation for the Python test_gettext.py module.
  371. # Copyright (C) 2001 Python Software Foundation
  372. # Barry Warsaw <barry@python.org>, 2000.
  373. #
  374. msgid ""
  375. msgstr ""
  376. "Project-Id-Version: 2.0\n"
  377. "PO-Revision-Date: 2003-04-11 12:42-0400\n"
  378. "Last-Translator: Barry A. WArsaw <barry@python.org>\n"
  379. "Language-Team: XX <python-dev@python.org>\n"
  380. "MIME-Version: 1.0\n"
  381. "Content-Type: text/plain; charset=utf-8\n"
  382. "Content-Transfer-Encoding: 7bit\n"
  383. "Generated-By: manually\n"
  384. #: nofile:0
  385. msgid "ab\xc3\x9e"
  386. msgstr "\xc2\xa4yz"
  387. '''
  388. # Here's the third example po file, used to generate MMO_DATA
  389. '''
  390. msgid ""
  391. msgstr ""
  392. "Project-Id-Version: No Project 0.0\n"
  393. "POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
  394. "PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
  395. "Last-Translator: John Doe <jdoe@example.com>\n"
  396. "Jane Foobar <jfoobar@example.com>\n"
  397. "Language-Team: xx <xx@example.com>\n"
  398. "MIME-Version: 1.0\n"
  399. "Content-Type: text/plain; charset=iso-8859-15\n"
  400. "Content-Transfer-Encoding: quoted-printable\n"
  401. "Generated-By: pygettext.py 1.3\n"
  402. '''
  403. #
  404. # messages.po, used for bug 17898
  405. #
  406. '''
  407. # test file for http://bugs.python.org/issue17898
  408. msgid ""
  409. msgstr ""
  410. "Plural-Forms: nplurals=2; plural=(n != 1);\n"
  411. "#-#-#-#-# messages.po (EdX Studio) #-#-#-#-#\n"
  412. "Content-Type: text/plain; charset=UTF-8\n"
  413. '''