test_gettext.py revision be8d06f5234ace688520bfea9139e68214788910
19e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawimport os
2ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsawimport base64
3a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawimport shutil
49e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawimport gettext
5d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisimport unittest
6a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
7ee8712cda46338d223509cc5751fd36509ad3860Benjamin Petersonfrom test import support
8a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
9004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake
10d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# TODO:
11d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis#  - Add new tests, for example for "dgettext"
12d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis#  - Remove dummy tests, for example testing for single and double quotes
13d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis#    has no sense, it would have if we were testing a parser (i.e. pygettext)
14d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis#  - Tests should have only one assert.
1564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
1639478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumGNU_MO_DATA = b'''\
17d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
18d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
19d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
20d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwiseW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
21d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
22d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
23d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
24d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
25d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
26d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
27d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
28d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
29d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
30d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisd29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
31d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwiseXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
32d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
33d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
34d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis'''
35d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
36be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# This data contains an invalid major version number (5)
37be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# An unexpected major version number should be treated as an error when
38be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# parsing a .mo file
39be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
40be8d06f5234ace688520bfea9139e68214788910Antoine PitrouGNU_MO_DATA_BAD_MAJOR_VERSION = b'''\
41be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou3hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
42be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
43be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
44be8d06f5234ace688520bfea9139e68214788910Antoine PitroueW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
45be8d06f5234ace688520bfea9139e68214788910Antoine PitrouaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
46be8d06f5234ace688520bfea9139e68214788910Antoine PitrouCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
47be8d06f5234ace688520bfea9139e68214788910Antoine PitrouY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
48be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
49be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
50be8d06f5234ace688520bfea9139e68214788910Antoine PitrouYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
51be8d06f5234ace688520bfea9139e68214788910Antoine PitrouSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
52be8d06f5234ace688520bfea9139e68214788910Antoine PitrouNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
53be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
54be8d06f5234ace688520bfea9139e68214788910Antoine Pitroud29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
55be8d06f5234ace688520bfea9139e68214788910Antoine PitroueXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
56be8d06f5234ace688520bfea9139e68214788910Antoine PitrouIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
57be8d06f5234ace688520bfea9139e68214788910Antoine PitrouciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
58be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou'''
59be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
60be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# This data contains an invalid minor version number (7)
61be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# An unexpected minor version number only indicates that some of the file's
62be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# contents may not be able to be read. It does not indicate an error.
63be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
64be8d06f5234ace688520bfea9139e68214788910Antoine PitrouGNU_MO_DATA_BAD_MINOR_VERSION = b'''\
65be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou3hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj
66be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD
67be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh
68be8d06f5234ace688520bfea9139e68214788910Antoine PitroueW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU
69be8d06f5234ace688520bfea9139e68214788910Antoine PitrouaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u
70be8d06f5234ace688520bfea9139e68214788910Antoine PitrouCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh
71be8d06f5234ace688520bfea9139e68214788910Antoine PitrouY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51
72be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt
73be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k
74be8d06f5234ace688520bfea9139e68214788910Antoine PitrouYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN
75be8d06f5234ace688520bfea9139e68214788910Antoine PitrouSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4
76be8d06f5234ace688520bfea9139e68214788910Antoine PitrouNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0
77be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0
78be8d06f5234ace688520bfea9139e68214788910Antoine Pitroud29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo
79be8d06f5234ace688520bfea9139e68214788910Antoine PitroueXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn
80be8d06f5234ace688520bfea9139e68214788910Antoine PitrouIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1
81be8d06f5234ace688520bfea9139e68214788910Antoine PitrouciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA==
82be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou'''
83be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
84be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
8539478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumUMO_DATA = b'''\
86a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm
87a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawAQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S
88a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy
89a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsaweSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t
90a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp
91a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawbjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl
92a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZC1CeTogbWFudWFsbHkKAMKkeXoA
93a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw'''
94d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
9539478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumMMO_DATA = b'''\
96e960e22579838419541357712bbbc3317c219071Barry Warsaw3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA
97e960e22579838419541357712bbbc3317c219071Barry WarsawUHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk
98e960e22579838419541357712bbbc3317c219071Barry WarsawIERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6
99e960e22579838419541357712bbbc3317c219071Barry WarsawNTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu
100e960e22579838419541357712bbbc3317c219071Barry WarsawZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt
101e960e22579838419541357712bbbc3317c219071Barry WarsawcGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy
102e960e22579838419541357712bbbc3317c219071Barry Warsawc2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi
103e960e22579838419541357712bbbc3317c219071Barry WarsawbGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA=
104e960e22579838419541357712bbbc3317c219071Barry Warsaw'''
105e960e22579838419541357712bbbc3317c219071Barry Warsaw
106d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisLOCALEDIR = os.path.join('xx', 'LC_MESSAGES')
107d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisMOFILE = os.path.join(LOCALEDIR, 'gettext.mo')
108be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo')
109be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo')
110a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawUMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo')
111e960e22579838419541357712bbbc3317c219071Barry WarsawMMOFILE = os.path.join(LOCALEDIR, 'metadata.mo')
112d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
113d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
114a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextBaseTest(unittest.TestCase):
115a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    def setUp(self):
116a0e0cd3013840299a789f05be239d6ecb6387cdfNeal Norwitz        if not os.path.isdir(LOCALEDIR):
117a0e0cd3013840299a789f05be239d6ecb6387cdfNeal Norwitz            os.makedirs(LOCALEDIR)
1187fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(MOFILE, 'wb') as fp:
1197fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo            fp.write(base64.decodebytes(GNU_MO_DATA))
120be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou        with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp:
121be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION))
122be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou        with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp:
123be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION))
1247fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(UMOFILE, 'wb') as fp:
1257fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo            fp.write(base64.decodebytes(UMO_DATA))
1267fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(MMOFILE, 'wb') as fp:
1277fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo            fp.write(base64.decodebytes(MMO_DATA))
128155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald        self.env = support.EnvironmentVarGuard()
129155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald        self.env['LANGUAGE'] = 'xx'
13037a89334da1fbe5b30f5a03a97b8f8c2a59adc1bÉric Araujo        gettext._translations.clear()
131a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
132a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    def tearDown(self):
133155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald        self.env.__exit__()
134155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald        del self.env
135cdb2c601db078e0af2fcca49341a7d17d603e500Victor Stinner        support.rmtree(os.path.split(LOCALEDIR)[0])
136d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
137ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
138a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextTestCase1(GettextBaseTest):
139d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def setUp(self):
140a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        GettextBaseTest.setUp(self)
141d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        self.localedir = os.curdir
142d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        self.mofile = MOFILE
143d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        gettext.install('gettext', self.localedir)
144ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
145d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_some_translations(self):
146a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
147d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # test some translations
148a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_('albatross'), 'albatross')
149ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_('mullusk'), 'bacon')
150a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
151ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_(r'nudge nudge'), 'wink wink')
152d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
153d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_double_quotes(self):
154a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
155d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # double quotes
156a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_("albatross"), 'albatross')
157ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_("mullusk"), 'bacon')
158a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
159ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_(r"nudge nudge"), 'wink wink')
160d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
161d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_triple_single_quotes(self):
162a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
163d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # triple single quotes
164a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_('''albatross'''), 'albatross')
165ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_('''mullusk'''), 'bacon')
166a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
167ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_(r'''nudge nudge'''), 'wink wink')
168d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
169d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_triple_double_quotes(self):
170a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
171d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # triple double quotes
172a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_("""albatross"""), 'albatross')
173ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_("""mullusk"""), 'bacon')
174a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
175ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(_(r"""nudge nudge"""), 'wink wink')
176d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
177d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_multiline_strings(self):
178a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
179d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # multiline strings
180a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_('''This module provides internationalization and localization
1819e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawsupport for your Python programs by providing an interface to the GNU
182a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawgettext message catalog library.'''),
183a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw           '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
184d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisfhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
185a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawtrggrkg zrffntr pngnybt yvoenel.''')
186ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
187d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_the_alternative_interface(self):
188a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
189d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # test the alternative interface
1907fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(self.mofile, 'rb') as fp:
1917fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo            t = gettext.GNUTranslations(fp)
192a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        # Install the translation object
193d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        t.install()
194a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_('nudge nudge'), 'wink wink')
195a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        # Try unicode return type
196801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson        t.install()
197a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(_('mullusk'), 'bacon')
198602b9ba6b37c4ac4ed445f8c9e9dccd68d631899Georg Brandl        # Test installation of other methods
1991a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl        import builtins
200801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson        t.install(names=["gettext", "lgettext"])
201801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson        eq(_, t.gettext)
202801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson        eq(builtins.gettext, t.gettext)
203602b9ba6b37c4ac4ed445f8c9e9dccd68d631899Georg Brandl        eq(lgettext, t.lgettext)
2041a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl        del builtins.gettext
2051a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl        del builtins.lgettext
206d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
207ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
208a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextTestCase2(GettextBaseTest):
209d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def setUp(self):
210a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        GettextBaseTest.setUp(self)
211d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        self.localedir = os.curdir
212a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        # Set up the bindings
213d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        gettext.bindtextdomain('gettext', self.localedir)
214d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        gettext.textdomain('gettext')
215a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        # For convenience
216d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        self._ = gettext.gettext
21764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
218d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_bindtextdomain(self):
219a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir)
22064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
221d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_textdomain(self):
222a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        self.assertEqual(gettext.textdomain(), 'gettext')
22364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
224be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou    def test_bad_major_version(self):
225be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou        with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp:
226be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            with self.assertRaises(OSError) as cm:
227be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou                gettext.GNUTranslations(fp)
228be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
229be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            exception = cm.exception
230be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            self.assertEqual(exception.errno, 0)
231be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            self.assertEqual(exception.strerror, "Bad version number 5")
232be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION)
233be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
234be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou    def test_bad_minor_version(self):
235be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou        with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp:
236be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            # Check that no error is thrown with a bad minor version number
237be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou            gettext.GNUTranslations(fp)
238be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou
239d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_some_translations(self):
240a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
241d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # test some translations
242a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._('albatross'), 'albatross')
243ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._('mullusk'), 'bacon')
244a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove')
245ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._(r'nudge nudge'), 'wink wink')
24664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
247d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_double_quotes(self):
248a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
249d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # double quotes
250a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._("albatross"), 'albatross')
251ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._("mullusk"), 'bacon')
252a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
253ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._(r"nudge nudge"), 'wink wink')
254d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
255d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_triple_single_quotes(self):
256a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
257d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # triple single quotes
258a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._('''albatross'''), 'albatross')
259ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._('''mullusk'''), 'bacon')
260a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
261ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._(r'''nudge nudge'''), 'wink wink')
262d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
263d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_triple_double_quotes(self):
264a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
265d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # triple double quotes
266a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._("""albatross"""), 'albatross')
267ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._("""mullusk"""), 'bacon')
268a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
269ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._(r"""nudge nudge"""), 'wink wink')
270d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
271d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_multiline_strings(self):
272a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
273d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # multiline strings
274a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(self._('''This module provides internationalization and localization
27564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawsupport for your Python programs by providing an interface to the GNU
276a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawgettext message catalog library.'''),
277a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw           '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba
278d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisfhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH
279a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawtrggrkg zrffntr pngnybt yvoenel.''')
28064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
28164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
282a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass PluralFormsTestCase(GettextBaseTest):
283d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def setUp(self):
284a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        GettextBaseTest.setUp(self)
285d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        self.mofile = MOFILE
286ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
287d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_plural_forms1(self):
288a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
289d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        x = gettext.ngettext('There is %s file', 'There are %s files', 1)
290a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(x, 'Hay %s fichero')
291d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        x = gettext.ngettext('There is %s file', 'There are %s files', 2)
292a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(x, 'Hay %s ficheros')
293ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
294d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_plural_forms2(self):
295a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
2967fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(self.mofile, 'rb') as fp:
2977fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo            t = gettext.GNUTranslations(fp)
298d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        x = t.ngettext('There is %s file', 'There are %s files', 1)
299a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(x, 'Hay %s fichero')
300d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        x = t.ngettext('There is %s file', 'There are %s files', 2)
301a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(x, 'Hay %s ficheros')
302d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
303d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_hu(self):
304a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
305d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('0')
306d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
307a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
308d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
309d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_de(self):
310a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
311d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n != 1')
312d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
313a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
314d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
315d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_fr(self):
316a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
317d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n>1')
318d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
319a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
320ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw
321d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_gd(self):
322a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
323d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2')
324d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
325a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
326d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
327d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_gd2(self):
328a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
329d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # Tests the combination of parentheses and "?:"
330d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)')
331d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
332a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
333d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
334d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_lt(self):
335a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
336d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2')
337d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
338a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111")
339d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
340d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_ru(self):
341a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
342d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
343d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
344a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222")
345d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
346d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_pl(self):
347a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
348d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2')
349d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
350a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222")
351d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
352d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_sl(self):
353a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
354d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3')
355d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        s = ''.join([ str(f(x)) for x in range(200) ])
356a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333")
357d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
358d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis    def test_security(self):
359a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        raises = self.assertRaises
360d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis        # Test for a dangerous expression
361a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)")
362a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
363a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
364a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass UnicodeTranslationsTest(GettextBaseTest):
365a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    def setUp(self):
366a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        GettextBaseTest.setUp(self)
3677fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(UMOFILE, 'rb') as fp:
368edb155fda199f7fa481d0020e911a6eec0705dfaBarry Warsaw            self.t = gettext.GNUTranslations(fp)
369801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson        self._ = self.t.gettext
370d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
371a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    def test_unicode_msgid(self):
372c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson        unless = self.assertTrue
373ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        unless(isinstance(self._(''), str))
374ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        unless(isinstance(self._(''), str))
375d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
376a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    def test_unicode_msgstr(self):
377a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw        eq = self.assertEqual
378ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum        eq(self._('ab\xde'), '\xa4yz')
379d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
380d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
381e960e22579838419541357712bbbc3317c219071Barry Warsawclass WeirdMetadataTest(GettextBaseTest):
382e960e22579838419541357712bbbc3317c219071Barry Warsaw    def setUp(self):
383e960e22579838419541357712bbbc3317c219071Barry Warsaw        GettextBaseTest.setUp(self)
3847fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo        with open(MMOFILE, 'rb') as fp:
385e960e22579838419541357712bbbc3317c219071Barry Warsaw            try:
386e960e22579838419541357712bbbc3317c219071Barry Warsaw                self.t = gettext.GNUTranslations(fp)
387e960e22579838419541357712bbbc3317c219071Barry Warsaw            except:
388e960e22579838419541357712bbbc3317c219071Barry Warsaw                self.tearDown()
389e960e22579838419541357712bbbc3317c219071Barry Warsaw                raise
390e960e22579838419541357712bbbc3317c219071Barry Warsaw
391e960e22579838419541357712bbbc3317c219071Barry Warsaw    def test_weird_metadata(self):
392e960e22579838419541357712bbbc3317c219071Barry Warsaw        info = self.t.info()
3936ae5d7f2a132aa9690bfb59b8eebcc1fb7c792c8Christian Heimes        self.assertEqual(len(info), 9)
394e960e22579838419541357712bbbc3317c219071Barry Warsaw        self.assertEqual(info['last-translator'],
395e960e22579838419541357712bbbc3317c219071Barry Warsaw           'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>')
396e960e22579838419541357712bbbc3317c219071Barry Warsaw
397e960e22579838419541357712bbbc3317c219071Barry Warsaw
3986108bf5ed002925f2092deb025f336d8c2024299Éric Araujoclass DummyGNUTranslations(gettext.GNUTranslations):
3996108bf5ed002925f2092deb025f336d8c2024299Éric Araujo    def foo(self):
4006108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        return 'foo'
4016108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4026108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4036108bf5ed002925f2092deb025f336d8c2024299Éric Araujoclass GettextCacheTestCase(GettextBaseTest):
4046108bf5ed002925f2092deb025f336d8c2024299Éric Araujo    def test_cache(self):
4056108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.localedir = os.curdir
4066108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.mofile = MOFILE
4076108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4086108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(len(gettext._translations), 0)
4096108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4106108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        t = gettext.translation('gettext', self.localedir)
4116108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4126108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(len(gettext._translations), 1)
4136108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4146108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        t = gettext.translation('gettext', self.localedir,
4156108bf5ed002925f2092deb025f336d8c2024299Éric Araujo                                class_=DummyGNUTranslations)
4166108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4176108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(len(gettext._translations), 2)
4186108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(t.__class__, DummyGNUTranslations)
4196108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4206108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        # Calling it again doesn't add to the cache
4216108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4226108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        t = gettext.translation('gettext', self.localedir,
4236108bf5ed002925f2092deb025f336d8c2024299Éric Araujo                                class_=DummyGNUTranslations)
4246108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4256108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(len(gettext._translations), 2)
4266108bf5ed002925f2092deb025f336d8c2024299Éric Araujo        self.assertEqual(t.__class__, DummyGNUTranslations)
4276108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
4286108bf5ed002925f2092deb025f336d8c2024299Éric Araujo
429a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawdef test_main():
430ee8712cda46338d223509cc5751fd36509ad3860Benjamin Peterson    support.run_unittest(__name__)
431004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake
432a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawif __name__ == '__main__':
433a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw    test_main()
434a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
435a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
436a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# For reference, here's the .po file used to created the GNU_MO_DATA above.
437d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis#
438d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# The original version was automatically generated from the sources with
439d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# pygettext. Later it was manually modified to add plural forms support.
44064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
44164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw'''
442a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Dummy translation for the Python test_gettext.py module.
443191487351abb5d2b7daf9d839ca2b3a3c7fdc07bBarry Warsaw# Copyright (C) 2001 Python Software Foundation
444191487351abb5d2b7daf9d839ca2b3a3c7fdc07bBarry Warsaw# Barry Warsaw <barry@python.org>, 2000.
44564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#
44664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid ""
44764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr ""
44864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Project-Id-Version: 2.0\n"
449a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"PO-Revision-Date: 2003-04-11 14:32-0400\n"
450d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Last-Translator: J. David Ibanez <j-david@noos.fr>\n"
45164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Language-Team: XX <python-dev@python.org>\n"
45264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"MIME-Version: 1.0\n"
453d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Content-Type: text/plain; charset=iso-8859-1\n"
454d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Content-Transfer-Encoding: 8bit\n"
45564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Generated-By: pygettext.py 1.1\n"
456d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Plural-Forms: nplurals=2; plural=n!=1;\n"
45764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
45864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37
45964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92
46064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:98
46164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "nudge nudge"
46264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "wink wink"
46364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
46464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34
46564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95
46664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "albatross"
46764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr ""
46864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
46964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36
47064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97
47164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "Raymond Luxury Yach-t"
47264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "Throatwobbler Mangrove"
47364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
47464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35
47564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90
47664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:96
47764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "mullusk"
47864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "bacon"
47964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw
48064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:40 test_gettext.py:101
48164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid ""
48264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"This module provides internationalization and localization\n"
48364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"support for your Python programs by providing an interface to the GNU\n"
48464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"gettext message catalog library."
48564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr ""
48664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n"
48764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n"
48864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"trggrkg zrffntr pngnybt yvoenel."
489d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis
490d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# Manually added, as neither pygettext nor xgettext support plural forms
491d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# in Python.
492d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgid "There is %s file"
493d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgid_plural "There are %s files"
494d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgstr[0] "Hay %s fichero"
495d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgstr[1] "Hay %s ficheros"
49664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw'''
497a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
498a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Here's the second example po file example, used to generate the UMO_DATA
499a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# containing utf-8 encoded Unicode strings
500a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
501a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw'''
502a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Dummy translation for the Python test_gettext.py module.
503a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Copyright (C) 2001 Python Software Foundation
504a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Barry Warsaw <barry@python.org>, 2000.
505a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw#
506a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgid ""
507a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgstr ""
508a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Project-Id-Version: 2.0\n"
509a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"PO-Revision-Date: 2003-04-11 12:42-0400\n"
510a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Last-Translator: Barry A. WArsaw <barry@python.org>\n"
511a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Language-Team: XX <python-dev@python.org>\n"
512a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"MIME-Version: 1.0\n"
513a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Content-Type: text/plain; charset=utf-8\n"
514a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Content-Transfer-Encoding: 7bit\n"
515a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Generated-By: manually\n"
516a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw
517a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw#: nofile:0
518a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgid "ab\xc3\x9e"
519a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgstr "\xc2\xa4yz"
520a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw'''
521e960e22579838419541357712bbbc3317c219071Barry Warsaw
522e960e22579838419541357712bbbc3317c219071Barry Warsaw# Here's the third example po file, used to generate MMO_DATA
523e960e22579838419541357712bbbc3317c219071Barry Warsaw
524e960e22579838419541357712bbbc3317c219071Barry Warsaw'''
525e960e22579838419541357712bbbc3317c219071Barry Warsawmsgid ""
526e960e22579838419541357712bbbc3317c219071Barry Warsawmsgstr ""
527e960e22579838419541357712bbbc3317c219071Barry Warsaw"Project-Id-Version: No Project 0.0\n"
528e960e22579838419541357712bbbc3317c219071Barry Warsaw"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n"
529e960e22579838419541357712bbbc3317c219071Barry Warsaw"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n"
530e960e22579838419541357712bbbc3317c219071Barry Warsaw"Last-Translator: John Doe <jdoe@example.com>\n"
531e960e22579838419541357712bbbc3317c219071Barry Warsaw"Jane Foobar <jfoobar@example.com>\n"
532e960e22579838419541357712bbbc3317c219071Barry Warsaw"Language-Team: xx <xx@example.com>\n"
533e960e22579838419541357712bbbc3317c219071Barry Warsaw"MIME-Version: 1.0\n"
534e960e22579838419541357712bbbc3317c219071Barry Warsaw"Content-Type: text/plain; charset=iso-8859-15\n"
535e960e22579838419541357712bbbc3317c219071Barry Warsaw"Content-Transfer-Encoding: quoted-printable\n"
536e960e22579838419541357712bbbc3317c219071Barry Warsaw"Generated-By: pygettext.py 1.3\n"
537e960e22579838419541357712bbbc3317c219071Barry Warsaw'''
538