diff --git a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java index 3648b2c7a2a1..606a924c8589 100644 --- a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java @@ -37,7 +37,7 @@ public class PyBroadExceptionInspection extends PyInspection { return new Visitor(holder, session); } - private static boolean equalsException(@NotNull PyClass cls, @NotNull TypeEvalContext context) { + public static boolean equalsException(@NotNull PyClass cls, @NotNull TypeEvalContext context) { final PyType type = cls.getType(context); return "Exception".equals(cls.getName()) && type != null && type.isBuiltin(context); } diff --git a/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java b/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java index ef9dee54d843..8b34202bd3aa 100644 --- a/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java @@ -9,6 +9,7 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.actions.AddCallSuperQuickFix; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,8 +49,9 @@ public class PyMissingConstructorInspection extends PyInspection { if (!superHasConstructor(node)) return; PyFunction initMethod = node.findMethodByName(PyNames.INIT, false); if (initMethod != null) { - if (hasConstructorCall(node, initMethod)) + if (isExceptionClass(node, myTypeEvalContext) || hasConstructorCall(node, initMethod)) { return; + } if (superClasses.length == 1 || node.isNewStyleClass()) registerProblem(initMethod.getNameIdentifier(), "Call to constructor of super class is missed", new AddCallSuperQuickFix(node.getSuperClasses()[0], superClasses[0].getText())); @@ -69,6 +71,18 @@ public class PyMissingConstructorInspection extends PyInspection { return false; } + private boolean isExceptionClass(@NotNull PyClass cls, @NotNull TypeEvalContext context) { + if (PyBroadExceptionInspection.equalsException(cls, context)) { + return true; + } + for (PyClass baseClass : cls.iterateAncestorClasses()) { + if (PyBroadExceptionInspection.equalsException(baseClass, context)) { + return true; + } + } + return false; + } + private static boolean hasConstructorCall(PyClass node, PyFunction initMethod) { PyStatementList statementList = initMethod.getStatementList(); CallVisitor visitor = new CallVisitor(node); diff --git a/python/testData/inspections/PyMissingConstructorInspection/exception.py b/python/testData/inspections/PyMissingConstructorInspection/exception.py new file mode 100644 index 000000000000..d3b2affbd987 --- /dev/null +++ b/python/testData/inspections/PyMissingConstructorInspection/exception.py @@ -0,0 +1,7 @@ +class C(Exception): + def __init__(self, x): #pass + self.x = x + +class C(KeyError): + def __init__(self, x): #pass + self.x = x diff --git a/python/testSrc/com/jetbrains/python/inspections/PyMissingConstructorTest.java b/python/testSrc/com/jetbrains/python/inspections/PyMissingConstructorTest.java index 519e352d797e..cf734731f38c 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyMissingConstructorTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyMissingConstructorTest.java @@ -32,6 +32,11 @@ public class PyMissingConstructorTest extends PyTestCase { public void testDunderClass() { // PY-4038 doTest(); } + + // PY-7176 + public void testException() { + doTest(); + } public void testPy3k() { setLanguageLevel(LanguageLevel.PYTHON30);