Merge lp:~danilo/pygettextpo/msgctxt-support into lp:pygettextpo

Proposed by Данило Шеган
Status: Needs review
Proposed branch: lp:~danilo/pygettextpo/msgctxt-support
Merge into: lp:pygettextpo
Prerequisite: lp:~danilo/pygettextpo/simplify
Diff against target: 303 lines (+96/-93)
2 files modified
gettextpo.c (+82/-92)
test_gettextpo.py (+14/-1)
To merge this branch: bzr merge lp:~danilo/pygettextpo/msgctxt-support
Reviewer Review Type Date Requested Status
Benji York (community) code Approve
Review via email: mp+92726@code.launchpad.net

Description of the change

Provide support for msgctxt field in GNU gettext PO files.

This depends on the 'simplify' branch which simplifies the C code to reduce repeating of the same pattern. A new test is added to ensure this works like the other fields.

http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files

To post a comment you must log in.
Revision history for this message
Benji York (benji) wrote :

Looks good.

review: Approve (code)
Revision history for this message
Colin Watson (cjwatson) wrote :

I've converted pygettextpo to git and merged this branch (though I can't mark this MP as Merged):

  https://git.launchpad.net/pygettextpo/commit/?id=771d6e7853f6149cec3cf93aa0ab58a397ff11c5

Unmerged revisions

29. By Данило Шеган

Re-merge simplify branch.

28. By Данило Шеган

Merge 'simplify' branch, make use of the refactoring for set_msgctxt.

27. By Данило Шеган

Merge pep8-fixes branch.

26. By Данило Шеган

Make msgctxt support conditional.

25. By Данило Шеган

