@Nullable
  public static PyType getIterationType(@Nullable PyType iterableType, @Nullable PyExpression source, @NotNull PsiElement anchor,
                                        @NotNull TypeEvalContext context) {
    if (iterableType instanceof PyTupleType tupleType) {
      return tupleType.getIteratedItemType();
    }
    else if (iterableType instanceof PyUnionType) {
      return ((PyUnionType)iterableType).map(member -> getIterationType(member, source, anchor, context));
    }
    else if (iterableType != null && PyABCUtil.isSubtype(iterableType, PyNames.ITERABLE, context)) {
      final PyFunction iterateMethod = findMethodByName(iterableType, PyNames.ITER, context);
      if (iterateMethod != null) {
        final PyType iterateReturnType = getContextSensitiveType(iterateMethod, context, source);
        return getIteratedItemType(iterateReturnType, source, anchor, context, false);
      }
      final Ref<PyType> nextMethodCallType = getNextMethodCallType(iterableType, source, anchor, context, false);
      if (nextMethodCallType != null) {
        return nextMethodCallType.get();
      }
      final PyFunction getItem = findMethodByName(iterableType, PyNames.GETITEM, context);
      if (getItem != null) {
        return getContextSensitiveType(getItem, context, source);
      }
    }
    else if (iterableType != null && PyABCUtil.isSubtype(iterableType, PyNames.ASYNC_ITERABLE, context)) {
      final PyFunction iterateMethod = findMethodByName(iterableType, PyNames.AITER, context);
      if (iterateMethod != null) {
        final PyType iterateReturnType = getContextSensitiveType(iterateMethod, context, source);
        return getIteratedItemType(iterateReturnType, source, anchor, context, true);
      }
    }
    return null;
  }
@Nullable
  public static PyType getIterationType(@Nullable PyType iterableType, @Nullable PyExpression source, @NotNull PsiElement anchor,
                                        @NotNull TypeEvalContext context)