Skip to content

Commit

Permalink
Fix used-before-assignment if conditional imports guarded again whe…
Browse files Browse the repository at this point in the history
…n used (#7980)

(cherry picked from commit e6f0bc5)
  • Loading branch information
jacobtylerwalls authored and Pierre-Sassoulas committed Dec 26, 2022
1 parent 1ded4d0 commit c3d7b39
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 11 deletions.
4 changes: 4 additions & 0 deletions doc/whatsnew/fragments/7979.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Prevent ``used-before-assignment`` when imports guarded by ``if TYPE_CHECKING``
are guarded again when used.

Closes #7979
10 changes: 3 additions & 7 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@
in_type_checking_block,
is_postponed_evaluation_enabled,
)
from pylint.constants import (
PY39_PLUS,
TYPING_NEVER,
TYPING_NORETURN,
TYPING_TYPE_CHECKS_GUARDS,
)
from pylint.constants import PY39_PLUS, TYPING_NEVER, TYPING_NORETURN
from pylint.interfaces import CONTROL_FLOW, HIGH, INFERENCE, INFERENCE_FAILURE
from pylint.typing import MessageDefinitionTuple

Expand Down Expand Up @@ -2003,7 +1998,8 @@ def _is_variable_violation(
if (
isinstance(defstmt, (nodes.Import, nodes.ImportFrom))
and isinstance(defstmt.parent, nodes.If)
and defstmt.parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
and in_type_checking_block(defstmt)
and not in_type_checking_block(node)
):
defstmt_parent = defstmt.parent

Expand Down
7 changes: 7 additions & 0 deletions tests/functional/u/used/used_before_assignment_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

if TYPE_CHECKING:
import datetime
from urllib.request import urlopen

class MyClass:
"""Type annotation or default values for first level methods can't refer to their own class"""
Expand Down Expand Up @@ -90,3 +91,9 @@ class VariableAnnotationsGuardedByTypeChecking: # pylint: disable=too-few-publi
def print_date(self, date) -> None:
date: datetime.date = date
print(date)


class ConditionalImportGuardedWhenUsed: # pylint: disable=too-few-public-methods
"""Conditional imports also guarded by TYPE_CHECKING when used."""
if TYPE_CHECKING:
print(urlopen)
8 changes: 4 additions & 4 deletions tests/functional/u/used/used_before_assignment_typing.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
undefined-variable:14:21:14:28:MyClass.incorrect_typing_method:Undefined variable 'MyClass':UNDEFINED
undefined-variable:19:26:19:33:MyClass.incorrect_nested_typing_method:Undefined variable 'MyClass':UNDEFINED
undefined-variable:24:20:24:27:MyClass.incorrect_default_method:Undefined variable 'MyClass':UNDEFINED
used-before-assignment:88:20:88:28:VariableAnnotationsGuardedByTypeChecking:Using variable 'datetime' before assignment:HIGH
undefined-variable:15:21:15:28:MyClass.incorrect_typing_method:Undefined variable 'MyClass':UNDEFINED
undefined-variable:20:26:20:33:MyClass.incorrect_nested_typing_method:Undefined variable 'MyClass':UNDEFINED
undefined-variable:25:20:25:27:MyClass.incorrect_default_method:Undefined variable 'MyClass':UNDEFINED
used-before-assignment:89:20:89:28:VariableAnnotationsGuardedByTypeChecking:Using variable 'datetime' before assignment:HIGH

0 comments on commit c3d7b39

Please sign in to comment.