diff --git a/python/python-psi-impl/resources/messages/PyPsiBundle.properties b/python/python-psi-impl/resources/messages/PyPsiBundle.properties
index 226f85614766..5d083938730f 100644
--- a/python/python-psi-impl/resources/messages/PyPsiBundle.properties
+++ b/python/python-psi-impl/resources/messages/PyPsiBundle.properties
@@ -791,6 +791,7 @@ INSP.compatibility.check.for.compatibility.with.python.versions=Check for compat
INSP.compatibility.inspection.unsupported.feature.prefix=Python {0,choice,1#version|2#versions} {1} {0,choice,1#does|2#do} not {2}
INSP.compatibility.feature.support.variable.annotations=support variable annotations
INSP.compatibility.feature.support.this.syntax=support this syntax
+INSP.compatibility.feature.support.type.alias.statements=support type alias statements
INSP.compatibility.feature.have.module.builtins=have module builtins
INSP.compatibility.feature.have.module.builtin=have module __builtin__
INSP.compatibility.feature.support.starred.expressions.as.assignment.targets=support starred expressions as assignment targets
diff --git a/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java
index bc87955b5919..d747ee6fd7c3 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/validation/CompatibilityVisitor.java
@@ -747,6 +747,23 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
matchStatement.getFirstChild());
}
+ @Override
+ public void visitPyTypeAliasStatement(@NotNull PyTypeAliasStatement node) {
+ registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON312),
+ PyPsiBundle.message("INSP.compatibility.feature.support.type.alias.statements"),
+ node);
+ }
+
+ @Override
+ public void visitPyTypeParameterList(@NotNull PyTypeParameterList node) {
+ // No need to report an error inside the statement which is already reported as unsupported
+ if (!(node.getParent() instanceof PyTypeAliasStatement)) {
+ registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON312),
+ PyPsiBundle.message("INSP.compatibility.feature.support.this.syntax"),
+ node);
+ }
+ }
+
private void checkBitwiseOrUnionSyntax(@NotNull PyBinaryExpression node) {
if (node.getOperator() != PyTokenTypes.OR) return;
diff --git a/python/testData/highlighting/typeAliasStatementBefore312.py b/python/testData/highlighting/typeAliasStatementBefore312.py
new file mode 100644
index 000000000000..a260ee59b786
--- /dev/null
+++ b/python/testData/highlighting/typeAliasStatementBefore312.py
@@ -0,0 +1 @@
+type myType[T] = list[T]
\ No newline at end of file
diff --git a/python/testData/highlighting/typeParameterListBefore312.py b/python/testData/highlighting/typeParameterListBefore312.py
new file mode 100644
index 000000000000..89a4fe0dac6a
--- /dev/null
+++ b/python/testData/highlighting/typeParameterListBefore312.py
@@ -0,0 +1,3 @@
+class Class[T]:
+ def foo[U](x: U):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/PyCompatibilityInspection/typeAliasStatements.py b/python/testData/inspections/PyCompatibilityInspection/typeAliasStatements.py
new file mode 100644
index 000000000000..40f37ea4124e
--- /dev/null
+++ b/python/testData/inspections/PyCompatibilityInspection/typeAliasStatements.py
@@ -0,0 +1 @@
+type MyType = str
\ No newline at end of file
diff --git a/python/testData/inspections/PyCompatibilityInspection/typeParameterLists.py b/python/testData/inspections/PyCompatibilityInspection/typeParameterLists.py
new file mode 100644
index 000000000000..35fad8d77030
--- /dev/null
+++ b/python/testData/inspections/PyCompatibilityInspection/typeParameterLists.py
@@ -0,0 +1,3 @@
+class Clazz[T]:
+ def foo[U](self):
+ pass
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java
index 7a56b19be28d..46f48b5e333b 100644
--- a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java
@@ -580,16 +580,26 @@ public class PythonHighlightingTest extends PyTestCase {
doTest(LanguageLevel.getLatest(), false, true);
}
- // PY-60767
+ // PY-61856
public void testTypeAliasStatement() {
doTest(LanguageLevel.PYTHON312, false, true);
}
- // PY-60767
+ // PY-61856
public void testTypeParameter() {
doTest(LanguageLevel.PYTHON312, false, true);
}
+ // PY-61856
+ public void testTypeAliasStatementBefore312() {
+ doTest(LanguageLevel.PYTHON311, false, true);
+ }
+
+ // PY-61856
+ public void testTypeParameterListBefore312() {
+ doTest(LanguageLevel.PYTHON311, false, true);
+ }
+
@NotNull
private static EditorColorsScheme createTemporaryColorScheme() {
EditorColorsManager manager = EditorColorsManager.getInstance();
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
index 32e499649127..0bb82ab1d3fd 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
@@ -270,6 +270,17 @@ public class PyCompatibilityInspectionTest extends PyInspectionTestCase {
doTest(LanguageLevel.PYTHON311);
}
+ // PY-60767
+ public void testTypeAliasStatements() {
+ doTest(LanguageLevel.PYTHON311);
+ }
+
+ // PY-60767
+ public void testTypeParameterLists() {
+ doTest(LanguageLevel.PYTHON311);
+ }
+
+
private void doTest(@NotNull LanguageLevel level) {
runWithLanguageLevel(level, this::doTest);
}