Skip to content

Commit 3f61f23

Browse files
tomasr8ebonnal
authored andcommitted
pythongh-126700: pygettext: Support more gettext functions (pythonGH-126912)
Support multi-argument gettext functions: ngettext(), pgettext(), dgettext(), etc.
1 parent da37837 commit 3f61f23

File tree

7 files changed

+260
-90
lines changed

7 files changed

+260
-90
lines changed

Lib/test/test_tools/i18n_data/messages.pot

+34-12
Original file line numberDiff line numberDiff line change
@@ -15,53 +15,75 @@ msgstr ""
1515
"Generated-By: pygettext.py 1.5\n"
1616

1717

18-
#: messages.py:5
18+
#: messages.py:16
1919
msgid ""
2020
msgstr ""
2121

22-
#: messages.py:8 messages.py:9
22+
#: messages.py:19 messages.py:20
2323
msgid "parentheses"
2424
msgstr ""
2525

26-
#: messages.py:12
26+
#: messages.py:23
2727
msgid "Hello, world!"
2828
msgstr ""
2929

30-
#: messages.py:15
30+
#: messages.py:26
3131
msgid ""
3232
"Hello,\n"
3333
" multiline!\n"
3434
msgstr ""
3535

36-
#: messages.py:29
36+
#: messages.py:46 messages.py:89 messages.py:90 messages.py:93 messages.py:94
37+
#: messages.py:99
38+
msgid "foo"
39+
msgid_plural "foos"
40+
msgstr[0] ""
41+
msgstr[1] ""
42+
43+
#: messages.py:47
44+
msgid "something"
45+
msgstr ""
46+
47+
#: messages.py:50
3748
msgid "Hello, {}!"
3849
msgstr ""
3950

40-
#: messages.py:33
51+
#: messages.py:54
4152
msgid "1"
4253
msgstr ""
4354

44-
#: messages.py:33
55+
#: messages.py:54
4556
msgid "2"
4657
msgstr ""
4758

48-
#: messages.py:34 messages.py:35
59+
#: messages.py:55 messages.py:56
4960
msgid "A"
5061
msgstr ""
5162

52-
#: messages.py:34 messages.py:35
63+
#: messages.py:55 messages.py:56
5364
msgid "B"
5465
msgstr ""
5566

56-
#: messages.py:36
67+
#: messages.py:57
5768
msgid "set"
5869
msgstr ""
5970

60-
#: messages.py:42
71+
#: messages.py:63
6172
msgid "nested string"
6273
msgstr ""
6374

64-
#: messages.py:47
75+
#: messages.py:68
6576
msgid "baz"
6677
msgstr ""
6778

79+
#: messages.py:91 messages.py:92 messages.py:95 messages.py:96
80+
msgctxt "context"
81+
msgid "foo"
82+
msgid_plural "foos"
83+
msgstr[0] ""
84+
msgstr[1] ""
85+
86+
#: messages.py:100
87+
msgid "domain foo"
88+
msgstr ""
89+

Lib/test/test_tools/i18n_data/messages.py

+49-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Test message extraction
2-
from gettext import gettext as _
2+
from gettext import (
3+
gettext,
4+
ngettext,
5+
pgettext,
6+
npgettext,
7+
dgettext,
8+
dngettext,
9+
dpgettext,
10+
dnpgettext
11+
)
12+
13+
_ = gettext
314

415
# Empty string
516
_("")
@@ -21,13 +32,23 @@
2132
_(None)
2233
_(1)
2334
_(False)
24-
_(x="kwargs are not allowed")
35+
_(("invalid"))
36+
_(["invalid"])
37+
_({"invalid"})
38+
_("string"[3])
39+
_("string"[:3])
40+
_({"string": "foo"})
41+
42+
# pygettext does not allow keyword arguments, but both xgettext and pybabel do
43+
_(x="kwargs work!")
44+
45+
# Unusual, but valid arguments
2546
_("foo", "bar")
2647
_("something", x="something else")
2748

2849
# .format()
2950
_("Hello, {}!").format("world") # valid
30-
_("Hello, {}!".format("world")) # invalid
51+
_("Hello, {}!".format("world")) # invalid, but xgettext and pybabel extract the first string
3152

3253
# Nested structures
3354
_("1"), _("2")
@@ -62,3 +83,28 @@ def _(x):
6283

6384
def _(x="don't extract me"):
6485
pass
86+
87+
88+
# Other gettext functions
89+
gettext("foo")
90+
ngettext("foo", "foos", 1)
91+
pgettext("context", "foo")
92+
npgettext("context", "foo", "foos", 1)
93+
dgettext("domain", "foo")
94+
dngettext("domain", "foo", "foos", 1)
95+
dpgettext("domain", "context", "foo")
96+
dnpgettext("domain", "context", "foo", "foos", 1)
97+
98+
# Complex arguments
99+
ngettext("foo", "foos", 42 + (10 - 20))
100+
dgettext(["some", {"complex"}, ("argument",)], "domain foo")
101+
102+
# Invalid calls which are not extracted
103+
gettext()
104+
ngettext('foo')
105+
pgettext('context')
106+
npgettext('context', 'foo')
107+
dgettext('domain')
108+
dngettext('domain', 'foo')
109+
dpgettext('domain', 'context')
110+
dnpgettext('domain', 'context', 'foo')

Lib/test/test_tools/test_i18n.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,14 +332,14 @@ def test_calls_in_fstring_with_multiple_args(self):
332332
msgids = self.extract_docstrings_from_str(dedent('''\
333333
f"{_('foo', 'bar')}"
334334
'''))
335-
self.assertNotIn('foo', msgids)
335+
self.assertIn('foo', msgids)
336336
self.assertNotIn('bar', msgids)
337337

338338
def test_calls_in_fstring_with_keyword_args(self):
339339
msgids = self.extract_docstrings_from_str(dedent('''\
340340
f"{_('foo', bar='baz')}"
341341
'''))
342-
self.assertNotIn('foo', msgids)
342+
self.assertIn('foo', msgids)
343343
self.assertNotIn('bar', msgids)
344344
self.assertNotIn('baz', msgids)
345345

Lib/test/translationdata/argparse/msgids.txt

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ argument %(argument_name)s: %(message)s
88
argument '%(argument_name)s' is deprecated
99
can't open '%(filename)s': %(error)s
1010
command '%(parser_name)s' is deprecated
11+
conflicting option string: %s
12+
expected %s argument
1113
expected at least one argument
1214
expected at most one argument
1315
expected one argument

Lib/test/translationdata/optparse/msgids.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
%(option)s option requires %(number)d argument
12
%prog [options]
23
%s option does not take a value
34
Options
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for multi-argument :mod:`gettext` functions in :program:`pygettext.py`.

0 commit comments

Comments
 (0)