PyType (@Nullable PyType type, boolean transformToDefinition, @NotNull TypeEvalContext context, @Nullable PyExpression typeElement) { if (type instanceof PyTupleType tupleType) { final List<PyType> members = new ArrayList<>(); final int count = tupleType.getElementCount(); final PyTupleExpression tupleExpression = PyUtil .as(PyPsiUtils.flattenParens(PyUtil.as(typeElement, PyParenthesizedExpression.class)), PyTupleExpression.class); if (tupleExpression != null && tupleExpression.getElements().length == count) { final PyExpression[] elements = tupleExpression.getElements(); for (int i = 0; i < count; i++) { members.add(transformTypeFromAssertion(tupleType.getElementType(i), transformToDefinition, context, elements[i])); } } else { for (int i = 0; i < count; i++) { members.add(transformTypeFromAssertion(tupleType.getElementType(i), transformToDefinition, context, null)); } } return PyUnionType.union(members); } else if (type instanceof PyUnionType) { return ((PyUnionType)type).map(member -> transformTypeFromAssertion(member, transformToDefinition, context, null)); } else if (type instanceof PyClassType && "types.UnionType".equals(((PyClassType)type).getClassQName()) && typeElement != null) { final Ref<PyType> typeFromTypingProvider = PyTypingTypeProvider.getType(typeElement, context); if (typeFromTypingProvider != null) { return transformTypeFromAssertion(typeFromTypingProvider.get(), transformToDefinition, context, null); } } else if (type instanceof PyInstantiableType instantiableType) { return transformToDefinition ? instantiableType.toClass() : instantiableType.toInstance(); } return type; }