Skip to content

Commit e2c15e3

Browse files
Add unsupported version checks for major 3.11 and 3.12 features (#9792)
* Bump DEFAULT_PYTHON checks.yaml to 3.12
1 parent 47fb321 commit e2c15e3

File tree

22 files changed

+155
-4
lines changed

22 files changed

+155
-4
lines changed

.github/workflows/checks.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ on:
1111
- "maintenance/**"
1212

1313
env:
14-
CACHE_VERSION: 1
14+
CACHE_VERSION: 2
1515
KEY_PREFIX: base-venv
16-
DEFAULT_PYTHON: "3.11"
16+
DEFAULT_PYTHON: "3.12"
1717
PRE_COMMIT_CACHE: ~/.cache/pre-commit
1818

1919
concurrency:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
string = "\z" # [anomalous-backslash-in-string]
1+
string = "\z" # [syntax-error]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
``\z`` is same as ``\\z`` because there's no escape sequence for ``z``. But it is not clear
22
for the reader of the code.
3+
4+
The only reason this is demonstrated to raise ``syntax-error`` is because
5+
pylint's CI now runs on Python 3.12, where this truly raises a ``SyntaxError``.
6+
We hope to address this discrepancy in the documentation in the future.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
print(b"\u%b" % b"0394") # [anomalous-unicode-escape-in-string]
1+
print(b"\u%b" % b"0394") # [syntax-error]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
def f():
2+
excs = [OSError("error 1"), SystemError("error 2")]
3+
# +1: [using-exception-groups-in-unsupported-version]
4+
raise ExceptionGroup("there were problems", excs)
5+
6+
7+
try: # [using-exception-groups-in-unsupported-version]
8+
f()
9+
except* OSError as e:
10+
print("There were OSErrors")
11+
except* SystemError as e:
12+
print("There were SystemErrors")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Exception groups were introduced in Python 3.11; to use it, please use a more recent version of Python.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def f():
2+
raise OSError("error 1")
3+
4+
5+
try:
6+
f()
7+
except OSError as e:
8+
print("There were OSErrors")
9+
except SystemError as e:
10+
print("There were SystemErrors")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[main]
2+
py-version=3.10
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type Vector = list[float] # [using-generic-type-syntax-in-unsupported-version]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generic type syntax was introduced in Python 3.12; to use it, please use a more recent version of Python.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from typing import TypeAlias
2+
3+
Vector: TypeAlias = list[float]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[main]
2+
py-version=3.11

doc/user_guide/checkers/features.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,9 +1351,15 @@ Verbatim name of the checker is ``unsupported_version``.
13511351

13521352
Unsupported Version checker Messages
13531353
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1354+
:using-exception-groups-in-unsupported-version (W2603): *Exception groups are not supported by all versions included in the py-version setting*
1355+
Used when the py-version set by the user is lower than 3.11 and pylint
1356+
encounters ``except*`` or `ExceptionGroup``.
13541357
:using-f-string-in-unsupported-version (W2601): *F-strings are not supported by all versions included in the py-version setting*
13551358
Used when the py-version set by the user is lower than 3.6 and pylint
13561359
encounters an f-string.
1360+
:using-generic-type-syntax-in-unsupported-version (W2604): *Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting*
1361+
Used when the py-version set by the user is lower than 3.12 and pylint
1362+
encounters generic type syntax.
13571363
:using-final-decorator-in-unsupported-version (W2602): *typing.final is not supported by all versions included in the py-version setting*
13581364
Used when the py-version set by the user is lower than 3.8 and pylint
13591365
encounters a ``typing.final`` decorator.

doc/user_guide/messages/messages_overview.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,10 @@ All messages in the warning category:
349349
warning/useless-type-doc
350350
warning/useless-with-lock
351351
warning/using-constant-test
352+
warning/using-exception-groups-in-unsupported-version
352353
warning/using-f-string-in-unsupported-version
353354
warning/using-final-decorator-in-unsupported-version
355+
warning/using-generic-type-syntax-in-unsupported-version
354356
warning/while-used
355357
warning/wildcard-import
356358
warning/wrong-exception-operation

doc/whatsnew/fragments/9791.new_check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Add `using-exception-group-in-unsupported-version` and
2+
`using-generic-type-syntax-in-unsupported-version` for uses of Python 3.11+ or
3+
3.12+ features on lower supported versions provided with `--py-version`.
4+
5+
Closes #9791

pylint/checkers/unsupported_version.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,27 @@ class UnsupportedVersionChecker(BaseChecker):
4242
"Used when the py-version set by the user is lower than 3.8 and pylint encounters "
4343
"a ``typing.final`` decorator.",
4444
),
45+
"W2603": (
46+
"Exception groups are not supported by all versions included in the py-version setting",
47+
"using-exception-groups-in-unsupported-version",
48+
"Used when the py-version set by the user is lower than 3.11 and pylint encounters "
49+
"``except*`` or `ExceptionGroup``.",
50+
),
51+
"W2604": (
52+
"Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting",
53+
"using-generic-type-syntax-in-unsupported-version",
54+
"Used when the py-version set by the user is lower than 3.12 and pylint encounters "
55+
"generic type syntax.",
56+
),
4557
}
4658

