diff --git a/doc/whatsnew/fragments/9193.false_positive b/doc/whatsnew/fragments/9193.false_positive new file mode 100644 index 0000000000..39dc70b81d --- /dev/null +++ b/doc/whatsnew/fragments/9193.false_positive @@ -0,0 +1,4 @@ +Fix false positives for ``undefined-variable`` and ``unused-argument`` for +classes and functions using Python 3.12 generic type syntax. + +Closes #9193 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 6cf3924665..c06efc3d85 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -1738,6 +1738,9 @@ def _should_node_be_skipped( elif consumer.scope_type == "function" and self._defined_in_function_definition( node, consumer.node ): + if any(node.name == param.name.name for param in consumer.node.type_params): + return False + # If the name node is used as a function default argument's value or as # a decorator, then start from the parent frame of the function instead # of the function frame - and thus open an inner class scope @@ -2262,10 +2265,13 @@ def _is_variable_violation( isinstance(defframe, nodes.FunctionDef) and frame is defframe and defframe.parent_of(node) - and stmt is not defstmt + and ( + defnode in defframe.type_params + # Single statement function, with the statement on the + # same line as the function definition + or stmt is not defstmt + ) ): - # Single statement function, with the statement on the - # same line as the function definition maybe_before_assign = False elif ( isinstance(defstmt, NODES_WITH_VALUE_ATTR) diff --git a/tests/functional/u/undefined/undefined_variable_py312.py b/tests/functional/u/undefined/undefined_variable_py312.py new file mode 100644 index 0000000000..0ca2475eb9 --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_py312.py @@ -0,0 +1,7 @@ +# pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring,too-few-public-methods + +def f[T](a: T) -> T: + print(a) + +class ChildClass[T, *Ts, **P]: + ... diff --git a/tests/functional/u/undefined/undefined_variable_py312.rc b/tests/functional/u/undefined/undefined_variable_py312.rc new file mode 100644 index 0000000000..9c966d4bda --- /dev/null +++ b/tests/functional/u/undefined/undefined_variable_py312.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.12