mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
PY-49697 Fix false positive for metaclass overloaded __or__
(cherry picked from commit d8e327da30c0b359c8eb3b890c72c41a9c3c4444) IJ-MR-11817 GitOrigin-RevId: a21ecb8b66e3510abc4401ac351789a858482463
This commit is contained in:
committed by
intellij-monorepo-bot
parent
059867630f
commit
f84e2d8452
@@ -28,8 +28,13 @@ import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
|||||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider;
|
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider;
|
||||||
import com.jetbrains.python.inspections.quickfix.*;
|
import com.jetbrains.python.inspections.quickfix.*;
|
||||||
import com.jetbrains.python.psi.*;
|
import com.jetbrains.python.psi.*;
|
||||||
|
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||||
import com.jetbrains.python.psi.types.*;
|
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||||
|
import com.jetbrains.python.psi.types.PyClassType;
|
||||||
|
import com.jetbrains.python.psi.types.PyType;
|
||||||
|
import com.jetbrains.python.psi.types.PyUnionType;
|
||||||
|
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||||
import org.jetbrains.annotations.Nls;
|
import org.jetbrains.annotations.Nls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -729,6 +734,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
|
|||||||
|
|
||||||
private void checkBitwiseOrUnionSyntax(@NotNull PyBinaryExpression node) {
|
private void checkBitwiseOrUnionSyntax(@NotNull PyBinaryExpression node) {
|
||||||
if (node.getOperator() != PyTokenTypes.OR) return;
|
if (node.getOperator() != PyTokenTypes.OR) return;
|
||||||
|
|
||||||
final PsiFile file = node.getContainingFile();
|
final PsiFile file = node.getContainingFile();
|
||||||
if (file == null ||
|
if (file == null ||
|
||||||
file instanceof PyFile &&
|
file instanceof PyFile &&
|
||||||
@@ -737,10 +743,21 @@ public abstract class CompatibilityVisitor extends PyAnnotator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final TypeEvalContext context = TypeEvalContext.codeAnalysis(node.getProject(), node.getContainingFile());
|
||||||
|
|
||||||
|
final List<PsiElement> resolvedVariants = PyUtil.multiResolveTopPriority(node.getReference(PyResolveContext.defaultContext(context)));
|
||||||
|
for (PsiElement resolved : resolvedVariants) {
|
||||||
|
if (resolved instanceof PyFunction) {
|
||||||
|
final PyClass containingClass = ((PyFunction)resolved).getContainingClass();
|
||||||
|
if (containingClass == null) return;
|
||||||
|
final String classQualifiedName = containingClass.getQualifiedName();
|
||||||
|
if (!PyNames.TYPE.equals(classQualifiedName) && !"types.Union".equals(classQualifiedName)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Consider only full expression not parts to have only one registered problem
|
// Consider only full expression not parts to have only one registered problem
|
||||||
if (PsiTreeUtil.getParentOfType(node, PyBinaryExpression.class, true, PyStatement.class) != null) return;
|
if (PsiTreeUtil.getParentOfType(node, PyBinaryExpression.class, true, PyStatement.class) != null) return;
|
||||||
|
|
||||||
final TypeEvalContext context = TypeEvalContext.codeAnalysis(node.getProject(), node.getContainingFile());
|
|
||||||
final Ref<PyType> refType = PyTypingTypeProvider.getType(node, context);
|
final Ref<PyType> refType = PyTypingTypeProvider.getType(node, context);
|
||||||
if (refType != null && refType.get() instanceof PyUnionType) {
|
if (refType != null && refType.get() instanceof PyUnionType) {
|
||||||
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON310),
|
registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON310),
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
class MetaA(type):
|
||||||
|
def __or__(self, other):
|
||||||
|
return 42
|
||||||
|
|
||||||
|
|
||||||
|
class A(metaclass=MetaA):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class B:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
print(A | B)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import types
|
||||||
|
|
||||||
|
|
||||||
|
class MetaA(type):
|
||||||
|
def __or__(self, other) -> types.Union:
|
||||||
|
return types.Union()
|
||||||
|
|
||||||
|
|
||||||
|
class A(metaclass=MetaA):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class B:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
print(A | B)
|
||||||
@@ -518,6 +518,16 @@ public class PythonHighlightingTest extends PyTestCase {
|
|||||||
doTest(LanguageLevel.PYTHON39, false, false);
|
doTest(LanguageLevel.PYTHON39, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PY-49697
|
||||||
|
public void testNoErrorMetaClassOverloadBitwiseOrOperator() {
|
||||||
|
doTest(LanguageLevel.PYTHON39, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PY-49697
|
||||||
|
public void testNoErrorMetaClassOverloadBitwiseOrOperatorReturnTypesUnion() {
|
||||||
|
doTest(LanguageLevel.PYTHON39, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static EditorColorsScheme createTemporaryColorScheme() {
|
private static EditorColorsScheme createTemporaryColorScheme() {
|
||||||
EditorColorsManager manager = EditorColorsManager.getInstance();
|
EditorColorsManager manager = EditorColorsManager.getInstance();
|
||||||
|
|||||||
Reference in New Issue
Block a user