PyType (@NotNull PyType genericType, @NotNull List<PyType> actualTypeParams, @NotNull TypeEvalContext context) { Generics typeParams = collectGenerics(genericType, context); if (!typeParams.isEmpty()) { var substitutions = new GenericSubstitutions(); List<PyType> expectedTypeParams = new ArrayList<>(new LinkedHashSet<>(typeParams.getAllTypeParameters())); PyTypeParameterMapping mapping = PyTypeParameterMapping.mapByShape(expectedTypeParams, actualTypeParams, Option.MAP_UNMATCHED_EXPECTED_TYPES_TO_ANY); if (mapping != null) { for (Couple<PyType> pair : mapping.getMappedTypes()) { if (pair.getFirst() instanceof PyTypeVarType typeVar) { substitutions.typeVars.put((PyGenericType)typeVar, pair.getSecond()); } else if (pair.getFirst() instanceof PyTypeVarTupleType typeVarTuple) { assert pair.getSecond() instanceof PyVariadicType; substitutions.typeVarTuples.put(typeVarTuple, (PyVariadicType)pair.getSecond()); } } } return substitute(genericType, substitutions, context); } // An already parameterized type, don't override existing values for type parameters else if (genericType instanceof PyCollectionType) { return genericType; } else if (genericType instanceof PyClassType) { PyClass cls = ((PyClassType)genericType).getPyClass(); return new PyCollectionTypeImpl(cls, false, actualTypeParams); } else { return null; } }