Skip to content

Commit

Permalink
Fix Python 3.12 generic type syntax (#10135) (#10146)
Browse files Browse the repository at this point in the history
(cherry picked from commit be1968e)

Co-authored-by: Marzuk Rashid <mail@marzuk.io>
  • Loading branch information
github-actions[bot] and marzukr authored Dec 21, 2024
1 parent 90cb29d commit a7202b1
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 6 deletions.
4 changes: 4 additions & 0 deletions doc/whatsnew/fragments/9335.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix false positives for ``undefined-variable`` for classes using Python 3.12
generic type syntax.

Closes #9335
16 changes: 15 additions & 1 deletion pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,11 @@ def _should_node_be_skipped(
if utils.is_ancestor_name(consumer.node, node) or (
not is_start_index and self._ignore_class_scope(node)
):
if any(
node.name == param.name.name for param in consumer.node.type_params
):
return False

return True

# Ignore inner class scope for keywords in class definition
Expand Down Expand Up @@ -1978,7 +1983,9 @@ def _check_consumer(
)
return (VariableVisitConsumerAction.RETURN, found_nodes)

elif isinstance(defstmt, nodes.ClassDef):
elif (
isinstance(defstmt, nodes.ClassDef) and defnode not in defframe.type_params
):
return self._is_first_level_self_reference(node, defstmt, found_nodes)

elif isinstance(defnode, nodes.NamedExpr):
Expand Down Expand Up @@ -2357,6 +2364,13 @@ def _is_variable_violation(
maybe_before_assign = defnode.value is node or any(
anc is defnode.value for anc in node.node_ancestors()
)
elif (
isinstance(defframe, nodes.ClassDef)
and defnode in defframe.type_params
):
# Generic on parent class:
# class Child[_T](Parent[_T])
maybe_before_assign = False

return maybe_before_assign, annotation_return, use_outer_definition

Expand Down
4 changes: 2 additions & 2 deletions tests/functional/g/generic_class_syntax_py312.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
class Entity[_T: float]:
last_update: int | None = None

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


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


class Child[_T](Parent[_T]): # [undefined-variable] # false-positive
class Child[_T](Parent[_T]):
def func(self):
self.update_interval = None
2 changes: 0 additions & 2 deletions tests/functional/g/generic_class_syntax_py312.txt

This file was deleted.

3 changes: 2 additions & 1 deletion tests/functional/u/undefined/undefined_variable_py312.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ def f[T](a: T) -> T:
print(a)

class ChildClass[T, *Ts, **P]:
...
def __init__(self, value: T):
self.value = value

0 comments on commit a7202b1

Please sign in to comment.