diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index f71d077e7c65..6a3be8d504fd 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -2244,6 +2244,10 @@ def cut_binary_lib_suffix(path, f): m = BIN_MODULE_FNAME_PAT.match(f) if m: ret = m.group(1) + modlen = len('module') + retlen = len(ret) + if ret.endswith('module') and retlen > modlen and f.endswith('.so'): + ret = ret[:(retlen - modlen)] if f.endswith('.pyc') or f.endswith('.pyo'): fullname = os.path.join(path, f[:-1]) # check for __pycache__ is made outside if os.path.exists(fullname): diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 8bc80feaa473..6b53a9eaa80a 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -334,8 +334,9 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { if (list != null) { myBuilder.startConditionalNode(list, condition, true); list.accept(this); - if (myBuilder.prevInstruction != null) { - myBuilder.addEdge(myBuilder.prevInstruction, instruction); //loop + final Instruction prevInstruction = myBuilder.prevInstruction != null ? myBuilder.prevInstruction : getPrevInstruction(list); + if (prevInstruction != null) { + myBuilder.addEdge(prevInstruction, instruction); //loop } } myBuilder.prevInstruction = head; diff --git a/python/src/com/jetbrains/python/debugger/PyCallSignatureTypeProvider.java b/python/src/com/jetbrains/python/debugger/PyCallSignatureTypeProvider.java index 27e254986903..750edbb342b2 100644 --- a/python/src/com/jetbrains/python/debugger/PyCallSignatureTypeProvider.java +++ b/python/src/com/jetbrains/python/debugger/PyCallSignatureTypeProvider.java @@ -2,26 +2,30 @@ package com.jetbrains.python.debugger; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.PyNamedParameter; -import com.jetbrains.python.psi.PyParameterList; import com.jetbrains.python.psi.impl.PyWeakTypeFactory; -import com.jetbrains.python.psi.types.*; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.PyTypeParser; +import com.jetbrains.python.psi.types.PyTypeProviderBase; +import com.jetbrains.python.psi.types.TypeEvalContext; +import org.jetbrains.annotations.Nullable; /** * @author traff */ public class PyCallSignatureTypeProvider extends PyTypeProviderBase { public PyType getParameterType(final PyNamedParameter param, final PyFunction func, TypeEvalContext context) { - if (!(param.getParent() instanceof PyParameterList)) return null; - String type = ((PySignatureCacheManagerImpl)PySignatureCacheManager.getInstance(param.getProject())).findParameterType(param); - if (type != null) { - PyType typeByName = PyTypeParser.getTypeByName(param, type); - return buildWeakType(typeByName); - } - else { - return null; + final String name = param.getName(); + if (name != null) { + final String type = ((PySignatureCacheManagerImpl)PySignatureCacheManager.getInstance(param.getProject())).findParameterType(func, name); + if (type != null) { + final PyType typeByName = PyTypeParser.getTypeByName(param, type); + return buildWeakType(typeByName); + } } + return null; } + @Nullable private static PyType buildWeakType(PyType type) { return PyWeakTypeFactory.create(type); } diff --git a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java index dd65ea7f96f9..009811ab0b2d 100644 --- a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java +++ b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java @@ -9,11 +9,9 @@ import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScopeBuilder; -import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.django.util.VirtualFileUtil; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyNamedParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,13 +101,10 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { } @Nullable - public static String findParameterType(@NotNull PyNamedParameter parameter) { - PyFunction function = PsiTreeUtil.getParentOfType(parameter, PyFunction.class); - if (function != null) { - PySignature signature = findSignature(function); - if (signature != null) { - return signature.getArgType(parameter.getName()); - } + public static String findParameterType(@NotNull PyFunction function, @NotNull String name) { + final PySignature signature = findSignature(function); + if (signature != null) { + return signature.getArgType(name); } return null; } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 8f0530c079f1..8626533ad1c2 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -111,9 +111,6 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { @Nullable PyExpression location, @NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext) { - if (myClass == null) { - return null; - } if (resolveContext.allowProperties()) { Property property = myClass.findProperty(name); if (property != null) { @@ -141,14 +138,12 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { PyType first_arg_type = first_arg.getType(resolveContext.getTypeEvalContext()); if (first_arg_type instanceof PyClassType) { PyClass derived_class = ((PyClassType)first_arg_type).getPyClass(); - if (derived_class != null) { - final Iterator base_it = derived_class.iterateAncestorClasses().iterator(); - if (base_it.hasNext()) { - return new PyClassTypeImpl(base_it.next(), true).resolveMember(name, location, direction, resolveContext); - } - else { - return null; // no base classes = super() cannot proxy anything meaningful from a base class - } + final Iterator base_it = derived_class.iterateAncestorClasses().iterator(); + if (base_it.hasNext()) { + return new PyClassTypeImpl(base_it.next(), true).resolveMember(name, location, direction, resolveContext); + } + else { + return null; // no base classes = super() cannot proxy anything meaningful from a base class } } } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 03af7858b806..500046cb6ae0 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -323,24 +323,25 @@ public class PyTypeChecker { if (resolved instanceof PyTypedElement) { final PyTypedElement typedElement = (PyTypedElement)resolved; final PyType type = typedElement.getType(context); - if (type instanceof PyFunctionType) { - final PyFunction function = ((PyFunctionType)type).getFunction(); - final boolean isRight = PyNames.isRightOperatorName(typedElement.getName()); - final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression(); - final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression(); - final PyParameter[] parameters = function.getParameterList().getParameters(); - if (parameters.length >= 2) { - final PyNamedParameter param = parameters[1].getAsNamed(); - if (arg != null && param != null) { - final Map arguments = new LinkedHashMap(); - arguments.put(arg, param); - final AnalyzeCallResults results = new AnalyzeCallResults(function, receiver, arguments); - if (firstResults == null) { - firstResults = results; - } - if (match(param.getType(context), arg.getType(context), context)) { - return results; - } + if (!(type instanceof PyFunctionType)) { + return null; + } + final PyFunction function = ((PyFunctionType)type).getFunction(); + final boolean isRight = PyNames.isRightOperatorName(typedElement.getName()); + final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression(); + final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression(); + final PyParameter[] parameters = function.getParameterList().getParameters(); + if (parameters.length >= 2) { + final PyNamedParameter param = parameters[1].getAsNamed(); + if (arg != null && param != null) { + final Map arguments = new LinkedHashMap(); + arguments.put(arg, param); + final AnalyzeCallResults results = new AnalyzeCallResults(function, receiver, arguments); + if (firstResults == null) { + firstResults = results; + } + if (match(param.getType(context), arg.getType(context), context)) { + return results; } } } diff --git a/python/testData/inspections/PyTypeCheckerInspection/AssignedOperator.py b/python/testData/inspections/PyTypeCheckerInspection/AssignedOperator.py new file mode 100644 index 000000000000..d5edd3dc8440 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/AssignedOperator.py @@ -0,0 +1,8 @@ +def f(x): + return x + +class C(object): + __div__, __rdiv__ = f(0) + +c = C() +print(c / 2) diff --git a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py index ec747ac101f2..345b4ce18440 100644 --- a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py +++ b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py @@ -286,3 +286,11 @@ class C: # PY-7126 def test_unused_empty_function(x): pass + + +# PY-7072 +def test_unused_variable_in_cycle(x, c): + while x > 0: + x -= 1 #pass + if c: + break diff --git a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java index 7bf8bc23d398..0169210658f1 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java @@ -135,4 +135,9 @@ public class PyTypeCheckerInspectionTest extends PyTestCase { public void testDecoratedFunction() { doTest(); } + + // PY-6925 + public void testAssignedOperator() { + doTest(); + } }