Skip to content

Commit

Permalink
Fix false positive undefined variable in decorator with list comprehe…
Browse files Browse the repository at this point in the history
…nsion (#4737)

Closes #3791
  • Loading branch information
rr- committed Jul 22, 2021
1 parent 31aa6fd commit a054796
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CONTRIBUTORS.txt
Expand Up @@ -519,3 +519,5 @@ contributors:
- Documented Jupyter integration

* Yilei Yang: contributor

* Marcin Kurczewski (rr-): contributor
10 changes: 7 additions & 3 deletions pylint/checkers/variables.py
Expand Up @@ -44,6 +44,7 @@
# Copyright (c) 2021 Lorena B <46202743+lorena-b@users.noreply.github.com>
# Copyright (c) 2021 haasea <44787650+haasea@users.noreply.github.com>
# Copyright (c) 2021 Alexander Kapshuna <kapsh@kap.sh>
# Copyright (c) 2021 Marcin Kurczewski <rr-@sakuya.pl>

# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
Expand Down Expand Up @@ -1006,9 +1007,12 @@ def visit_name(self, node):
# variable used outside the loop
# avoid the case where there are homonyms inside function scope and
# comprehension current scope (avoid bug #1731)
if name in current_consumer.consumed and not (
current_consumer.scope_type == "comprehension"
and self._has_homonym_in_upper_function_scope(node, i)
if name in current_consumer.consumed and (
utils.is_func_decorator(current_consumer.node)
or not (
current_consumer.scope_type == "comprehension"
and self._has_homonym_in_upper_function_scope(node, i)
)
):
defnode = utils.assign_parent(current_consumer.consumed[name][0])
self._check_late_binding_closure(node, defnode)
Expand Down
19 changes: 19 additions & 0 deletions tests/functional/u/undefined/undefined_variable.py
Expand Up @@ -309,3 +309,22 @@ def undefined_annotation(a:x): # [undefined-variable]
]
for item in lst
]


# 3791
@decorator(x for x in range(3))
def decorated1(x):
print(x)

@decorator(x * x for x in range(3))
def decorated2(x):
print(x)

@decorator(x) # [undefined-variable]
@decorator(x * x for x in range(3))
def decorated3(x):
print(x)

@decorator(x * x * y for x in range(3)) # [undefined-variable]
def decorated4(x):
print(x)
2 changes: 2 additions & 0 deletions tests/functional/u/undefined/undefined_variable.txt
Expand Up @@ -28,3 +28,5 @@ used-before-assignment:254:26:func_should_fail:Using variable 'datetime' before
undefined-variable:281:18:not_using_loop_variable_accordingly:Undefined variable 'iteree'
undefined-variable:292:27:undefined_annotation:Undefined variable 'x'
used-before-assignment:293:7:undefined_annotation:Using variable 'x' before assignment
undefined-variable:323:11:decorated3:Undefined variable 'x'
undefined-variable:328:19:decorated4:Undefined variable 'y'

0 comments on commit a054796

Please sign in to comment.