Don't analyze arguments to object method called through super (PY-25497)

This commit is contained in:
Semyon Proshev
2018-02-26 15:40:32 +03:00
parent e705a4d46f
commit b4ac9e94d6
3 changed files with 66 additions and 0 deletions
@@ -123,6 +123,8 @@ public class PyArgumentListInspection extends PyInspection {
decoratedClassInitCall(call.getCallee(), function, context)) {
return;
}
if (objectMethodCallViaSuper(call, function)) return;
}
}
}
@@ -153,6 +155,42 @@ public class PyArgumentListInspection extends PyInspection {
return false;
}
private static boolean objectMethodCallViaSuper(@NotNull PyCallExpression call, @NotNull PyFunction function) {
/*
Class could be designed to be used in cooperative multiple inheritance
so `super()` could be resolved to some non-object class that is able to receive passed arguments.
Example:
class Shape(object):
def __init__(self, shapename, **kwds):
self.shapename = shapename
# in case of ColoredShape the call below will be executed on Colored
# so warning should not be raised
super(Shape, self).__init__(**kwds)
class Colored(object):
def __init__(self, color, **kwds):
self.color = color
super(Colored, self).__init__(**kwds)
class ColoredShape(Shape, Colored):
pass
*/
final PyClass receiverClass = function.getContainingClass();
if (receiverClass != null && PyUtil.isObjectClass(receiverClass)) {
final PyExpression receiverExpression = call.getReceiver(null);
if (receiverExpression instanceof PyCallExpression && PyUtil.isSuperCall((PyCallExpression)receiverExpression)) {
return true;
}
}
return false;
}
private static void highlightStarArgumentTypeMismatch(PyArgumentList node, ProblemsHolder holder, TypeEvalContext context) {
for (PyExpression arg : node.getArguments()) {
if (arg instanceof PyStarArgument) {
@@ -0,0 +1,23 @@
# Class could be designed to be used in cooperative multiple inheritance
# so `super()` could be resolved to some non-object class that is able to receive passed arguments.
class Shape(object):
def __init__(self, shapename, **kwds):
self.shapename = shapename
# in case of ColoredShape the call below will be executed on Colored
# so warning should not be raised
super(Shape, self).__init__(**kwds)
class Colored(object):
def __init__(self, color, **kwds):
self.color = color
super(Colored, self).__init__(**kwds)
class ColoredShape(Shape, Colored):
pass
cs = ColoredShape(color='red', shapename='circle')
@@ -337,4 +337,9 @@ public class PyArgumentListInspectionTest extends PyInspectionTestCase {
public void testInitializingImportedTypingNamedTupleInheritor() {
runWithLanguageLevel(LanguageLevel.PYTHON37, this::doMultiFileTest);
}
// PY-25497
public void testObjectMethodInPossiblyInheritanceChain() {
doTest();
}
}