Skip to content

Commit be1968e

Browse files
authored
Fix Python 3.12 generic type syntax (#10135)
1 parent cb12577 commit be1968e

File tree

5 files changed

+23
-6
lines changed

5 files changed

+23
-6
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix false positives for ``undefined-variable`` for classes using Python 3.12
2+
generic type syntax.
3+
4+
Closes #9335

pylint/checkers/variables.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,11 @@ def _should_node_be_skipped(
17421742
if utils.is_ancestor_name(consumer.node, node) or (
17431743
not is_start_index and self._ignore_class_scope(node)
17441744
):
1745+
if any(
1746+
node.name == param.name.name for param in consumer.node.type_params
1747+
):
1748+
return False
1749+
17451750
return True
17461751

17471752
# Ignore inner class scope for keywords in class definition
@@ -1952,7 +1957,9 @@ def _check_consumer(
19521957
)
19531958
return (VariableVisitConsumerAction.RETURN, found_nodes)
19541959

1955-
elif isinstance(defstmt, nodes.ClassDef):
1960+
elif (
1961+
isinstance(defstmt, nodes.ClassDef) and defnode not in defframe.type_params
1962+
):
19561963
return self._is_first_level_self_reference(node, defstmt, found_nodes)
19571964

19581965
elif isinstance(defnode, nodes.NamedExpr):
@@ -2334,6 +2341,13 @@ def _is_variable_violation(
23342341
maybe_before_assign = defnode.value is node or any(
23352342
anc is defnode.value for anc in node.node_ancestors()
23362343
)
2344+
elif (
2345+
isinstance(defframe, nodes.ClassDef)
2346+
and defnode in defframe.type_params
2347+
):
2348+
# Generic on parent class:
2349+
# class Child[_T](Parent[_T])
2350+
maybe_before_assign = False
23372351

23382352
return maybe_before_assign, annotation_return, use_outer_definition
23392353

tests/functional/g/generic_class_syntax_py312.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
class Entity[_T: float]:
33
last_update: int | None = None
44

5-
def __init__(self, data: _T) -> None: # [undefined-variable] # false-positive
5+
def __init__(self, data: _T) -> None:
66
self.data = data
77

88

@@ -28,6 +28,6 @@ def __init__(self):
2828
self.update_interval = 0
2929

3030

31-
class Child[_T](Parent[_T]): # [undefined-variable] # false-positive
31+
class Child[_T](Parent[_T]):
3232
def func(self):
3333
self.update_interval = None

tests/functional/g/generic_class_syntax_py312.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/functional/u/undefined/undefined_variable_py312.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ def f[T](a: T) -> T:
44
print(a)
55

66
class ChildClass[T, *Ts, **P]:
7-
...
7+
def __init__(self, value: T):
8+
self.value = value

0 commit comments

Comments
 (0)