diff --git a/python/src/com/jetbrains/python/psi/impl/PyParameterListImpl.java b/python/src/com/jetbrains/python/psi/impl/PyParameterListImpl.java index a097c41995d2..ee1df4f3b38a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyParameterListImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyParameterListImpl.java @@ -63,93 +63,29 @@ public class PyParameterListImpl extends PyBaseElementImpl return false; } - public boolean isCompatibleTo(@NotNull PyParameterList another) { - PyParameter[] parameters = getParameters(); - final PyParameter[] anotherParameters = another.getParameters(); - final int parametersLength = parameters.length; - final int anotherParametersLength = anotherParameters.length; - if (parametersLength == anotherParametersLength) { - if (hasPositionalContainer() == another.hasPositionalContainer() && hasKeywordContainer() == another.hasKeywordContainer()) { - return true; - } + public boolean isCompatibleTo(@NotNull PyParameterList other) { + PyParameter[] params = getParameters(); + final PyParameter[] otherParams = other.getParameters(); + if (hasPositionalContainer() || hasKeywordContainer()) { + return true; } - - int i = 0; - int j = 0; - while (i < parametersLength && j < anotherParametersLength) { - PyParameter parameter = parameters[i]; - PyParameter anotherParameter = anotherParameters[j]; - if (parameter instanceof PyNamedParameter && anotherParameter instanceof PyNamedParameter) { - PyNamedParameter namedParameter = (PyNamedParameter)parameter; - PyNamedParameter anotherNamedParameter = (PyNamedParameter)anotherParameter; - - if (namedParameter.isPositionalContainer()) { - while (j < anotherParametersLength - && !anotherNamedParameter.isPositionalContainer() - && !anotherNamedParameter.isKeywordContainer()) { - anotherParameter = anotherParameters[j++]; - anotherNamedParameter = (PyNamedParameter) anotherParameter; - } - ++i; - continue; - } - - if (anotherNamedParameter.isPositionalContainer()) { - while (i < parametersLength - && !namedParameter.isPositionalContainer() - && !namedParameter.isKeywordContainer()) { - parameter = parameters[i++]; - namedParameter = (PyNamedParameter) parameter; - } - ++j; - continue; - } - - if (namedParameter.isKeywordContainer() || anotherNamedParameter.isKeywordContainer()) { - break; - } + final PyFunction otherFunction = other.getContainingFunction(); + final boolean otherHasArgs = other.hasPositionalContainer(); + final boolean otherHasKwargs = other.hasKeywordContainer(); + if (otherHasArgs || otherHasKwargs) { + int specialParamsCount = 0; + if (otherHasArgs) { + specialParamsCount++; } - - // both are simple parameters - ++i; - ++j; - } - - if (i < parametersLength) { - if (parameters[i] instanceof PyNamedParameter) { - final PyNamedParameter nextParameter = (PyNamedParameter)parameters[i]; - if (nextParameter.isKeywordContainer() || nextParameter.isPositionalContainer()) { - ++i; - } - while (nextParameter.isKeywordContainer() && j= parametersLength) && (j >= anotherParametersLength); - // - //if (weHaveStarred && parameters.length - 1 <= anotherParameters.length) { - // if (weHaveDoubleStarred == anotherHasDoubleStarred) { - // return true; - // } - //} - //if ((anotherHasDoubleStarred && parameters.length == anotherParameters.length - 1) - // || (weHaveDoubleStarred && parameters.length == anotherParameters.length + 1)) { - // return true; - //} - //return false; + return params.length == otherParams.length; } @Override diff --git a/python/testData/inspections/PyMethodOverridingInspection/expected.xml b/python/testData/inspections/PyMethodOverridingInspection/expected.xml deleted file mode 100644 index 364ca8c654d8..000000000000 --- a/python/testData/inspections/PyMethodOverridingInspection/expected.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - method-overriding.py - 10 - Method signature does not match signature of base method - - - method-overriding.py - 14 - Method signature does not match signature of base method - - - method-overriding.py - 46 - Method signature does not match signature of base method - - diff --git a/python/testData/inspections/PyMethodOverridingInspection/test.py b/python/testData/inspections/PyMethodOverridingInspection/test.py new file mode 100644 index 000000000000..1ee30bab8e9e --- /dev/null +++ b/python/testData/inspections/PyMethodOverridingInspection/test.py @@ -0,0 +1,105 @@ +class c1: + def foo(self, a): + pass + +class c2(c1): + def foo(self, *a): + pass + +class c3(c1): + def foo(self): + pass + +class c4(c1): + def foo(self, **a): + pass + +class c5(c1): + def foo(self, a): + pass + +class c6: + pass + +class c7(c6): + def foo(self): + pass + +class c8: + def __init__(self): + pass + + def __new__(self): + pass + + def foo(self, a): + pass + + +class c9(c8): + def __init__(self, a): # different but ok because __init__ is special + pass + + def __new__(self, p, q): # different but ok because __new__ is special + pass + + def foo(self, s, t): + pass + +class c10: + def foo(self, a, b): + pass + +class c11(c10): + def foo(self, *b): + pass + +class c12(c4): + def foo(self): + pass + +class c13: + def foo(self, *args): + pass + +class c14(c13): + def foo(self): + pass + +class c15: # PY-1083 + def foo(self, x = 1): + pass + +class c16: + def foo(self, **kwargs): + pass + + +# PY-6700 +class c17: + def foo(self, **kwargs): + pass + +class c18(c17): + def foo(self, arg1=None, **kwargs): # pass + pass + +class c19: + def foo(self, *args, **kwargs): + raise NotImplementedError() + +class c20(c19): + def foo(self): # pass + pass + +class c21(c19): + def foo(self, arg1): # pass + pass + +class c22: + def foo(self, arg1, *args, **kwargs): + raise NotImplementedError() + +class c23(c22): + def foo(self, arg1, arg2=None): # fail + pass diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index 2f229c9fa07f..8f63f47a57ab 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -70,7 +70,7 @@ public class PythonInspectionsTest extends PyTestCase { public void testPyMethodOverridingInspection() { LocalInspectionTool inspection = new PyMethodOverridingInspection(); - doTest(getTestName(false), inspection); + doHighlightingTest(inspection); } public void testPyTrailingSemicolonInspection() {