From 27543fe191430ed05646523e2a5f487c57390815 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Wed, 28 Sep 2016 19:39:41 +0300 Subject: [PATCH] PY-20946 Fixed: False positive: `__init_subclass__` method first parameter should be named "self" Update PyMethodParametersInspection to correctly handle Python 3.6 __init_subclass__ method. This method is implicitly a @classmethod --- python/psi-api/src/com/jetbrains/python/PyNames.java | 3 ++- .../inspections/PyMethodParametersInspection.java | 4 +++- .../PyMethodParametersInspectionInitSubclass/test.py | 10 ++++++++++ .../com/jetbrains/python/PythonInspectionsTest.java | 4 ++++ 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 python/testData/inspections/PyMethodParametersInspectionInitSubclass/test.py diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index f3f787a39390..651e67039aeb 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -170,6 +170,7 @@ public class PyNames { public static final String AENTER = "__aenter__"; public static final String AEXIT = "__aexit__"; public static final String SIZEOF = "__sizeof__"; + public static final String INIT_SUBCLASS = "__init_subclass__"; public static final String NAME = "__name__"; public static final String ENTER = "__enter__"; @@ -434,7 +435,7 @@ public class PyNames { public static final ImmutableMap PY36_BUILTIN_METHODS = ImmutableMap.builder() .putAll(PY35_BUILTIN_METHODS) - .put("__init_subclass__", new BuiltinDescription("(cls, **kwargs)")) + .put(INIT_SUBCLASS, new BuiltinDescription("(cls, **kwargs)")) .put("__set_name__", new BuiltinDescription("(self, owner, name)")) .build(); diff --git a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java index 86b763820513..e60ba1dbee4c 100644 --- a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java @@ -205,7 +205,9 @@ public class PyMethodParametersInspection extends PyInspection { ); } } - else if (flags.isClassMethod() || PyNames.NEW.equals(methodName)) { + else if (flags.isClassMethod() || + PyNames.NEW.equals(methodName) || + PyNames.INIT_SUBCLASS.equals(methodName) && LanguageLevel.forElement(node).isAtLeast(LanguageLevel.PYTHON36)) { if (!CLS.equals(pname)) { registerProblem( PyUtil.sure(params[0].getNode()).getPsi(), diff --git a/python/testData/inspections/PyMethodParametersInspectionInitSubclass/test.py b/python/testData/inspections/PyMethodParametersInspectionInitSubclass/test.py new file mode 100644 index 000000000000..794d1177cae6 --- /dev/null +++ b/python/testData/inspections/PyMethodParametersInspectionInitSubclass/test.py @@ -0,0 +1,10 @@ +class QuestBase: + def __init_subclass__(cls, swallow, **kwargs): + cls.swallow = swallow + super().__init_subclass__(**kwargs) + + +class QuestBase: + def __init_subclass__(self, swallow, **kwargs): + self.swallow = swallow + super().__init_subclass__(**kwargs) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index da69bbbdfa4d..76130c106c11 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -69,6 +69,10 @@ public class PythonInspectionsTest extends PyTestCase { myFixture.checkHighlighting(true, false, true); } + public void testPyMethodParametersInspectionInitSubclass() { + doHighlightingTest(PyMethodParametersInspection.class, LanguageLevel.PYTHON36); + } + public void testPyNestedDecoratorsInspection() { LocalInspectionTool inspection = new PyNestedDecoratorsInspection(); doTest(getTestName(false), inspection);