Skip to content

Commit a53028d

Browse files
rdlukaszszPCManticore
authored andcommitted
Fix ifs in formatted strings crashing Pylint
1 parent 0fc0440 commit a53028d

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

pylint/checkers/refactoring.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ def __init__(self, linter=None):
118118
def _init(self):
119119
self._nested_blocks = []
120120
self._elifs = []
121-
self._if_counter = 0
122121
self._nested_blocks_msg = None
123122

124123
@decorators.cachedproperty
@@ -144,7 +143,7 @@ def _is_actual_elif(self, node):
144143
orelse = node.parent.orelse
145144
# current if node must directly follow a "else"
146145
if orelse and orelse == [node]:
147-
if self._elifs[self._if_counter]:
146+
if (node.lineno, node.col_offset) in self._elifs:
148147
return True
149148
return False
150149

@@ -208,9 +207,13 @@ def process_tokens(self, tokens):
208207
for index, token in enumerate(tokens):
209208
token_string = token[1]
210209
if token_string == 'elif':
211-
self._elifs.append(True)
212-
elif token_string == 'if':
213-
self._elifs.append(False)
210+
# AST exists by the time process_tokens is called, so
211+
# it's safe to assume tokens[index+1]
212+
# exists. tokens[index+1][2] is the elif's position as
213+
# reported by cPython, Jython and PyPy,
214+
# tokens[index][2] is the actual position and also is
215+
# reported by IronPython.
216+
self._elifs.extend([tokens[index][2], tokens[index+1][2]])
214217
elif six.PY3 and token.exact_type == tokenize.COMMA:
215218
self._check_one_element_trailing_comma_tuple(tokens, token, index)
216219

@@ -282,12 +285,6 @@ def visit_with(self, node):
282285
for name in names.nodes_of_class(astroid.AssignName):
283286
self._check_redefined_argument_from_local(name)
284287

285-
def visit_ifexp(self, _):
286-
self._if_counter += 1
287-
288-
def visit_comprehension(self, node):
289-
self._if_counter += len(node.ifs)
290-
291288
def _check_superfluous_else_return(self, node):
292289
if not node.orelse:
293290
# Not interested in if statements without else.
@@ -302,7 +299,6 @@ def visit_if(self, node):
302299
self._check_simplifiable_if(node)
303300
self._check_nested_blocks(node)
304301
self._check_superfluous_else_return(node)
305-
self._if_counter += 1
306302

307303
@utils.check_messages('too-many-nested-blocks')
308304
def leave_functiondef(self, _):
@@ -329,7 +325,7 @@ def _check_nested_blocks(self, node):
329325
break
330326
self._nested_blocks.pop()
331327
# if the node is a elif, this should not be another nesting level
332-
if isinstance(node, astroid.If) and self._elifs[self._if_counter]:
328+
if isinstance(node, astroid.If) and self._is_actual_elif(node):
333329
if self._nested_blocks:
334330
self._nested_blocks.pop()
335331
self._nested_blocks.append(node)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""Test that `if` in formatted string literal won't break Pylint."""
2+
# pylint: disable=missing-docstring, pointless-statement, using-constant-test
3+
4+
f'{"+" if True else "-"}'
5+
if True:
6+
pass
7+
elif True:
8+
pass
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[testoptions]
2+
min_pyver=3.6

0 commit comments

Comments
 (0)