diff --git a/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java b/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java
index bfb2de030fd0..a296f457bccf 100644
--- a/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java
+++ b/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java
@@ -44,10 +44,24 @@ public abstract class PyInspectionExtension {
return null;
}
+ /**
+ * @deprecated Use {@link PyInspectionExtension#ignoreMethodParameters(PyFunction, TypeEvalContext)} instead.
+ * This method will be removed in 2019.2.
+ */
+ @Deprecated
public boolean ignoreMethodParameters(@NotNull PyFunction function) {
return false;
}
+ /**
+ * @param function function that is inspecting in {@link com.jetbrains.python.inspections.PyMethodParametersInspection}
+ * @param context type evaluation context
+ * @return true if the passed function could be ignored
+ */
+ public boolean ignoreMethodParameters(@NotNull PyFunction function, @NotNull TypeEvalContext context) {
+ return ignoreMethodParameters(function);
+ }
+
public boolean ignorePackageNameInRequirements(@NotNull PyQualifiedExpression importedExpression) {
return false;
}
diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml
index 86bd3d429a83..82b42bf65eb8 100644
--- a/python/src/META-INF/python-core-common.xml
+++ b/python/src/META-INF/python-core-common.xml
@@ -814,6 +814,7 @@
+
diff --git a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java
index 089980065e7a..725b8d381fd7 100644
--- a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java
@@ -8,17 +8,14 @@ import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.ui.ComboBox;
-import com.intellij.openapi.util.Ref;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.inspections.quickfix.AddSelfQuickFix;
import com.jetbrains.python.inspections.quickfix.RenameParameterQuickFix;
import com.jetbrains.python.psi.*;
-import com.jetbrains.python.psi.resolve.ResolveImportUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -87,39 +84,19 @@ public class PyMethodParametersInspection extends PyInspection {
}
public class Visitor extends PyInspectionVisitor {
- private Ref myPossibleZopeRef = null;
public Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
super(holder, session);
}
- @Nullable
- private PsiElement findZopeInterface(PsiElement foothold) {
- PsiElement ret;
- synchronized (this) { // other threads would wait as long in resolveInRoots() anyway
- if (myPossibleZopeRef == null) {
- myPossibleZopeRef = new Ref<>();
- ret = ResolveImportUtil.resolveModuleInRoots(QualifiedName.fromDottedString("zope.interface.Interface"), foothold);
- myPossibleZopeRef.set(ret); // null is OK
- }
- else ret = myPossibleZopeRef.get();
- }
- return ret;
- }
-
@Override
public void visitPyFunction(final PyFunction node) {
for (PyInspectionExtension extension : PyInspectionExtension.EP_NAME.getExtensionList()) {
- if (extension.ignoreMethodParameters(node)) {
+ if (extension.ignoreMethodParameters(node, myTypeEvalContext)) {
return;
}
}
- // maybe it's a zope interface?
- PsiElement zope_interface = findZopeInterface(node);
- final PyClass cls = node.getContainingClass();
- if (zope_interface instanceof PyClass) {
- if (cls != null && cls.isSubclass((PyClass) zope_interface, myTypeEvalContext)) return; // it can have any params
- }
+
// analyze function itself
PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(node);
if (flags != null) {
diff --git a/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt b/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt
new file mode 100644
index 000000000000..054b7d8a7913
--- /dev/null
+++ b/python/src/com/jetbrains/python/inspections/PyThirdPartyInspectionExtension.kt
@@ -0,0 +1,37 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.jetbrains.python.inspections
+
+import com.intellij.util.containers.ContainerUtil
+import com.jetbrains.python.psi.PyElement
+import com.jetbrains.python.psi.PyExpression
+import com.jetbrains.python.psi.PyFunction
+import com.jetbrains.python.psi.PyUtil
+import com.jetbrains.python.psi.resolve.PyResolveContext
+import com.jetbrains.python.psi.resolve.QualifiedNameFinder
+import com.jetbrains.python.psi.types.TypeEvalContext
+
+class PyThirdPartyInspectionExtension : PyInspectionExtension() {
+
+ override fun ignoreMethodParameters(function: PyFunction, context: TypeEvalContext): Boolean {
+ val cls = function.containingClass
+ if (cls != null) {
+ // zope.interface.Interface inheritor could have any parameters
+ val interfaceQName = "zope.interface.interface.Interface"
+ if (cls.isSubclass(interfaceQName, context)) return true
+
+ // Checking for subclassing above does not help while zope.interface.Interface is defined as target with call expression assigned
+ val resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context)
+ for (expression in cls.superClassExpressions) {
+ if (resolvesTo(expression, interfaceQName, resolveContext)) return true
+ }
+ }
+
+ return false
+ }
+
+ private fun resolvesTo(expression: PyExpression, qualifiedName: String, resolveContext: PyResolveContext): Boolean {
+ return ContainerUtil.exists(PyUtil.multiResolveTopPriority(expression, resolveContext)) {
+ it is PyElement && QualifiedNameFinder.getQualifiedName(it) == qualifiedName
+ }
+ }
+}
\ No newline at end of file