PY-49935 Fix back compatibility for substitution in PyTypeChecker

Fix the problem happened with com.koxudaxi.pydantic:0.3.4 plugin using old version of PyTypeChecker API (substitue and unifyReceiver methods used Map instead of GenericSubstitutions)

(cherry picked from commit 866187f2a9cc0a4d169922df77426d93a91003eb)

IJ-MR-13344

GitOrigin-RevId: 4cadda7469802e0cf38621df9e48712f590cf623
This commit is contained in:
andrey.matveev
2021-08-24 18:31:14 +07:00
committed by intellij-monorepo-bot
parent 62207cf93f
commit b4cf36fb95
6 changed files with 44 additions and 10 deletions

View File

@@ -219,7 +219,7 @@ public class PyTypeCheckerInspection extends PyInspection {
final List<AnalyzeArgumentResult> result = new ArrayList<>();
final var receiver = callSite.getReceiver(callableType.getCallable());
final var substitutions = PyTypeChecker.unifyReceiver(receiver, myTypeEvalContext);
final var substitutions = PyTypeChecker.unifyReceiverWithParamSpecs(receiver, myTypeEvalContext);
final var mappedParameters = mapping.getMappedParameters();
final var regularMappedParameters = getRegularMappedParameters(mappedParameters);

View File

@@ -1209,7 +1209,7 @@ public final class PyCallExpressionHelper {
}
allMappedParameters.putAll(mappedExplicitParameters);
return PyTypeChecker.unifyGenericCall(receiver, allMappedParameters, context) == null;
return PyTypeChecker.unifyGenericCallWithParamSpecs(receiver, allMappedParameters, context) == null;
}
private static class ArgumentMappingResults {

View File

@@ -271,7 +271,7 @@ public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements
@NotNull Map<PyExpression, PyCallableParameter> parameters,
@NotNull TypeEvalContext context) {
if (PyTypeChecker.hasGenerics(type, context)) {
final var substitutions = PyTypeChecker.unifyGenericCall(receiver, parameters, context);
final var substitutions = PyTypeChecker.unifyGenericCallWithParamSpecs(receiver, parameters, context);
if (substitutions != null) {
final var substitutionsWithUnresolvedReturnGenerics =
PyTypeChecker.getSubstitutionsWithUnresolvedReturnGenerics(getParameters(context), type, substitutions, context);

View File

@@ -405,7 +405,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
boolean possiblyParameterizedQualifier = !(qualifierType instanceof PyModuleType || qualifierType instanceof PyImportedModuleType);
if (possiblyParameterizedQualifier && PyTypeChecker.hasGenerics(type, context)) {
final var substitutions =
PyTypeChecker.unifyGenericCall(qualifier, Collections.emptyMap(), context);
PyTypeChecker.unifyGenericCallWithParamSpecs(qualifier, Collections.emptyMap(), context);
if (substitutions != null) {
final PyType substituted = PyTypeChecker.substitute(type, substitutions, context);
if (substituted != null) {

View File

@@ -67,7 +67,7 @@ public class PyCallableTypeImpl implements PyCallableType {
@NotNull Collection<PyCallableParameter> allParameters,
@Nullable PyExpression receiver,
@NotNull TypeEvalContext context) {
final var substitutions = PyTypeChecker.unifyGenericCall(receiver, actualParameters, context);
final var substitutions = PyTypeChecker.unifyGenericCallWithParamSpecs(receiver, actualParameters, context);
final var substitutionsWithUnresolvedReturnGenerics =
PyTypeChecker.getSubstitutionsWithUnresolvedReturnGenerics(allParameters, type, substitutions, context);
return PyTypeChecker.substitute(type, substitutionsWithUnresolvedReturnGenerics, context);

View File

@@ -810,6 +810,17 @@ public final class PyTypeChecker {
}
}
/**
* @deprecated use {@link PyTypeChecker#substitute(PyType, GenericSubstitutions, TypeEvalContext)} instead
*/
@Deprecated
@Nullable
public static PyType substitute(@Nullable PyType type, @NotNull Map<PyGenericType, PyType> substitutions,
@NotNull TypeEvalContext context) {
final var genericSubstitutions = new GenericSubstitutions(substitutions, new LinkedHashMap<>());
return substitute(type, genericSubstitutions, context);
}
@Nullable
public static PyType substitute(@Nullable PyType type,
@NotNull GenericSubstitutions substitutions,
@@ -906,11 +917,24 @@ public final class PyTypeChecker {
return type;
}
/**
* @deprecated use {@link PyTypeChecker#unifyGenericCallWithParamSpecs(PyExpression, Map, TypeEvalContext)} instead
*/
@Deprecated
@Nullable
public static GenericSubstitutions unifyGenericCall(@Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyCallableParameter> arguments,
@NotNull TypeEvalContext context) {
final var substitutions = unifyReceiver(receiver, context);
public static Map<PyGenericType, PyType> unifyGenericCall(@Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyCallableParameter> arguments,
@NotNull TypeEvalContext context) {
final var result = unifyGenericCallWithParamSpecs(receiver, arguments, context);
if (result == null) return null;
return result.typeVars;
}
@Nullable
public static GenericSubstitutions unifyGenericCallWithParamSpecs(@Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyCallableParameter> arguments,
@NotNull TypeEvalContext context) {
final var substitutions = unifyReceiverWithParamSpecs(receiver, context);
for (Map.Entry<PyExpression, PyCallableParameter> entry : getRegularMappedParameters(arguments).entrySet()) {
final PyCallableParameter paramWrapper = entry.getValue();
final PyType expectedType = paramWrapper.getArgumentType(context);
@@ -961,7 +985,17 @@ public final class PyTypeChecker {
return match(container.getArgumentType(context), PyUnionType.union(types), context, substitutions);
}
public static GenericSubstitutions unifyReceiver(@Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
/**
* @deprecated use {@link PyTypeChecker#unifyReceiverWithParamSpecs(PyExpression, TypeEvalContext)} instead
*/
@Deprecated
@NotNull
public static Map<PyGenericType, PyType> unifyReceiver(@Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
return unifyReceiverWithParamSpecs(receiver, context).typeVars;
}
@NotNull
public static GenericSubstitutions unifyReceiverWithParamSpecs(@Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
// Collect generic params of object type
final var substitutions = new GenericSubstitutions();
final PyType qualifierType = receiver != null ? context.getType(receiver) : null;