@Override
  public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
    if (PyNames.ALL.equals(getName())) {
      // no type for __all__, to avoid unresolved reference errors for expressions where a qualifier is a name
      // imported via __all__
      return null;
    }
    final Ref<PyType> pyType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(this, context, null);
    if (pyType != null) {
      return pyType.get();
    }
    PyType type = getTypeFromDocString();
    if (type != null) {
      return type;
    }
    if (!context.maySwitchToAST(this)) {
      final PyResolveContext resolveContext = PyResolveContext.defaultContext(context);

      final List<PyType> types = StreamEx
        .of(multiResolveAssignedValue(resolveContext))
        .select(PyTypedElement.class)
        .map(context::getType)
        .toList();

      return PyUnionType.union(types);
    }
    type = getTypeFromComment(this);
    if (type != null) {
      return type;
    }
    final PsiElement parent = PsiTreeUtil.skipParentsOfType(this, PyParenthesizedExpression.class);
    if (parent instanceof PyAssignmentStatement assignmentStatement) {
      PyExpression assignedValue = assignmentStatement.getAssignedValue();
      if (assignedValue instanceof PyParenthesizedExpression) {
        assignedValue = ((PyParenthesizedExpression)assignedValue).getContainedExpression();
      }
      if (assignedValue != null) {
        if (assignedValue instanceof PyYieldExpression assignedYield) {
          return assignedYield.isDelegating() ? context.getType(assignedValue) : null;
        }
        return context.getType(assignedValue);
      }
    }
    if (parent instanceof PyTupleExpression || parent instanceof PyListLiteralExpression) {
      PsiElement nextParent =
        PsiTreeUtil.skipParentsOfType(parent, PyParenthesizedExpression.class, PyTupleExpression.class, PyListLiteralExpression.class);
      if (nextParent instanceof PyAssignmentStatement assignment) {
        final PyExpression value = assignment.getAssignedValue();
        final PyExpression lhs = assignment.getLeftHandSideExpression();
        final PySequenceExpression targetTupleOrList = PsiTreeUtil.findChildOfType(lhs, PySequenceExpression.class, false);
        if (value != null && (targetTupleOrList instanceof PyTupleExpression || targetTupleOrList instanceof PyListLiteralExpression)) {
          final PyType positionalItemType = getTargetTypeFromIterableUnpacking(targetTupleOrList, value, context);
          if (positionalItemType != null) {
            return positionalItemType;
          }
        }
      }
    }
    if (parent instanceof PyWithItem) {
      return getWithItemVariableType((PyWithItem)parent, context);
    }
    if (parent instanceof PyAssignmentExpression) {
      final PyExpression assignedValue = ((PyAssignmentExpression)parent).getAssignedValue();
      return assignedValue == null ? null : context.getType(assignedValue);
    }
    if (parent instanceof PyGlobalStatement || parent instanceof PyNonlocalStatement) {
      PyResolveContext resolveContext = PyResolveContext.defaultContext(context);
      List<PyType> collect = StreamEx.of(getReference(resolveContext).multiResolve(false))
        .map(ResolveResult::getElement)
        .select(PyTypedElement.class)
        .map(context::getType)
        .toList();

      return PyUnionType.union(collect);
    }
    if (parent instanceof PyExceptPart && ((PyExceptPart)parent).isStar() &&
        LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON311)) {
      return PyClassTypeImpl.createTypeByQName(this, "ExceptionGroup", false);
    }
    PyType iterType = getTypeFromIteration(context);
    if (iterType != null) {
      return iterType;
    }
    PyType excType = getTypeFromExcept();
    if (excType != null) {
      return excType;
    }
    return null;
  }
@Override
  public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key)