From fcb06c9523ef78f592e8bf859b9b25f0ab8cdc00 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 18 Sep 2013 13:09:53 +0400 Subject: [PATCH 1/4] handle nulls in superclasstypes do not unstub in class has no init inspection --- .../PyClassHasNoInitInspection.java | 18 +++++++++++------- .../PyOldStyleClassesInspection.java | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyClassHasNoInitInspection.java b/python/src/com/jetbrains/python/inspections/PyClassHasNoInitInspection.java index 56e0e1f90183..1bc5e080e13a 100644 --- a/python/src/com/jetbrains/python/inspections/PyClassHasNoInitInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyClassHasNoInitInspection.java @@ -3,18 +3,20 @@ package com.jetbrains.python.inspections; import com.intellij.codeInspection.LocalInspectionToolSession; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.PsiReference; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.inspections.quickfix.AddMethodQuickFix; import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.types.PyClassLikeType; +import com.jetbrains.python.psi.types.PyClassType; import com.jetbrains.python.psi.types.PyClassTypeImpl; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * User: ktisha * See pylint W0232 @@ -42,12 +44,14 @@ public class PyClassHasNoInitInspection extends PyInspection { @Override public void visitPyClass(PyClass node) { - final PyExpression[] classes = node.getSuperClassExpressions(); - for (PyExpression pyClass : classes) { - final PsiReference reference = pyClass.getReference(); - if (reference == null || reference.resolve() == null) return; - if (reference.getCanonicalText().contains(PyNames.TEST_CASE)) return; + final List types = node.getSuperClassTypes(myTypeEvalContext); + for (PyClassLikeType type : types) { + if (type == null) return; + final String qName = type.getClassQName(); + if (qName != null && qName.contains(PyNames.TEST_CASE)) return; + if (!(type instanceof PyClassType)) return; } + final PyFunction init = node.findInitOrNew(true); if (init == null) { registerProblem(node.getNameIdentifier(), PyBundle.message("INSP.class.has.no.init"), diff --git a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java index c8ddf0034715..5aa05194ea4b 100644 --- a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java @@ -62,6 +62,7 @@ public class PyOldStyleClassesInspection extends PyInspection { if (klass != null && !klass.isNewStyleClass()) { final List types = klass.getSuperClassTypes(myTypeEvalContext); for (PyClassLikeType type : types) { + if (type == null) return; final String qName = type.getClassQName(); if (qName != null && qName.contains("PyQt")) return; if (!(type instanceof PyClassType)) return; From b8927f4d734c3334abc54fbff836f547aa702718 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 18 Sep 2013 13:40:59 +0400 Subject: [PATCH 2/4] fixed PY-10458 Chameleon: comment with block comment does nothing inside html ad pt files --- python/src/META-INF/python-plugin-common.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index 73f6d6f394cc..6c1bea107187 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -389,6 +389,7 @@ + From 36394cbad7f42ff1303a213082d2a6ea7509e5a1 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 18 Sep 2013 18:36:13 +0400 Subject: [PATCH 3/4] do not map implicit arguments to **args fixed PY-10487 Garbled parameter info for call with double-starred arguments --- .../psi/impl/CallArgumentsMappingImpl.java | 18 ++++++++++-------- python/testData/paramInfo/KwdArgInClass.py | 9 +++++++++ .../jetbrains/python/PyParameterInfoTest.java | 5 +++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 python/testData/paramInfo/KwdArgInClass.py diff --git a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java index 7122f4c93bc2..4f71bd786f70 100644 --- a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java @@ -79,12 +79,12 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { PyNamedParameter kwd_par = null; // **param PyNamedParameter tuple_par = null; // *param Set mapped_args = new HashSet(); - final int implicit_offset = resolved_callee.getImplicitOffset(); + final int implicitOffset = resolved_callee.getImplicitOffset(); int positional_index = 0; // up to this index parameters are positional // check positional arguments, fill slots int i = 0; for (PyParameter par : parameters) { - if (tuple_par == null && kwd_par == null && positional_index < implicit_offset) { + if (tuple_par == null && kwd_par == null && positional_index < implicitOffset) { positional_index += 1; continue; } @@ -107,14 +107,14 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { i += 1; } // rule out 'self' or other implicit params - for (i=0; i < implicit_offset && i < parameters.size(); i+=1) { + for (i=0; i < implicitOffset && i < parameters.size(); i+=1) { slots.remove(parameters.get(i).getAsNamed()); positional_index += 1; } // now params to the left of positional_index are positional. // map positional args to positional params. // we assume that implicitly skipped parameters are never nested tuples. no idea when they could ever be. - int cnt = implicit_offset; + int cnt = implicitOffset; int positional_bound = arguments.length; // to the right of this pos args are verboten ListIterator unmatched_arg_iter = unmatched_args.listIterator(); while (unmatched_arg_iter.hasNext()) { @@ -290,10 +290,12 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { } // map unmapped named params to **kwarg if (myKwdArg != null) { - for (PyParameter par : parameters) { - PyNamedParameter n_par = par.getAsNamed(); - if (n_par != null && !n_par.isKeywordContainer() && !n_par.isPositionalContainer() && slots.get(n_par) == null) { - slots.put(n_par, myKwdArg); + for (int j = implicitOffset; j != parameters.size(); ++j) { + final PyParameter par = parameters.get(j); + final PyNamedParameter namedParameter = par.getAsNamed(); + if (namedParameter != null && !namedParameter.isKeywordContainer() + && !namedParameter.isPositionalContainer() && slots.get(namedParameter) == null) { + slots.put(namedParameter, myKwdArg); } } } diff --git a/python/testData/paramInfo/KwdArgInClass.py b/python/testData/paramInfo/KwdArgInClass.py new file mode 100644 index 000000000000..8bfc48529a42 --- /dev/null +++ b/python/testData/paramInfo/KwdArgInClass.py @@ -0,0 +1,9 @@ +class A: + def foo(self, e): + self.kw = {} + self.add_comm(**self.kw) + + + def add_comm(self, **kw): + self.kw = [] + diff --git a/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java b/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java index d4f40cf21e94..1c931314f20c 100644 --- a/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java +++ b/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java @@ -132,6 +132,11 @@ public class PyParameterInfoTest extends LightMarkedTestCase { feignCtrlP(marks.get("").getTextOffset()).check("a, b, c", new String[]{"b, ","c"}); } + public void testKwdArgInClass() { + Map marks = loadTest(1); + feignCtrlP(marks.get("").getTextOffset()).check("self, **kw", new String[]{"**kw"}, new String[]{"self, "}); + } + public void testKwdArgOutOfOrder() { Map marks = loadTest(3); From c5e734d36f86392a823c805d1f51cb52180fdaa4 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 18 Sep 2013 18:43:06 +0400 Subject: [PATCH 4/4] use proper type eval context for parameter info popup --- python/src/com/jetbrains/python/PyParameterInfoHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/PyParameterInfoHandler.java b/python/src/com/jetbrains/python/PyParameterInfoHandler.java index 07b004da2c68..d1a5bd5afb5c 100644 --- a/python/src/com/jetbrains/python/PyParameterInfoHandler.java +++ b/python/src/com/jetbrains/python/PyParameterInfoHandler.java @@ -39,7 +39,9 @@ public class PyParameterInfoHandler implements ParameterInfoHandler