PY-58658 Drop an inspection setting for metaclass "self" name, recognize more aliases

GitOrigin-RevId: 73f53f7e3318eafb87373387ea65426cc1c28662
This commit is contained in:
Mikhail Golubev
2022-12-22 17:33:29 +02:00
committed by intellij-monorepo-bot
parent 6f579e7854
commit 417ae25578
5 changed files with 35 additions and 54 deletions

View File

@@ -5,9 +5,7 @@ import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
@@ -21,16 +19,12 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.codeInspection.options.OptPane.*;
import java.util.Set;
/**
* Looks for the 'self' or its equivalents.
*/
public class PyMethodParametersInspection extends PyInspection {
private static final @NlsSafe String MODE_MCS = "mcs";
private static final @NlsSafe String MODE_METACLS = "metacls";
public String MCS = MODE_MCS;
@Nullable
public static PyMethodParametersInspection getInstance(@NotNull PsiElement element) {
@@ -39,16 +33,6 @@ public class PyMethodParametersInspection extends PyInspection {
return (PyMethodParametersInspection)inspectionProfile.getUnwrappedTool(toolName, element);
}
@Override
public @NotNull OptPane getOptionsPane() {
//TODO: simplify this (drop this?)
// it should offer only one default option mcs or metacls, inspection should accept both
return pane(
dropdown("MCS", PyPsiBundle.message("INSP.method.parameters.metaclass.method.first.argument.name"),
option(MODE_MCS, MODE_MCS), option(MODE_METACLS, MODE_METACLS))
);
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
@@ -57,7 +41,7 @@ public class PyMethodParametersInspection extends PyInspection {
return new Visitor(holder, PyInspectionVisitor.getContext(session));
}
private class Visitor extends PyInspectionVisitor {
private static class Visitor extends PyInspectionVisitor {
private Visitor(@Nullable ProblemsHolder holder, @NotNull TypeEvalContext context) {
super(holder, context);
@@ -77,7 +61,6 @@ public class PyMethodParametersInspection extends PyInspection {
PyParameterList plist = node.getParameterList();
PyParameter[] params = plist.getParameters();
final String methodName = node.getName();
final String CLS = "cls"; // TODO: move to style settings
if (params.length == 0) { // fix: add
// check for "staticmetod"
if (flags.isStaticMethod()) return; // no params may be fine
@@ -91,16 +74,8 @@ public class PyMethodParametersInspection extends PyInspection {
"(".equals(open_paren.getText()) && ")".equals(close_paren.getText())
) {
String paramName;
if (flags.isMetaclassMethod()) {
if (flags.isClassMethod()) {
paramName = MCS;
}
else {
paramName = CLS;
}
}
else if (flags.isClassMethod()) {
paramName = CLS;
if (flags.isMetaclassMethod() || flags.isClassMethod()) {
paramName = PyNames.CANONICAL_CLS;
}
else {
paramName = PyNames.CANONICAL_SELF;
@@ -134,18 +109,20 @@ public class PyMethodParametersInspection extends PyInspection {
return;
}
String expectedName;
String alternativeName = null;
Set<String> alternativeNames;
if (PyNames.NEW.equals(methodName) || flags.isClassMethod()) {
expectedName = MCS;
expectedName = PyNames.CANONICAL_CLS;
alternativeNames = Set.of("mcs", "mcls", "metacls");
}
else if (flags.isSpecialMetaclassMethod()) {
expectedName = CLS;
expectedName = PyNames.CANONICAL_CLS;
alternativeNames = Set.of();
}
else {
expectedName = PyNames.CANONICAL_SELF;
alternativeName = CLS;
alternativeNames = Set.of(PyNames.CANONICAL_CLS);
}
if (!expectedName.equals(pname) && (alternativeName == null || !alternativeName.equals(pname))) {
if (!expectedName.equals(pname) && !alternativeNames.contains(pname)) {
registerProblem(
PyUtil.sure(params[0].getNode()).getPsi(),
PyPsiBundle.message("INSP.usually.named", expectedName),
@@ -154,11 +131,11 @@ public class PyMethodParametersInspection extends PyInspection {
}
}
else if (flags.isClassMethod() || PyNames.NEW.equals(methodName)) {
if (!CLS.equals(pname)) {
if (!PyNames.CANONICAL_CLS.equals(pname)) {
registerProblem(
PyUtil.sure(params[0].getNode()).getPsi(),
PyPsiBundle.message("INSP.usually.named", CLS),
new RenameParameterQuickFix(CLS)
PyPsiBundle.message("INSP.usually.named", PyNames.CANONICAL_CLS),
new RenameParameterQuickFix(PyNames.CANONICAL_CLS)
);
}
}

View File

@@ -1264,7 +1264,9 @@ maxstring
maybesave
mbcs
mbstate
mcls
mcontext
mcs
mdays
mdiff
memmove
@@ -1273,6 +1275,7 @@ memset
menubutton
menudefs
metaclass
metacls
metas
metastrings
metavar

View File

@@ -62,7 +62,7 @@ class Meta(type):
def foo(<weak_warning descr="Usually first parameter of such methods is named 'self'">first</weak_warning>): # rename to "self"
pass
def __new__(<weak_warning descr="Usually first parameter of such methods is named 'mcs'">self</weak_warning>, *rest): # rename to "mcs"
def __new__(<weak_warning descr="Usually first parameter of such methods is named 'cls'">self</weak_warning>, *rest): # rename to "mcs"
pass
def __call__(<weak_warning descr="Usually first parameter of such methods is named 'cls'">self</weak_warning>): # rename to "cls"
@@ -72,9 +72,25 @@ class Meta(type):
return "foobar"
@classmethod
def baz(<weak_warning descr="Usually first parameter of such methods is named 'mcs'">moo</weak_warning>): # <- rename to "mcs"
def baz(<weak_warning descr="Usually first parameter of such methods is named 'cls'">moo</weak_warning>): # <- rename to "mcs"
return "foobar"
@classmethod
def cls_is_preferred(cls):
pass
@classmethod
def mcls_is_valid(mcls):
pass
@classmethod
def mcs_is_valid(mcs):
pass
@classmethod
def metacls_is_valid(metacls):
pass
@staticmethod
def bazz(param1):
return "foobar"

View File

@@ -1,7 +0,0 @@
class Meta(type):
def __new__(<weak_warning descr="Usually first parameter of such methods is named 'metacls'">self</weak_warning>, *rest): # rename to "metacls"
pass
@classmethod
def baz(<weak_warning descr="Usually first parameter of such methods is named 'metacls'">moo</weak_warning>): # <- rename to "metacls"
return "foobar"

View File

@@ -50,14 +50,6 @@ public class PythonInspectionsTest extends PyTestCase {
doHighlightingTest(PyMethodParametersInspection.class);
}
public void testPyMethodParametersInspectionMetacls() {
PyMethodParametersInspection inspection = new PyMethodParametersInspection();
inspection.MCS = "metacls";
myFixture.configureByFile("inspections/" + getTestName(false) + "/test.py");
myFixture.enableInspections(inspection);
myFixture.checkHighlighting(true, false, true);
}
public void testPyMethodParametersInspectionInitSubclass() {
doHighlightingTest(PyMethodParametersInspection.class, LanguageLevel.PYTHON36);
}