Skip to content

Commit 9f8e9b1

Browse files
committed
Do not print error messages if atleast 1 spec matches
1 parent 4426daf commit 9f8e9b1

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

Lib/test/test_tools/test_i18n.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,32 @@ def test_process_keywords(self):
543543
no_default_keywords=no_default_keywords)
544544
self.assertEqual(processed, expected)
545545

546+
def test_multiple_keywords_same_funcname_errors(self):
547+
# If at least one keyword spec for a given funcname matches,
548+
# no error should be printed.
549+
msgids, stderr = self.extract_from_str(dedent('''\
550+
_("foo", 42)
551+
_(42, "bar")
552+
'''), args=('--keyword=_:1', '--keyword=_:2'), with_stderr=True)
553+
self.assertIn('foo', msgids)
554+
self.assertIn('bar', msgids)
555+
self.assertEqual(stderr, b'')
556+
557+
# If no keyword spec for a given funcname matches,
558+
# all errors are printed.
559+
msgids, stderr = self.extract_from_str(dedent('''\
560+
_(x, 42)
561+
_(42, y)
562+
'''), args=('--keyword=_:1', '--keyword=_:2'), with_stderr=True,
563+
strict=False)
564+
self.assertEqual(msgids, [''])
565+
self.assertEqual(
566+
stderr,
567+
b'*** test.py:1: Expected a string constant for argument 1, got x\n'
568+
b'*** test.py:1: Expected a string constant for argument 2, got 42\n'
569+
b'*** test.py:2: Expected a string constant for argument 1, got 42\n'
570+
b'*** test.py:2: Expected a string constant for argument 2, got y\n')
571+
546572

547573
def extract_from_snapshots():
548574
snapshots = {

Tools/i18n/pygettext.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -475,44 +475,46 @@ def _extract_docstring(self, node):
475475

476476
def _extract_message(self, node):
477477
func_name = self._get_func_name(node)
478+
errors = []
478479
for spec in self.options.keywords.get(func_name, []):
479-
if self._extract_message_with_spec(node, spec):
480+
err = self._extract_message_with_spec(node, spec)
481+
if err is None:
480482
break
483+
errors.append(err)
484+
else:
485+
for err in errors:
486+
print(err, file=sys.stderr)
481487

482488
def _extract_message_with_spec(self, node, spec):
483489
"""Extract a gettext call with the given spec.
484490
485-
Return True if the gettext call was successfully extracted, False
486-
otherwise.
491+
Return `None` if the gettext call was successfully extracted,
492+
otherwise return an error message.
487493
"""
488494
max_index = max(spec.values())
489495
has_var_positional = any(isinstance(arg, ast.Starred) for
490496
arg in node.args[:max_index+1])
491497
if has_var_positional:
492-
print(f'*** {self.filename}:{node.lineno}: Variable positional '
493-
f'arguments are not allowed in gettext calls', file=sys.stderr)
494-
return False
498+
return (f'*** {self.filename}:{node.lineno}: Variable positional '
499+
f'arguments are not allowed in gettext calls')
495500

496501
if max_index >= len(node.args):
497-
print(f'*** {self.filename}:{node.lineno}: Expected at least '
498-
f'{max_index + 1} positional argument(s) in gettext call, '
499-
f'got {len(node.args)}', file=sys.stderr)
500-
return False
502+
return (f'*** {self.filename}:{node.lineno}: Expected at least '
503+
f'{max_index + 1} positional argument(s) in gettext call, '
504+
f'got {len(node.args)}')
501505

502506
msg_data = {}
503507
for arg_type, position in spec.items():
504508
arg = node.args[position]
505509
if not self._is_string_const(arg):
506-
print(f'*** {self.filename}:{arg.lineno}: Expected a string '
507-
f'constant for argument {position + 1}, '
508-
f'got {ast.unparse(arg)}', file=sys.stderr)
509-
return False
510+
return (f'*** {self.filename}:{arg.lineno}: Expected a string '
511+
f'constant for argument {position + 1}, '
512+
f'got {ast.unparse(arg)}')
510513
msg_data[arg_type] = arg.value
511514

512515
lineno = node.lineno
513516
comments = self._extract_comments(node)
514517
self._add_message(lineno, **msg_data, comments=comments)
515-
return True
516518

517519
def _extract_comments(self, node):
518520
"""Extract translator comments.

0 commit comments

Comments
 (0)