PY-30967: Do not show "missing docstring" in case of inheritance

GitOrigin-RevId: 48b227b0818391034b2d79085862c8a6934f8c66
This commit is contained in:
Irina Fediaeva
2023-03-08 19:14:26 +02:00
committed by intellij-monorepo-bot
parent 8d7601f860
commit b805ad488d
2 changed files with 47 additions and 4 deletions

View File

@@ -10,6 +10,7 @@ import com.intellij.psi.PsiElement;
import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.inspections.quickfix.DocstringQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
/**
@@ -47,11 +48,16 @@ public class PyMissingOrEmptyDocstringInspection extends PyBaseDocstringInspecti
return;
}
if (marker == null) marker = node;
if (node instanceof PyFunction || (node instanceof PyClass && ((PyClass)node).findInitOrNew(false, null) != null)) {
if (node instanceof PyFunction pyFunction && !superFunctionHasDoc(pyFunction, myTypeEvalContext)) {
registerProblem(marker, PyPsiBundle.message("INSP.no.docstring"), new DocstringQuickFix(null, null));
}
else {
registerProblem(marker, PyPsiBundle.message("INSP.no.docstring"));
else if (node instanceof PyClass pyClass && !superClassHasDoc(pyClass, myTypeEvalContext)) {
if (pyClass.findInitOrNew(false, myTypeEvalContext) != null) {
registerProblem(marker, PyPsiBundle.message("INSP.no.docstring"), new DocstringQuickFix(null, null));
}
else {
registerProblem(marker, PyPsiBundle.message("INSP.no.docstring"));
}
}
}
else if (StringUtil.isEmptyOrSpaces(docStringExpression.getStringValue())) {
@@ -60,4 +66,26 @@ public class PyMissingOrEmptyDocstringInspection extends PyBaseDocstringInspecti
}
};
}
private static boolean superClassHasDoc(@NotNull PyClass pyClass, @NotNull TypeEvalContext context) {
for (PyClass ancestor : pyClass.getAncestorClasses(context)) {
if (StringUtil.isNotEmpty(ancestor.getDocStringValue())) {
return true;
}
}
return false;
}
private static boolean superFunctionHasDoc(@NotNull PyFunction pyFunction, @NotNull TypeEvalContext context) {
PyClass containingClass = pyFunction.getContainingClass();
if (containingClass == null) return false;
for (PyClass ancestor : containingClass.getAncestorClasses(context)) {
PyFunction superFunction = ancestor.findMethodByName(pyFunction.getName(), false, context);
if (superFunction != null && StringUtil.isNotEmpty(superFunction.getDocStringValue())) {
return true;
}
}
return false;
}
}

View File

@@ -25,4 +25,19 @@ class C:
@x.deleter
def x(self):
pass
pass
class Parent:
"""
Parent class doc
"""
def foo(self):
"""
Parent foo doc
"""
pass
class Child(Parent):
def foo(self):
pass