diff --git a/doc/whatsnew/fragments/9196.feature b/doc/whatsnew/fragments/9196.feature new file mode 100644 index 0000000000..df1a560e2a --- /dev/null +++ b/doc/whatsnew/fragments/9196.feature @@ -0,0 +1,3 @@ +Check ``TypeAlias`` and ``TypeVar`` (PEP 695) nodes for ``invalid-name``. + +Refs #9196 diff --git a/doc/whatsnew/fragments/9457.internal b/doc/whatsnew/fragments/9457.internal new file mode 100644 index 0000000000..504ee2b1d0 --- /dev/null +++ b/doc/whatsnew/fragments/9457.internal @@ -0,0 +1,3 @@ +Update astroid version to 3.1.0. + +Refs #9457 diff --git a/pylint/checkers/base/name_checker/checker.py b/pylint/checkers/base/name_checker/checker.py index c6272a6fbe..82ff725369 100644 --- a/pylint/checkers/base/name_checker/checker.py +++ b/pylint/checkers/base/name_checker/checker.py @@ -409,6 +409,12 @@ def visit_assignname( # pylint: disable=too-many-branches if isinstance(assign_type, nodes.Comprehension): self._check_name("inlinevar", node.name, node) + elif isinstance(assign_type, nodes.TypeVar): + self._check_name("typevar", node.name, node) + + elif isinstance(assign_type, nodes.TypeAlias): + self._check_name("typealias", node.name, node) + # Check names defined in module scope elif isinstance(frame, nodes.Module): # Check names defined in Assign nodes @@ -625,6 +631,9 @@ def _check_typevar(self, name: str, node: nodes.AssignName) -> None: node.assign_type().value.elts[node.parent.elts.index(node)].keywords ) args = node.assign_type().value.elts[node.parent.elts.index(node)].args + else: # PEP 695 generic type nodes + keywords = () + args = () variance = TypeVarVariance.invariant name_arg = None diff --git a/pyproject.toml b/pyproject.toml index 81e0f4422f..822e5efb9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dependencies = [ # Also upgrade requirements_test_min.txt. # Pinned to dev of second minor update to allow editable installs and fix primer issues, # see https://github.com/pylint-dev/astroid/issues/1341 - "astroid>=3.0.3,<=3.1.0-dev0", + "astroid>=3.1.0,<=3.2.0-dev0", "isort>=4.2.5,<6,!=5.13.0", "mccabe>=0.6,<0.8", "tomli>=1.1.0;python_version<'3.11'", diff --git a/requirements_test_min.txt b/requirements_test_min.txt index 9074af5192..f2631e6ff1 100644 --- a/requirements_test_min.txt +++ b/requirements_test_min.txt @@ -1,6 +1,6 @@ .[testutils,spelling] # astroid dependency is also defined in pyproject.toml -astroid==3.0.3 # Pinned to a specific version for tests +astroid==3.1.0 # Pinned to a specific version for tests typing-extensions~=4.9 py~=1.11.0 pytest~=7.4 diff --git a/tests/functional/i/import_error.txt b/tests/functional/i/import_error.txt index 49cc0a673e..b24d885063 100644 --- a/tests/functional/i/import_error.txt +++ b/tests/functional/i/import_error.txt @@ -1,6 +1,6 @@ import-error:3:0:3:22::Unable to import 'totally_missing':UNDEFINED import-error:21:4:21:26::Unable to import 'maybe_missing_2':UNDEFINED no-name-in-module:33:0:33:49::No name 'syntax_error' in module 'functional.s.syntax':UNDEFINED -syntax-error:33:0:None:None::Cannot import 'functional.s.syntax.syntax_error' due to 'invalid syntax (, line 1)':HIGH +syntax-error:33:0:None:None::Cannot import 'functional.s.syntax.syntax_error' due to 'invalid syntax (functional.s.syntax.syntax_error, line 1)':HIGH multiple-imports:78:0:78:15::Multiple imports on one line (foo, bar):UNDEFINED import-error:96:4:96:15::Unable to import 'foo2':UNDEFINED diff --git a/tests/functional/s/syntax/syntax_error.txt b/tests/functional/s/syntax/syntax_error.txt index 3640717728..9432084dd1 100644 --- a/tests/functional/s/syntax/syntax_error.txt +++ b/tests/functional/s/syntax/syntax_error.txt @@ -1 +1 @@ -syntax-error:1:5:None:None::"Parsing failed: 'invalid syntax (, line 1)'":HIGH +syntax-error:1:5:None:None::"Parsing failed: 'invalid syntax (syntax_error, line 1)'":HIGH diff --git a/tests/functional/t/type/__init__.py b/tests/functional/t/type/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/t/typealias_naming_style_default.py b/tests/functional/t/type/typealias_naming_style_default.py similarity index 100% rename from tests/functional/t/typealias_naming_style_default.py rename to tests/functional/t/type/typealias_naming_style_default.py diff --git a/tests/functional/t/typealias_naming_style_default.rc b/tests/functional/t/type/typealias_naming_style_default.rc similarity index 100% rename from tests/functional/t/typealias_naming_style_default.rc rename to tests/functional/t/type/typealias_naming_style_default.rc diff --git a/tests/functional/t/typealias_naming_style_default.txt b/tests/functional/t/type/typealias_naming_style_default.txt similarity index 100% rename from tests/functional/t/typealias_naming_style_default.txt rename to tests/functional/t/type/typealias_naming_style_default.txt diff --git a/tests/functional/t/type/typealias_naming_style_py312.py b/tests/functional/t/type/typealias_naming_style_py312.py new file mode 100644 index 0000000000..0caa2970bb --- /dev/null +++ b/tests/functional/t/type/typealias_naming_style_py312.py @@ -0,0 +1,4 @@ +"""PEP 695 generic typing nodes""" + +type Point[T] = tuple[T, ...] +type point[T] = tuple[T, ...] # [invalid-name] diff --git a/tests/functional/t/type/typealias_naming_style_py312.rc b/tests/functional/t/type/typealias_naming_style_py312.rc new file mode 100644 index 0000000000..9c966d4bda --- /dev/null +++ b/tests/functional/t/type/typealias_naming_style_py312.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.12 diff --git a/tests/functional/t/type/typealias_naming_style_py312.txt b/tests/functional/t/type/typealias_naming_style_py312.txt new file mode 100644 index 0000000000..1b5af3482f --- /dev/null +++ b/tests/functional/t/type/typealias_naming_style_py312.txt @@ -0,0 +1 @@ +invalid-name:4:5:4:10::"Type alias name ""point"" doesn't conform to predefined naming style":HIGH diff --git a/tests/functional/t/typealias_naming_style_rgx.py b/tests/functional/t/type/typealias_naming_style_rgx.py similarity index 100% rename from tests/functional/t/typealias_naming_style_rgx.py rename to tests/functional/t/type/typealias_naming_style_rgx.py diff --git a/tests/functional/t/typealias_naming_style_rgx.rc b/tests/functional/t/type/typealias_naming_style_rgx.rc similarity index 100% rename from tests/functional/t/typealias_naming_style_rgx.rc rename to tests/functional/t/type/typealias_naming_style_rgx.rc diff --git a/tests/functional/t/typealias_naming_style_rgx.txt b/tests/functional/t/type/typealias_naming_style_rgx.txt similarity index 100% rename from tests/functional/t/typealias_naming_style_rgx.txt rename to tests/functional/t/type/typealias_naming_style_rgx.txt diff --git a/tests/functional/t/typedDict.py b/tests/functional/t/type/typedDict.py similarity index 100% rename from tests/functional/t/typedDict.py rename to tests/functional/t/type/typedDict.py diff --git a/tests/functional/t/typevar_double_variance.py b/tests/functional/t/type/typevar_double_variance.py similarity index 100% rename from tests/functional/t/typevar_double_variance.py rename to tests/functional/t/type/typevar_double_variance.py diff --git a/tests/functional/t/typevar_double_variance.txt b/tests/functional/t/type/typevar_double_variance.txt similarity index 100% rename from tests/functional/t/typevar_double_variance.txt rename to tests/functional/t/type/typevar_double_variance.txt diff --git a/tests/functional/t/typevar_name_incorrect_variance.py b/tests/functional/t/type/typevar_name_incorrect_variance.py similarity index 100% rename from tests/functional/t/typevar_name_incorrect_variance.py rename to tests/functional/t/type/typevar_name_incorrect_variance.py diff --git a/tests/functional/t/typevar_name_incorrect_variance.txt b/tests/functional/t/type/typevar_name_incorrect_variance.txt similarity index 100% rename from tests/functional/t/typevar_name_incorrect_variance.txt rename to tests/functional/t/type/typevar_name_incorrect_variance.txt diff --git a/tests/functional/t/typevar_name_mismatch.py b/tests/functional/t/type/typevar_name_mismatch.py similarity index 100% rename from tests/functional/t/typevar_name_mismatch.py rename to tests/functional/t/type/typevar_name_mismatch.py diff --git a/tests/functional/t/typevar_name_mismatch.txt b/tests/functional/t/type/typevar_name_mismatch.txt similarity index 100% rename from tests/functional/t/typevar_name_mismatch.txt rename to tests/functional/t/type/typevar_name_mismatch.txt diff --git a/tests/functional/t/typevar_naming_style_default.py b/tests/functional/t/type/typevar_naming_style_default.py similarity index 100% rename from tests/functional/t/typevar_naming_style_default.py rename to tests/functional/t/type/typevar_naming_style_default.py diff --git a/tests/functional/t/typevar_naming_style_default.txt b/tests/functional/t/type/typevar_naming_style_default.txt similarity index 100% rename from tests/functional/t/typevar_naming_style_default.txt rename to tests/functional/t/type/typevar_naming_style_default.txt diff --git a/tests/functional/t/type/typevar_naming_style_py312.py b/tests/functional/t/type/typevar_naming_style_py312.py new file mode 100644 index 0000000000..378290219f --- /dev/null +++ b/tests/functional/t/type/typevar_naming_style_py312.py @@ -0,0 +1,4 @@ +"""PEP 695 generic typing nodes""" + +type Point[T] = tuple[T, ...] +type Point[t] = tuple[t, ...] # [invalid-name] diff --git a/tests/functional/t/type/typevar_naming_style_py312.rc b/tests/functional/t/type/typevar_naming_style_py312.rc new file mode 100644 index 0000000000..9c966d4bda --- /dev/null +++ b/tests/functional/t/type/typevar_naming_style_py312.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.12 diff --git a/tests/functional/t/type/typevar_naming_style_py312.txt b/tests/functional/t/type/typevar_naming_style_py312.txt new file mode 100644 index 0000000000..babe2a57bb --- /dev/null +++ b/tests/functional/t/type/typevar_naming_style_py312.txt @@ -0,0 +1 @@ +invalid-name:4:11:4:12::"Type variable name ""t"" doesn't conform to predefined naming style":HIGH diff --git a/tests/functional/t/typevar_naming_style_rgx.py b/tests/functional/t/type/typevar_naming_style_rgx.py similarity index 100% rename from tests/functional/t/typevar_naming_style_rgx.py rename to tests/functional/t/type/typevar_naming_style_rgx.py diff --git a/tests/functional/t/typevar_naming_style_rgx.rc b/tests/functional/t/type/typevar_naming_style_rgx.rc similarity index 100% rename from tests/functional/t/typevar_naming_style_rgx.rc rename to tests/functional/t/type/typevar_naming_style_rgx.rc diff --git a/tests/functional/t/typevar_naming_style_rgx.txt b/tests/functional/t/type/typevar_naming_style_rgx.txt similarity index 100% rename from tests/functional/t/typevar_naming_style_rgx.txt rename to tests/functional/t/type/typevar_naming_style_rgx.txt diff --git a/tests/functional/u/used/used_before_assignment.py b/tests/functional/u/used/used_before_assignment.py index 0d1a938b9e..16f33939cb 100644 --- a/tests/functional/u/used/used_before_assignment.py +++ b/tests/functional/u/used/used_before_assignment.py @@ -132,15 +132,15 @@ def turn_on2(**kwargs): # Variables guarded by the same test when used. # Always false -if __name__ == "__main__": +if 1 in []: PERCENT = 20 SALE = True -if __name__ == "__main__": +if 1 in []: print(PERCENT) # Different test -if __name__ is None: +if 1 in [1]: print(SALE) # [used-before-assignment] diff --git a/tests/test_self.py b/tests/test_self.py index 023fbd8c99..e45b524ac9 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -372,7 +372,7 @@ def test_json_report_when_file_has_syntax_error(self) -> None: assert message[key] == value msg = message["message"].lower() assert any(x in msg for x in ("expected ':'", "invalid syntax")) - assert "" in msg + assert "syntax_error" in msg assert "line 1" in msg def test_json_report_when_file_is_missing(self) -> None: @@ -610,7 +610,7 @@ def foobar(arg): def test_stdin_syntax_error(self) -> None: expected_output = """************* Module a -a.py:1:4: E0001: Parsing failed: 'invalid syntax (, line 1)' (syntax-error)""" +a.py:1:4: E0001: Parsing failed: 'invalid syntax (a, line 1)' (syntax-error)""" with mock.patch( "pylint.lint.pylinter._read_stdin", return_value="for\n" ) as mock_stdin: