mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-84469 Consider ClassVar when matching protocol and a concrete class
GitOrigin-RevId: 76af969cfe9318049f02dc7f6bdd03fe20a9504f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
044c140516
commit
f9b4104d74
@@ -38,6 +38,8 @@ public class PyCustomMember extends UserDataHolderBase {
|
||||
private final PsiElement myTarget;
|
||||
private PyPsiPath myPsiPath;
|
||||
|
||||
private boolean myIsClassVar = false;
|
||||
|
||||
boolean myFunction = false;
|
||||
|
||||
/**
|
||||
@@ -243,6 +245,16 @@ public class PyCustomMember extends UserDataHolderBase {
|
||||
return myFunction;
|
||||
}
|
||||
|
||||
|
||||
public PyCustomMember asClassVar() {
|
||||
myIsClassVar = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isClassVar() {
|
||||
return myIsClassVar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if some reference points to this element
|
||||
*
|
||||
|
||||
@@ -1101,6 +1101,8 @@ INSP.protocol.newtype.cannot.be.used.with.protocol.classes=NewType cannot be use
|
||||
INSP.protocol.element.type.incompatible.with.protocol=Type of ''{0}'' is incompatible with ''{1}''
|
||||
INSP.protocol.cannot.instantiate.protocol.class=Cannot instantiate protocol class ''{0}''
|
||||
INSP.protocol.element.type.not.writable=''{0}'' is writable in protocol ''{1}''
|
||||
INSP.protocol.element.type.not.classvar=Cannot override class variable from protocol ''{0}'' with instance variable
|
||||
INSP.protocol.element.type.not.instancevar=Cannot override instance variable from protocol ''{0}'' with class variable
|
||||
|
||||
# PyShadowingBuiltinsInspection
|
||||
INSP.NAME.shadowing.builtins=Shadowing built-in names
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public final class PyDataclassClassMembersProvider extends PyClassMembersProvide
|
||||
if (hasAttrs) {
|
||||
PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(pyClass);
|
||||
PyClass objectClass = builtinCache.getClass(PyNames.OBJECT);
|
||||
result.add(new PyCustomMember("__attrs_attrs__", objectClass));
|
||||
result.add(new PyCustomMember("__attrs_attrs__", objectClass).asClassVar());
|
||||
}
|
||||
|
||||
return CachedValueProvider.Result.create(result, PsiModificationTracker.MODIFICATION_COUNT);
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.jetbrains.python.codeInsight.PyCustomMember;
|
||||
import com.jetbrains.python.codeInsight.PyCustomMemberUtils;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
|
||||
@@ -607,7 +608,12 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
|
||||
type = resolveContext.getTypeEvalContext().getType(typedElement);
|
||||
}
|
||||
|
||||
result.add(new PyTypeMember(element, type));
|
||||
boolean isClassVar = false;
|
||||
if (element instanceof PyAnnotationOwner && element instanceof PyTypeCommentOwner) {
|
||||
isClassVar =
|
||||
PyTypingTypeProvider.isClassVar((PyAnnotationOwner & PyTypeCommentOwner)element, resolveContext.getTypeEvalContext());
|
||||
}
|
||||
result.add(new PyTypeMember(element, type, isClassVar));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -689,12 +695,16 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
|
||||
|
||||
return ContainerUtil.map(results, result -> {
|
||||
PsiElement element = result.getElement();
|
||||
boolean isClassVar = false;
|
||||
if (element instanceof PyAnnotationOwner && element instanceof PyTypeCommentOwner) {
|
||||
isClassVar = PyTypingTypeProvider.isClassVar((PyAnnotationOwner & PyTypeCommentOwner)element, context.getTypeEvalContext());
|
||||
}
|
||||
if (element instanceof PyTypedElement typedElement) {
|
||||
return new PyTypeMember(typedElement,
|
||||
context.getTypeEvalContext().getType(typedElement), typedElement, typedElement, typedElement);
|
||||
context.getTypeEvalContext().getType(typedElement), isClassVar);
|
||||
}
|
||||
else {
|
||||
return new PyTypeMember(element, null, element, element, element);
|
||||
return new PyTypeMember(element, null, isClassVar);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -596,6 +596,12 @@ public final class PyTypeChecker {
|
||||
if (protocolMember.isDeletable() && !subclassElementMember.isDeletable()) {
|
||||
return false;
|
||||
}
|
||||
boolean isProtocolMemberClassVar = protocolMember.isClassVar();
|
||||
boolean isSubclassMemberClassVar = subclassElementMember.isClassVar();
|
||||
if (isSubclassMemberClassVar != isProtocolMemberClassVar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PyType subclassElementType = dropSelfIfNeeded(actual, subclassElementMember.getType(), matchContext.context);
|
||||
subclassElementType = substitute(subclassElementType, substitutions, matchContext.context);
|
||||
boolean matched = match(protocolElementType, subclassElementType, protocolContext).orElse(true);
|
||||
|
||||
+499
-450
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user