import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import com.intellij.util.Processor;
-import com.jetbrains.python.*;
+import com.jetbrains.python.PyElementTypes;
+import com.jetbrains.python.PyNames;
+import com.jetbrains.python.PyTokenTypes;
+import com.jetbrains.python.PythonDialectsTokenSetProvider;
import com.jetbrains.python.codeInsight.PyTypingTypeProvider;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
}
}
}
+
+ @Override
+ public void visitPyCallExpression(PyCallExpression node) {
+ Optional
+ .ofNullable(node.getCallee())
+ .map(context::getType)
+ .map(type -> PyUtil.as(type, PyFunctionType.class))
+ .map(PyFunctionType::getCallable)
+ .map(PyCallable::getName)
+ .filter("len"::equals)
+ .ifPresent(
+ callable -> {
+ final PyReferenceExpression argument = node.getArgument(0, PyReferenceExpression.class);
+ if (argument != null && argument.getReference().isReferenceTo(PyNamedParameterImpl.this)) {
+ result.add(PyNames.LEN);
+ }
+ }
+ );
+
+ super.visitPyCallExpression(node);
+ }
});
}
return result;
<weak_warning descr="Assignment can be replaced with augmented assignment">values1 = values1 + values2</weak_warning>
-#def expand(values1, values2):
-# a = len(values1)
-# b = len(values2)
-#
-# values1 = values2 + values1
-# values1 = values1 + values2
-# inspection should suggest replacement only for the second assignment
+def expand(values1, values2):
+ a = len(values1)
+ b = len(values2)
+
+ values1 = values2 + values1
+ <weak_warning descr="Assignment can be replaced with augmented assignment">values1 = values1 + values2</weak_warning>
#def expand(values1, values2):
"expr = f\n");
}
+ // PY-20833
+ public void testStructuralTypeWithDunderLen() {
+ doTest("{__len__}",
+ "def expand(values1):\n" +
+ " a = len(values1)\n" +
+ " expr = values1\n");
+ }
+
// PY-16267
public void testGenericField() {
doTest("str",