mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-25045 Fixed: False positive: expected type '{__div__}', got 'Union[int, float]' instead
Update PyBinaryExpressionImpl to return `__truediv__` as referenced name instead of `__div__` when it is enabled.
This commit is contained in:
@@ -17,6 +17,7 @@ package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -24,6 +25,7 @@ import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyOperatorReference;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -209,6 +211,9 @@ public class PyBinaryExpressionImpl extends PyElementImpl implements PyBinaryExp
|
||||
@Override
|
||||
public String getReferencedName() {
|
||||
final PyElementType t = getOperator();
|
||||
if (t == PyTokenTypes.DIV && isTrueDivEnabled(this)) {
|
||||
return PyNames.TRUEDIV;
|
||||
}
|
||||
return t != null ? t.getSpecialMethodName() : null;
|
||||
}
|
||||
|
||||
@@ -217,4 +222,13 @@ public class PyBinaryExpressionImpl extends PyElementImpl implements PyBinaryExp
|
||||
final PsiElement op = getPsiOperator();
|
||||
return op != null ? op.getNode() : null;
|
||||
}
|
||||
|
||||
private static boolean isTrueDivEnabled(@NotNull PyElement anchor) {
|
||||
final PsiFile file = anchor.getContainingFile();
|
||||
if (file instanceof PyFile) {
|
||||
final PyFile pyFile = (PyFile)file;
|
||||
return FutureFeature.DIVISION.requiredAt(pyFile.getLanguageLevel()) || pyFile.hasImportFromFuture(FutureFeature.DIVISION);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@ package com.jetbrains.python.psi.impl.references;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
@@ -54,9 +53,6 @@ public class PyOperatorReference extends PyReferenceImpl {
|
||||
res = resolveMember(expr.getRightExpression(), name);
|
||||
}
|
||||
else {
|
||||
if (PyNames.DIV.equals(name) && isTrueDivEnabled(myElement)) {
|
||||
resolveLeftAndRightOperators(res, expr, PyNames.TRUEDIV);
|
||||
}
|
||||
resolveLeftAndRightOperators(res, expr, name);
|
||||
}
|
||||
}
|
||||
@@ -125,15 +121,6 @@ public class PyOperatorReference extends PyReferenceImpl {
|
||||
return name.replaceFirst("__([a-z]+)__", "__r$1__");
|
||||
}
|
||||
|
||||
private static boolean isTrueDivEnabled(@NotNull PyElement anchor) {
|
||||
final PsiFile file = anchor.getContainingFile();
|
||||
if (file instanceof PyFile) {
|
||||
final PyFile pyFile = (PyFile)file;
|
||||
return FutureFeature.DIVISION.requiredAt(pyFile.getLanguageLevel()) || pyFile.hasImportFromFuture(FutureFeature.DIVISION);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void resolveLeftAndRightOperators(List<RatedResolveResult> res, PyBinaryExpression expr, String name) {
|
||||
final TypeEvalContext typeEvalContext = myContext.getTypeEvalContext();
|
||||
typeEvalContext.trace("Trying to resolve left operator");
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
from typing import Union
|
||||
|
||||
|
||||
def foo(x):
|
||||
return x / (60 * 60)
|
||||
|
||||
bar = 0 # type: Union[int, float]
|
||||
foo(bar)
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
class D1(object):
|
||||
def __div__(self, other) -> "D1": ...
|
||||
def __truediv__(self, other) -> "D1": ...
|
||||
|
||||
class D2(object):
|
||||
def __rtruediv__(self, other) -> "D2": ...
|
||||
@@ -483,7 +483,7 @@ public class Py3TypeTest extends PyTestCase {
|
||||
|
||||
public void testNumpyResolveRaterDoesNotIncreaseRateForNotNdarrayRightOperatorFoundInStub() {
|
||||
myFixture.copyDirectoryToProject(TEST_DIRECTORY + getTestName(false), "");
|
||||
doTest("Union[D2, D1]",
|
||||
doTest("Union[D1, D2]",
|
||||
"class D1(object):\n" +
|
||||
" pass\n" +
|
||||
"class D2(object):\n" +
|
||||
|
||||
@@ -255,4 +255,9 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase {
|
||||
public void testPromotingBytearrayToBytes() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-25045
|
||||
public void testUnionOfIntAndFloatShouldBeConsideredAsDividable() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user