Skip to content

Commit 282a627

Browse files
committed
Keep translator comments next to the translation function call, even if the text is further away
Fixes #1195
1 parent 36fc23b commit 282a627

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

babel/messages/extract.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def extract_python(
508508
:rtype: ``iterator``
509509
"""
510510
funcname = lineno = message_lineno = None
511-
call_stack = -1
511+
call_stack = [] # line numbers of calls
512512
buf = []
513513
messages = []
514514
translator_comments = []
@@ -526,7 +526,7 @@ def extract_python(
526526
current_fstring_start = None
527527

528528
for tok, value, (lineno, _), _, _ in tokens:
529-
if call_stack == -1 and tok == NAME and value in ('def', 'class'):
529+
if not call_stack and tok == NAME and value in ('def', 'class'):
530530
in_def = True
531531
elif tok == OP and value == '(':
532532
if in_def:
@@ -535,12 +535,12 @@ def extract_python(
535535
in_def = False
536536
continue
537537
if funcname:
538-
call_stack += 1
538+
call_stack.append(lineno)
539539
elif in_def and tok == OP and value == ':':
540540
# End of a class definition without parens
541541
in_def = False
542542
continue
543-
elif call_stack == -1 and tok == COMMENT:
543+
elif not call_stack and tok == COMMENT:
544544
# Strip the comment token from the line
545545
value = value[1:].strip()
546546
if in_translator_comments and \
@@ -555,7 +555,7 @@ def extract_python(
555555
in_translator_comments = True
556556
translator_comments.append((lineno, value))
557557
break
558-
elif funcname and call_stack == 0:
558+
elif funcname and len(call_stack) == 1:
559559
nested = (tok == NAME and value in keywords)
560560
if (tok == OP and value == ')') or nested:
561561
if buf:
@@ -565,17 +565,20 @@ def extract_python(
565565
messages.append(None)
566566

567567
messages = tuple(messages) if len(messages) > 1 else messages[0]
568-
# Comments don't apply unless they immediately
569-
# precede the message
570-
if translator_comments and \
571-
translator_comments[-1][0] < message_lineno - 1:
572-
translator_comments = []
568+
569+
if translator_comments:
570+
last_comment_lineno = translator_comments[-1][0]
571+
if last_comment_lineno < min(message_lineno, call_stack[-1]) - 1:
572+
# Comments don't apply unless they immediately
573+
# precede the message, or the line where the parenthesis token
574+
# to start this message's translation call is.
575+
translator_comments.clear()
573576

574577
yield (message_lineno, funcname, messages,
575578
[comment[1] for comment in translator_comments])
576579

577580
funcname = lineno = message_lineno = None
578-
call_stack = -1
581+
call_stack.clear()
579582
messages = []
580583
translator_comments = []
581584
in_translator_comments = False
@@ -619,9 +622,9 @@ def extract_python(
619622

620623
elif tok != NL and not message_lineno:
621624
message_lineno = lineno
622-
elif call_stack > 0 and tok == OP and value == ')':
623-
call_stack -= 1
624-
elif funcname and call_stack == -1:
625+
elif len(call_stack) > 1 and tok == OP and value == ')':
626+
call_stack.pop()
627+
elif funcname and not call_stack:
625628
funcname = None
626629
elif tok == NAME and value in keywords:
627630
funcname = value

tests/messages/test_extract.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,28 @@ def test_issue_1195():
579579
assert message[0] in (5, 6) # Depends on whether #1126 is in
580580
assert message[1] == 'Text string that is on a new line'
581581
assert message[2] == ['NOTE: Text describing a test string']
582+
583+
584+
def test_issue_1195_2():
585+
buf = BytesIO(b"""
586+
# NOTE: This should still be considered, even if
587+
# the text is far away
588+
foof = _(
589+
590+
591+
592+
593+
594+
595+
596+
597+
598+
'Hey! Down here!')
599+
""")
600+
messages = list(extract.extract('python', buf, {'_': None}, ["NOTE"], {}))
601+
message = messages[0]
602+
assert message[1] == 'Hey! Down here!'
603+
assert message[2] == [
604+
'NOTE: This should still be considered, even if',
605+
'the text is far away',
606+
]

0 commit comments

Comments
 (0)