diff --git a/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeVarType.java b/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeVarType.java
index ba6d6ad6d7b8..d89c276647ff 100644
--- a/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeVarType.java
+++ b/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeVarType.java
@@ -34,4 +34,10 @@ public interface PyTypeVarType extends PyTypeParameterType, PyInstantiableType
{
return new PyParamSpecType(name)
@@ -1543,6 +1545,25 @@ public final class PyTypingTypeProvider extends PyTypeProviderWithCustomContext<
return null;
}
+ private static @NotNull PyTypeVarType.Variance getTypeVarVarianceFromDeclaration(@NotNull PyCallExpression assignedCall) {
+ boolean covariant = PyEvaluator.evaluateAsBooleanNoResolve(assignedCall.getKeywordArgument("covariant"), false);
+ boolean contravariant = PyEvaluator.evaluateAsBooleanNoResolve(assignedCall.getKeywordArgument("contravariant"), false);
+ boolean inferVariance = PyEvaluator.evaluateAsBooleanNoResolve(assignedCall.getKeywordArgument("infer_variance"), false);
+
+ if (covariant && !contravariant) {
+ return PyTypeVarType.Variance.COVARIANT;
+ }
+ else if (contravariant && !covariant) {
+ return PyTypeVarType.Variance.CONTRAVARIANT;
+ }
+ else if (inferVariance) {
+ return PyTypeVarType.Variance.INFER_VARIANCE;
+ }
+ else {
+ return PyTypeVarType.Variance.INVARIANT;
+ }
+ }
+
@ApiStatus.Internal
public static @Nullable PyAstTypeParameter.Kind getTypeParameterKindFromDeclaration(@NotNull PyCallExpression callExpression,
@NotNull TypeEvalContext context) {
@@ -1600,7 +1621,7 @@ public final class PyTypingTypeProvider extends PyTypeProviderWithCustomContext<
else if (boundExpression != null) {
boundType = Ref.deref(getTypePreventingRecursion(boundExpression, context));
}
- return new PyTypeVarTypeImpl(name, constraints, boundType, defaultType)
+ return new PyTypeVarTypeImpl(name, constraints, boundType, defaultType, PyTypeVarType.Variance.INFER_VARIANCE)
.withScopeOwner(scopeOwner)
.withDeclarationElement(declarationElement);
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java
index 8078d6c61396..a7a9c5593f86 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java
@@ -27,6 +27,7 @@ public class PyGenericType implements PyTypeVarType {
private final @NotNull List<@Nullable PyType> myConstraints;
private final @Nullable PyType myBound;
private final @Nullable Ref myDefaultType;
+ private final @NotNull Variance myVariance;
private final boolean myIsDefinition;
private final @Nullable PyQualifiedNameOwner myDeclarationElement;
private final @Nullable PyQualifiedNameOwner myScopeOwner;
@@ -34,14 +35,16 @@ public class PyGenericType implements PyTypeVarType {
public PyGenericType(@NotNull String name,
@NotNull List<@Nullable PyType> constraints,
@Nullable PyType bound,
- @Nullable Ref defaultType) {
- this(name, constraints, bound, defaultType, false, null, null);
+ @Nullable Ref defaultType,
+ @NotNull Variance variance) {
+ this(name, constraints, bound, defaultType, variance, false, null, null);
}
protected PyGenericType(@NotNull String name,
@NotNull List<@Nullable PyType> constraints,
@Nullable PyType bound,
@Nullable Ref defaultType,
+ @NotNull Variance variance,
boolean isDefinition,
@Nullable PyQualifiedNameOwner declarationElement,
@Nullable PyQualifiedNameOwner scopeOwner) {
@@ -49,6 +52,7 @@ public class PyGenericType implements PyTypeVarType {
myConstraints = constraints;
myBound = bound;
myDefaultType = defaultType;
+ myVariance = variance;
myIsDefinition = isDefinition;
myDeclarationElement = declarationElement;
myScopeOwner = scopeOwner;
@@ -156,6 +160,11 @@ public class PyGenericType implements PyTypeVarType {
return myBound;
}
+ @Override
+ public @NotNull Variance getVariance() {
+ return myVariance;
+ }
+
@Override
public @Nullable Ref getDefaultType() {
return myDefaultType;
@@ -172,7 +181,7 @@ public class PyGenericType implements PyTypeVarType {
}
public @NotNull PyGenericType withScopeOwner(@Nullable PyQualifiedNameOwner scopeOwner) {
- return new PyTypeVarTypeImpl(getName(), getConstraints(), getBound(), getDefaultType(), isDefinition(), getDeclarationElement(), scopeOwner);
+ return new PyTypeVarTypeImpl(getName(), getConstraints(), getBound(), getDefaultType(), getVariance(), isDefinition(), getDeclarationElement(), scopeOwner);
}
public @NotNull PyGenericType withTargetExpression(@Nullable PyTargetExpression targetExpression) {
@@ -180,16 +189,16 @@ public class PyGenericType implements PyTypeVarType {
}
public @NotNull PyGenericType withDeclarationElement(@Nullable PyQualifiedNameOwner declarationElement) {
- return new PyTypeVarTypeImpl(getName(), getConstraints(), getBound(), getDefaultType(), isDefinition(), declarationElement, getScopeOwner());
+ return new PyTypeVarTypeImpl(getName(), getConstraints(), getBound(), getDefaultType(), getVariance(), isDefinition(), declarationElement, getScopeOwner());
}
@Override
public @NotNull PyGenericType toInstance() {
- return myIsDefinition ? new PyTypeVarTypeImpl(myName, myConstraints, myBound, myDefaultType, false, myDeclarationElement, myScopeOwner) : this;
+ return myIsDefinition ? new PyTypeVarTypeImpl(myName, myConstraints, myBound, myDefaultType, myVariance, false, myDeclarationElement, myScopeOwner) : this;
}
@Override
public @NotNull PyGenericType toClass() {
- return myIsDefinition ? this : new PyTypeVarTypeImpl(myName, myConstraints, myBound, myDefaultType, true, myDeclarationElement, myScopeOwner);
+ return myIsDefinition ? this : new PyTypeVarTypeImpl(myName, myConstraints, myBound, myDefaultType, myVariance, true, myDeclarationElement, myScopeOwner);
}
}
diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java
index cdd09fbe1601..68bf05c9cd30 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java
@@ -9,24 +9,26 @@ import java.util.List;
public final class PyTypeVarTypeImpl extends PyGenericType {
public PyTypeVarTypeImpl(@NotNull String name, @Nullable PyType bound) {
- this(name, List.of(), bound, null);
+ this(name, List.of(), bound, null, Variance.INVARIANT);
}
public PyTypeVarTypeImpl(@NotNull String name,
@NotNull List<@Nullable PyType> constraints,
@Nullable PyType bound,
- @Nullable Ref defaultType) {
- super(name, constraints, bound, defaultType);
+ @Nullable Ref defaultType,
+ @NotNull Variance variance) {
+ super(name, constraints, bound, defaultType, variance);
}
PyTypeVarTypeImpl(@NotNull String name,
@NotNull List<@Nullable PyType> constraints,
@Nullable PyType bound,
@Nullable Ref defaultType,
+ @NotNull Variance variance,
boolean isDefinition,
@Nullable PyQualifiedNameOwner declarationElement,
@Nullable PyQualifiedNameOwner scopeOwner) {
- super(name, constraints, bound, defaultType, isDefinition, declarationElement, scopeOwner);
+ super(name, constraints, bound, defaultType, variance, isDefinition, declarationElement, scopeOwner);
}
@Override