diff --git a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java index 40f5b676ffda..f9818b771282 100644 --- a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java @@ -157,6 +157,9 @@ public class PyStatementEffectInspection extends PyInspection { final PyPrefixExpression prefixExpr = (PyPrefixExpression)expression; return prefixExpr.getOperator() == PyTokenTypes.AWAIT_KEYWORD; } + else if (expression instanceof PyNoneLiteralExpression && ((PyNoneLiteralExpression)expression).isEllipsis()) { + return true; + } return false; } } diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index ab6f3ff3f8b4..f24b7821edf5 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1790,25 +1790,31 @@ public class PyUtil { return true; } else if (statements.length == 1) { - if (isStringLiteral(statements[0]) || isPassOrRaiseOrEmptyReturn(statements[0])) { + if (isStringLiteral(statements[0]) || isPassOrRaiseOrEmptyReturnOrEllipsis(statements[0])) { return true; } } else if (statements.length == 2) { - if (isStringLiteral(statements[0]) && (isPassOrRaiseOrEmptyReturn(statements[1]))) { + if (isStringLiteral(statements[0]) && (isPassOrRaiseOrEmptyReturnOrEllipsis(statements[1]))) { return true; } } return false; } - private static boolean isPassOrRaiseOrEmptyReturn(PyStatement stmt) { + private static boolean isPassOrRaiseOrEmptyReturnOrEllipsis(PyStatement stmt) { if (stmt instanceof PyPassStatement || stmt instanceof PyRaiseStatement) { return true; } if (stmt instanceof PyReturnStatement && ((PyReturnStatement)stmt).getExpression() == null) { return true; } + if (stmt instanceof PyExpressionStatement) { + final PyExpression expression = ((PyExpressionStatement)stmt).getExpression(); + if (expression instanceof PyNoneLiteralExpression && ((PyNoneLiteralExpression)expression).isEllipsis()) { + return true; + } + } return false; } diff --git a/python/testData/inspections/PyStatementEffectInspection/functionWithEllipsis.py b/python/testData/inspections/PyStatementEffectInspection/functionWithEllipsis.py new file mode 100644 index 000000000000..641e3c0936b9 --- /dev/null +++ b/python/testData/inspections/PyStatementEffectInspection/functionWithEllipsis.py @@ -0,0 +1,2 @@ +def foo(): + ... \ No newline at end of file diff --git a/python/testData/inspections/PyTypeCheckerInspection/EllipsisInFunctionWithSpecifiedReturnType.py b/python/testData/inspections/PyTypeCheckerInspection/EllipsisInFunctionWithSpecifiedReturnType.py new file mode 100644 index 000000000000..9be3f3ff5efd --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/EllipsisInFunctionWithSpecifiedReturnType.py @@ -0,0 +1,2 @@ +def bar() -> int: + ... \ No newline at end of file diff --git a/python/testData/inspections/PyUnusedLocalInspection/parameterInMethodWithEllipsis.py b/python/testData/inspections/PyUnusedLocalInspection/parameterInMethodWithEllipsis.py new file mode 100644 index 000000000000..28998bce0824 --- /dev/null +++ b/python/testData/inspections/PyUnusedLocalInspection/parameterInMethodWithEllipsis.py @@ -0,0 +1,3 @@ +class A: + def bar(self, p): + ... \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java index c118d3effe03..f9d2b24d5067 100644 --- a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java @@ -32,7 +32,6 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { private void doTest() { runWithLanguageLevel(LanguageLevel.PYTHON36, () -> { - myFixture.copyDirectoryToProject("typing", ""); myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py"); myFixture.enableInspections(PyTypeCheckerInspection.class); myFixture.checkHighlighting(true, false, true); @@ -42,7 +41,6 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { private void doMultiFileTest() { runWithLanguageLevel(LanguageLevel.PYTHON36, () -> { myFixture.copyDirectoryToProject(TEST_DIRECTORY + getTestName(false), ""); - myFixture.copyDirectoryToProject("typing", ""); myFixture.configureFromTempProjectFile("a.py"); myFixture.enableInspections(PyTypeCheckerInspection.class); myFixture.checkHighlighting(true, false, true); @@ -237,4 +235,9 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { public void testTypingNamedTupleAsParameter() { doTest(); } + + // PY-23057 + public void testEllipsisInFunctionWithSpecifiedReturnType() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/inspections/PyStatementEffectInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyStatementEffectInspectionTest.java index a891256a33ee..f1dd73779367 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyStatementEffectInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyStatementEffectInspectionTest.java @@ -35,6 +35,11 @@ public class PyStatementEffectInspectionTest extends PyInspectionTestCase { doTest(); } + // PY-23057 + public void testFunctionWithEllipsis() { + doTest(LanguageLevel.PYTHON35); + } + private void doTest(@NotNull LanguageLevel level) { runWithLanguageLevel(level, this::doTest); } diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnusedLocalInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnusedLocalInspectionTest.java index fc997125e058..ed3ec5fdf8e2 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnusedLocalInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnusedLocalInspectionTest.java @@ -77,6 +77,11 @@ public class PyUnusedLocalInspectionTest extends PyTestCase { runWithLanguageLevel(LanguageLevel.PYTHON35, this::doTest); } + // PY-23057 + public void testParameterInMethodWithEllipsis() { + runWithLanguageLevel(LanguageLevel.PYTHON35, this::doTest); + } + private void doTest() { final String path = "inspections/PyUnusedLocalInspection/" + getTestName(true) + ".py";