Skip to content

Commit e7ef1fd

Browse files
Emit used-before-assignment for further imports guarded by TYPE_CHECKING (#7806)
Previously, this message was only emitted for imports guarded directly under TYPE_CHECKING, not guarded two if-branches deep, nor when TYPE_CHECKING was imported from typing under an alias.
1 parent b5a85f6 commit e7ef1fd

File tree

5 files changed

+25
-14
lines changed

5 files changed

+25
-14
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Emit ``used-before-assignment`` for further imports guarded by ``TYPE_CHECKING``
2+
3+
Previously, this message was only emitted for imports guarded directly under
4+
``TYPE_CHECKING``, not guarded two if-branches deep, nor when ``TYPE_CHECKING``
5+
was imported from ``typing`` under an alias.
6+
7+
Closes #7539

pylint/checkers/variables.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@
2828
in_type_checking_block,
2929
is_postponed_evaluation_enabled,
3030
)
31-
from pylint.constants import (
32-
PY39_PLUS,
33-
TYPING_NEVER,
34-
TYPING_NORETURN,
35-
TYPING_TYPE_CHECKS_GUARDS,
36-
)
31+
from pylint.constants import PY39_PLUS, TYPING_NEVER, TYPING_NORETURN
3732
from pylint.interfaces import CONTROL_FLOW, HIGH, INFERENCE, INFERENCE_FAILURE
3833
from pylint.typing import MessageDefinitionTuple
3934

@@ -2201,7 +2196,7 @@ def _is_variable_violation(
22012196
if (
22022197
isinstance(defstmt, (nodes.Import, nodes.ImportFrom))
22032198
and isinstance(defstmt.parent, nodes.If)
2204-
and defstmt.parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
2199+
and in_type_checking_block(defstmt)
22052200
):
22062201
defstmt_parent = defstmt.parent
22072202

pylint/constants.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ class WarningScope:
9999
)
100100

101101

102-
TYPING_TYPE_CHECKS_GUARDS = frozenset({"typing.TYPE_CHECKING", "TYPE_CHECKING"})
103-
104-
105102
def _warn_about_old_home(pylint_home: pathlib.Path) -> None:
106103
"""Warn users about the old pylint home being deprecated.
107104

tests/functional/u/used/used_before_assignment_typing.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from typing import List, Optional, TYPE_CHECKING
66

77
if TYPE_CHECKING:
8+
if True: # pylint: disable=using-constant-test
9+
import math
810
import datetime
911

1012
class MyClass:
@@ -78,6 +80,15 @@ def other_function(self) -> None:
7880
_x: MyThirdClass = self
7981

8082

83+
class MyFourthClass: # pylint: disable=too-few-public-methods
84+
"""Class to test conditional imports guarded by TYPE_CHECKING two levels
85+
up then used in function annotation. See https://github.com/PyCQA/pylint/issues/7539"""
86+
87+
def is_close(self, comparator: math.isclose, first, second): # [used-before-assignment]
88+
"""Conditional imports guarded are only valid for variable annotations."""
89+
comparator(first, second)
90+
91+
8192
class VariableAnnotationsGuardedByTypeChecking: # pylint: disable=too-few-public-methods
8293
"""Class to test conditional imports guarded by TYPE_CHECKING then used in
8394
local (function) variable annotations, which are not evaluated at runtime.
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
undefined-variable:14:21:14:28:MyClass.incorrect_typing_method:Undefined variable 'MyClass':UNDEFINED
2-
undefined-variable:19:26:19:33:MyClass.incorrect_nested_typing_method:Undefined variable 'MyClass':UNDEFINED
3-
undefined-variable:24:20:24:27:MyClass.incorrect_default_method:Undefined variable 'MyClass':UNDEFINED
4-
used-before-assignment:88:20:88:28:VariableAnnotationsGuardedByTypeChecking:Using variable 'datetime' before assignment:HIGH
1+
undefined-variable:16:21:16:28:MyClass.incorrect_typing_method:Undefined variable 'MyClass':UNDEFINED
2+
undefined-variable:21:26:21:33:MyClass.incorrect_nested_typing_method:Undefined variable 'MyClass':UNDEFINED
3+
undefined-variable:26:20:26:27:MyClass.incorrect_default_method:Undefined variable 'MyClass':UNDEFINED
4+
used-before-assignment:87:35:87:39:MyFourthClass.is_close:Using variable 'math' before assignment:HIGH
5+
used-before-assignment:99:20:99:28:VariableAnnotationsGuardedByTypeChecking:Using variable 'datetime' before assignment:HIGH

0 commit comments

Comments
 (0)