diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1ed76bfc9e..f1d54dbd5c 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -519,3 +519,5 @@ contributors: - Documented Jupyter integration * Yilei Yang: contributor + +* Marcin Kurczewski (rr-): contributor diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 7578f840f2..564a9e88a0 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -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 +# Copyright (c) 2021 Marcin Kurczewski # 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 @@ -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) diff --git a/tests/functional/u/undefined/undefined_variable.py b/tests/functional/u/undefined/undefined_variable.py index 30bf3917df..0b92a495da 100644 --- a/tests/functional/u/undefined/undefined_variable.py +++ b/tests/functional/u/undefined/undefined_variable.py @@ -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) diff --git a/tests/functional/u/undefined/undefined_variable.txt b/tests/functional/u/undefined/undefined_variable.txt index 384a3a3061..a6db029bb0 100644 --- a/tests/functional/u/undefined/undefined_variable.txt +++ b/tests/functional/u/undefined/undefined_variable.txt @@ -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'