4759
def open(self) -> None:
4860
"""Initialize visit variables and statistics."""
4961
py_version = self.linter.config.py_version
5062
self._py36_plus = py_version >= (3, 6)
5163
self._py38_plus = py_version >= (3, 8)
64+
self._py311_plus = py_version >= (3, 11)
65+
self._py312_plus = py_version >= (3, 12)
5266

5367
@only_required_for_messages("using-f-string-in-unsupported-version")
5468
def visit_joinedstr(self, node: nodes.JoinedStr) -> None:
@@ -79,6 +93,51 @@ def _check_typing_final(self, node: nodes.Decorators) -> None:
7993
"using-final-decorator-in-unsupported-version", node=decorator
8094
)
8195

96+
@only_required_for_messages("using-exception-groups-in-unsupported-version")
97+
def visit_trystar(self, node: nodes.TryStar) -> None:
98+
if not self._py311_plus:
99+
self.add_message("using-exception-groups-in-unsupported-version", node=node)
100+
101+
@only_required_for_messages("using-exception-groups-in-unsupported-version")
102+
def visit_excepthandler(self, node: nodes.ExceptHandler) -> None:
103+
if (
104+
not self._py311_plus
105+
and isinstance(node.type, nodes.Name)
106+
and node.type.name == "ExceptionGroup"
107+
):
108+
self.add_message("using-exception-groups-in-unsupported-version", node=node)
109+
110+
@only_required_for_messages("using-exception-groups-in-unsupported-version")
111+
def visit_raise(self, node: nodes.Raise) -> None:
112+
if (
113+
not self._py311_plus
114+
and isinstance(node.exc, nodes.Call)
115+
and isinstance(node.exc.func, nodes.Name)
116+
and node.exc.func.name == "ExceptionGroup"
117+
):
118+
self.add_message("using-exception-groups-in-unsupported-version", node=node)
119+
120+
@only_required_for_messages("using-generic-type-syntax-in-unsupported-version")
121+
def visit_typealias(self, node: nodes.TypeAlias) -> None:
122+
if not self._py312_plus:
123+
self.add_message(
124+
"using-generic-type-syntax-in-unsupported-version", node=node
125+
)
126+
127+
@only_required_for_messages("using-generic-type-syntax-in-unsupported-version")
128+
def visit_typevar(self, node: nodes.TypeVar) -> None:
129+
if not self._py312_plus:
130+
self.add_message(
131+
"using-generic-type-syntax-in-unsupported-version", node=node
132+
)
133+
134+
@only_required_for_messages("using-generic-type-syntax-in-unsupported-version")
135+
def visit_typevartuple(self, node: nodes.TypeVarTuple) -> None:
136+
if not self._py312_plus:
137+
self.add_message(
138+
"using-generic-type-syntax-in-unsupported-version", node=node
139+
)
140+
82141

83142
def register(linter: PyLinter) -> None:
84143
linter.register_checker(UnsupportedVersionChecker(linter))
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring
2+
def f():
3+
excs = [OSError("error 1"), SystemError("error 2")]
4+
# +1: [using-exception-groups-in-unsupported-version]
5+
raise ExceptionGroup("there were problems", excs)
6+
7+
8+
try: # [using-exception-groups-in-unsupported-version]
9+
f()
10+
except* OSError as e:
11+
print("There were OSErrors")
12+
except* SystemError as e:
13+
print("There were SystemErrors")
14+
15+
16+
try:
17+
f()
18+
except ExceptionGroup as group: # [using-exception-groups-in-unsupported-version]
19+
# https://github.com/pylint-dev/pylint/issues/8985
20+
for exc in group.exceptions: # pylint: disable=not-an-iterable
21+
print("ERROR: ", exc)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[main]
2+
py-version=3.10
3+
4+
[testoptions]
5+
min_pyver=3.11
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using-exception-groups-in-unsupported-version:5:4:5:53:f:Exception groups are not supported by all versions included in the py-version setting:UNDEFINED
2+
using-exception-groups-in-unsupported-version:8:0:13:36::Exception groups are not supported by all versions included in the py-version setting:UNDEFINED
3+
using-exception-groups-in-unsupported-version:18:0:21:29::Exception groups are not supported by all versions included in the py-version setting:UNDEFINED
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring, line-too-long
2+
# +1: [using-generic-type-syntax-in-unsupported-version, using-generic-type-syntax-in-unsupported-version]
3+
type Point[T] = tuple[float, float]
4+
# +1: [using-generic-type-syntax-in-unsupported-version, using-generic-type-syntax-in-unsupported-version]
5+
type Alias[*Ts] = tuple[*Ts]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[main]
2+
py-version=3.11
3+
4+
[testoptions]
5+
min_pyver=3.12
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using-generic-type-syntax-in-unsupported-version:3:0:3:35::Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting:UNDEFINED
2+
using-generic-type-syntax-in-unsupported-version:3:11:3:12::Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting:UNDEFINED
3+
using-generic-type-syntax-in-unsupported-version:5:0:5:28::Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting:UNDEFINED
4+
using-generic-type-syntax-in-unsupported-version:5:11:5:14::Generic type syntax (PEP 695) is not supported by all versions included in the py-version setting:UNDEFINED

0 commit comments

Comments
 (0)