Skip to content

Commit 4aa5151

Browse files
committed
Print errors in a more structured way
1 parent ec02b07 commit 4aa5151

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

Lib/test/test_tools/test_i18n.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,10 +567,12 @@ def test_multiple_keywords_same_funcname_errors(self):
567567
self.assertEqual(msgids, [''])
568568
self.assertEqual(
569569
stderr,
570-
b'*** test.py:1: Expected a string constant for argument 1, got x\n'
571-
b'*** test.py:1: Expected a string constant for argument 2, got 42\n'
572-
b'*** test.py:2: Expected a string constant for argument 1, got 42\n'
573-
b'*** test.py:2: Expected a string constant for argument 2, got y\n')
570+
b'*** test.py:1: No keywords matched gettext call "_":\n'
571+
b'\tkeyword="_": Expected a string constant for argument 1, got x\n'
572+
b'\tkeyword="_:2": Expected a string constant for argument 2, got 42\n'
573+
b'*** test.py:2: No keywords matched gettext call "_":\n'
574+
b'\tkeyword="_": Expected a string constant for argument 1, got 42\n'
575+
b'\tkeyword="_:2": Expected a string constant for argument 2, got y\n')
574576

575577

576578
def extract_from_snapshots():

Tools/i18n/pygettext.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -490,14 +490,28 @@ def _extract_docstring(self, node):
490490
def _extract_message(self, node):
491491
func_name = self._get_func_name(node)
492492
errors = []
493-
for spec in self.options.keywords.get(func_name, []):
493+
specs = self.options.keywords.get(func_name, [])
494+
for spec in specs:
494495
err = self._extract_message_with_spec(node, spec)
495496
if err is None:
496-
break
497+
return
497498
errors.append(err)
499+
500+
if not errors:
501+
return
502+
if len(errors) == 1:
503+
print(f'*** {self.filename}:{node.lineno}: {errors[0]}',
504+
file=sys.stderr)
498505
else:
499-
for err in errors:
500-
print(err, file=sys.stderr)
506+
# There are multiple keyword specs for the function name and
507+
# none of them could be exxtracted. Print a general error
508+
# message and list the errors for each keyword spec.
509+
print(f'*** {self.filename}:{node.lineno}: '
510+
f'No keywords matched gettext call "{func_name}":',
511+
file=sys.stderr)
512+
for spec, err in zip(specs, errors, strict=True):
513+
unparsed = unparse_spec(func_name, spec)
514+
print(f'\tkeyword="{unparsed}": {err}', file=sys.stderr)
501515

502516
def _extract_message_with_spec(self, node, spec):
503517
"""Extract a gettext call with the given spec.
@@ -509,21 +523,19 @@ def _extract_message_with_spec(self, node, spec):
509523
has_var_positional = any(isinstance(arg, ast.Starred) for
510524
arg in node.args[:max_index+1])
511525
if has_var_positional:
512-
return (f'*** {self.filename}:{node.lineno}: Variable positional '
513-
f'arguments are not allowed in gettext calls')
526+
return ('Variable positional arguments are not '
527+
'allowed in gettext calls')
514528

515529
if max_index >= len(node.args):
516-
return (f'*** {self.filename}:{node.lineno}: Expected at least '
517-
f'{max_index + 1} positional argument(s) in gettext call, '
518-
f'got {len(node.args)}')
530+
return (f'Expected at least {max_index + 1} positional '
531+
f'argument(s) in gettext call, got {len(node.args)}')
519532

520533
msg_data = {}
521534
for arg_type, position in spec.items():
522535
arg = node.args[position]
523536
if not self._is_string_const(arg):
524-
return (f'*** {self.filename}:{arg.lineno}: Expected a string '
525-
f'constant for argument {position + 1}, '
526-
f'got {ast.unparse(arg)}')
537+
return (f'Expected a string constant for argument '
538+
f'{position + 1}, got {ast.unparse(arg)}')
527539
msg_data[arg_type] = arg.value
528540

529541
lineno = node.lineno

0 commit comments

Comments
 (0)