PY-23057 Fixed: "Statement has no effect" inspection should ignore ellipsis operator

PyTypeCheckerInspection, PyStatementEffectInspection and PyUnusedLocalInspection consider `...` as `pass`.
This commit is contained in:
Semyon Proshev
2017-06-09 15:35:03 +03:00
parent e6447a91d6
commit 990c1be9b5
8 changed files with 34 additions and 5 deletions
@@ -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;
}
}
@@ -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;
}
@@ -0,0 +1,2 @@
def foo():
...
@@ -0,0 +1,2 @@
def bar() -> int:
...
@@ -0,0 +1,3 @@
class A:
def bar(self, p):
...
@@ -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();
}
}
@@ -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);
}
@@ -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";