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); }