Add msgctxt support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'gettextpo.c'
2--- gettextpo.c 2009-06-02 15:31:25 +0000
3+++ gettextpo.c 2012-02-13 10:08:18 +0000
4@@ -11,6 +11,7 @@
5 #include <gettext-po.h>
6
7 #define MIN_REQUIRED_GETTEXTPO_VERSION 0x000E02
8+#define MIN_MSGCTXT_GETTEXTPO_VERSION 0x000F00
9
10 #if LIBGETTEXTPO_VERSION < MIN_REQUIRED_GETTEXTPO_VERSION
11 # error "this module requires gettext >= 0.14.2"
12@@ -533,35 +534,60 @@
13 return res;
14 }
15
16+typedef void (po_value_setter_t)(po_message_t, const char *);
17+
18+static PyObject *
19+_message_set_field(PyPoMessage *self, PyObject *args, const char *field,
20+ po_value_setter_t * setter)
21+{
22+ const char *value;
23+ PyObject *object;
24+ PyObject *string;
25+
26+ if (!PyArg_ParseTuple(args, field, &object))
27+ return NULL;
28+
29+ if (object == Py_None) {
30+ (*setter)(self->msg, NULL);
31+ } else {
32+ string = get_pystring_from_pyobject(object);
33+
34+ if (string == NULL)
35+ /* Got an exception */
36+ return NULL;
37+ else {
38+ value = PyString_AsString(string);
39+ (*setter)(self->msg, value);
40+ Py_DECREF(string);
41+ }
42+ }
43+
44+ Py_RETURN_NONE;
45+}
46+
47+/* msgctxt support was added in 0.15. */
48+#if LIBGETTEXTPO_VERSION >= MIN_MSGCTXT_GETTEXTPO_VERSION
49+
50+PyDoc_STRVAR(doc_pypo_message_set_msgctxt,
51+"M.set_msgctxt(msgctxt) -> None. Set the msgctxt for this PoMessage");
52+
53+static PyObject *
54+pypo_message_set_msgctxt(PyPoMessage *self, PyObject *args)
55+{
56+ return _message_set_field(self, args, "O:set_msgctxt",
57+ &po_message_set_msgctxt);
58+}
59+#endif
60+
61+
62 PyDoc_STRVAR(doc_pypo_message_set_msgid,
63 "M.set_msgid(msgid) -> None. Set the msgid for this PoMessage");
64
65 static PyObject *
66 pypo_message_set_msgid(PyPoMessage *self, PyObject *args)
67 {
68- const char *msgid;
69- PyObject *object;
70- PyObject *string;
71-
72- if (!PyArg_ParseTuple(args, "O:set_msgid", &object))
73- return NULL;
74-
75- if (object == Py_None) {
76- po_message_set_msgid(self->msg, NULL);
77- } else {
78- string = get_pystring_from_pyobject(object);
79-
80- if (string == NULL)
81- /* Got an exception */
82- return NULL;
83- else {
84- msgid = PyString_AsString(string);
85- po_message_set_msgid(self->msg, msgid);
86- Py_DECREF(string);
87- }
88- }
89-
90- Py_RETURN_NONE;
91+ return _message_set_field(self, args, "O:set_msgid",
92+ &po_message_set_msgid);
93 }
94
95 PyDoc_STRVAR(doc_pypo_message_set_msgid_plural,
96@@ -571,29 +597,8 @@
97 static PyObject *
98 pypo_message_set_msgid_plural(PyPoMessage *self, PyObject *args)
99 {
100- const char *msgid;
101- PyObject *object;
102- PyObject *string;
103-
104- if (!PyArg_ParseTuple(args, "O:set_msgid_plural", &object))
105- return NULL;
106-
107- if (object == Py_None) {
108- po_message_set_msgid_plural(self->msg, NULL);
109- } else {
110- string = get_pystring_from_pyobject(object);
111-
112- if (string == NULL)
113- /* Got an exception */
114- return NULL;
115- else {
116- msgid = PyString_AsString(string);
117- po_message_set_msgid_plural(self->msg, msgid);
118- Py_DECREF(string);
119- }
120- }
121-
122- Py_RETURN_NONE;
123+ return _message_set_field(self, args, "O:set_msgid_plural",
124+ &po_message_set_msgid_plural);
125 }
126
127 PyDoc_STRVAR(doc_pypo_message_set_msgstr,
128@@ -602,29 +607,8 @@
129 static PyObject *
130 pypo_message_set_msgstr(PyPoMessage *self, PyObject *args)
131 {
132- const char *msgstr;
133- PyObject *object;
134- PyObject *string;
135-
136- if (!PyArg_ParseTuple(args, "O:set_msgstr", &object))
137- return NULL;
138-
139- if (object == Py_None) {
140- po_message_set_msgstr(self->msg, NULL);
141- } else {
142- string = get_pystring_from_pyobject(object);
143-
144- if (string == NULL)
145- /* Got an exception */
146- return NULL;
147- else {
148- msgstr = PyString_AsString(string);
149- po_message_set_msgstr(self->msg, msgstr);
150- Py_DECREF(string);
151- }
152- }
153-
154- Py_RETURN_NONE;
155+ return _message_set_field(self, args, "O:set_msgstr",
156+ &po_message_set_msgstr);
157 }
158
159 PyDoc_STRVAR(doc_pypo_message_set_msgstr_plural,
160@@ -675,29 +659,8 @@
161 static PyObject *
162 pypo_message_set_comments(PyPoMessage *self, PyObject *args)
163 {
164- const char *comments;
165- PyObject *object;
166- PyObject *string;
167-
168- if (!PyArg_ParseTuple(args, "O:set_comments", &object))
169- return NULL;
170-
171- if (object == Py_None) {
172- po_message_set_comments(self->msg, NULL);
173- } else {
174- string = get_pystring_from_pyobject(object);
175-
176- if (string == NULL)
177- /* Got an exception */
178- return NULL;
179- else {
180- comments = PyString_AsString(string);
181- po_message_set_comments(self->msg, comments);
182- Py_DECREF(string);
183- }
184- }
185-
186- Py_RETURN_NONE;
187+ return _message_set_field(self, args, "O:set_comments",
188+ &po_message_set_comments);
189 }
190
191 PyDoc_STRVAR(doc_pypo_message_set_format,
192@@ -779,6 +742,11 @@
193 }
194
195 static PyMethodDef pypo_message_methods[] = {
196+/* msgctxt support was added in 0.15. */
197+#if LIBGETTEXTPO_VERSION >= MIN_MSGCTXT_GETTEXTPO_VERSION
198+ { "set_msgctxt", (PyCFunction)pypo_message_set_msgctxt, METH_VARARGS,
199+ doc_pypo_message_set_msgctxt },
200+#endif
201 { "set_msgid", (PyCFunction)pypo_message_set_msgid, METH_VARARGS,
202 doc_pypo_message_set_msgid },
203 { "set_msgid_plural", (PyCFunction)pypo_message_set_msgid_plural, METH_VARARGS,
204@@ -796,6 +764,23 @@
205 { NULL, 0, 0 }
206 };
207
208+/* msgctxt support was added in 0.15. */
209+#if LIBGETTEXTPO_VERSION >= MIN_MSGCTXT_GETTEXTPO_VERSION
210+PyDoc_STRVAR(doc_pypo_message_msgctxt,
211+"M.msgctxt -> the msgctxt for this PoMessage.");
212+
213+static PyObject *
214+pypo_message_get_msgctxt(PyPoMessage *self, void *closure)
215+{
216+ const char *msgctxt;
217+
218+ msgctxt = po_message_msgctxt(self->msg);
219+ if (msgctxt)
220+ return PyString_FromString(msgctxt);
221+ Py_RETURN_NONE;
222+}
223+#endif
224+
225 PyDoc_STRVAR(doc_pypo_message_msgid,
226 "M.msgid -> the msgid for this PoMessage.");
227
228@@ -878,6 +863,11 @@
229
230
231 static PyGetSetDef pypo_message_getsets[] = {
232+/* msgctxt support was added in 0.15. */
233+#if LIBGETTEXTPO_VERSION >= MIN_MSGCTXT_GETTEXTPO_VERSION
234+ { "msgctxt", (getter)pypo_message_get_msgctxt, (setter)0,
235+ doc_pypo_message_msgctxt },
236+#endif
237 { "msgid", (getter)pypo_message_get_msgid, (setter)0,
238 doc_pypo_message_msgid },
239 { "msgid_plural", (getter)pypo_message_get_msgid_plural, (setter)0,
240
241=== modified file 'test_gettextpo.py'
242--- test_gettextpo.py 2009-06-02 15:31:25 +0000
243+++ test_gettextpo.py 2012-02-13 10:08:18 +0000
244@@ -4,11 +4,14 @@
245 import unittest
246 import gettextpo
247
248+
249 class PoFileTestCase(unittest.TestCase):
250+
251 def testCreateEmpty(self):
252 # Test that we can create an empty pofile object
253 pofile = gettextpo.PoFile()
254 self.assertEquals(list(iter(pofile)), [])
255+
256 def testAddMessage(self):
257 # Test that we can add messages to a new pofile object
258 pofile = gettextpo.PoFile()
259@@ -18,6 +21,7 @@
260 poiter.insert(msg)
261
262 self.assertEquals(list(iter(pofile)), [msg])
263+
264 def testAddMessageTwice(self):
265 # A message object can only be added to one pofile object
266 pofile1 = gettextpo.PoFile()
267@@ -31,7 +35,9 @@
268 poiter = iter(pofile2)
269 self.assertRaises(ValueError, poiter.insert, msg)
270
271+
272 class PoMessageTestCase(unittest.TestCase):
273+
274 def testCreateMessage(self):
275 # Test that messages can be created.
276 msg = gettextpo.PoMessage()
277@@ -43,11 +49,16 @@
278 msg.set_msgid_plural('Hellos')
279 self.assertEquals(msg.msgid_plural, 'Hellos')
280
281+ def testSetMsgCtxt(self):
282+ msg = gettextpo.PoMessage()
283+ msg.set_msgctxt('Hello')
284+ self.assertEquals(msg.msgctxt, 'Hello')
285+
286 def testSetMsgStr(self):
287 msg = gettextpo.PoMessage()
288 msg.set_msgstr('Hello World')
289 self.assertEquals(msg.msgstr, 'Hello World')
290-
291+
292 def testSetMsgStrPlural(self):
293 # Test handling of plural msgstrs. The PoMessage object can
294 # not hold plural msgstrs if the msgid does not have a plural.
295@@ -63,7 +74,9 @@
296 msg.set_msgstr_plural(2, 'Two')
297 self.assertEquals(msg.msgstr_plural, ['Zero', 'One', 'Two'])
298
299+
300 class CheckFormatTestCase(unittest.TestCase):
301+
302 def testGoodFormat(self):
303 # Check that no exception is raised on a good translation.
304

Subscribers

People subscribed via source and target branches