@Nullable
  @Override
  public Ref<PyType> getReferenceType(@NotNull PsiElement referenceTarget, @NotNull TypeEvalContext context, @Nullable PsiElement anchor) {
    if (!(referenceTarget instanceof PyDecoratable pyDecoratable)) {
      return null;
    }
    PyDecoratorList decoratorList = pyDecoratable.getDecoratorList();
    if (decoratorList == null) {
      return null;
    }

    List<PyDecorator> decorators = ContainerUtil.filter(decoratorList.getDecorators(), d -> !isTransparentDecorator(d, context));
    if (decorators.isEmpty()) {
      return null;
    }

    /* Our goal is to infer the type of reference of decorated object.
     * For that we going to infer a type of expression <code>decorator(reference)<code>.
     * The expression contains a new reference for the same object, and our
     * type inferring engine will ask this provider about the type of the object again.
     * To prevent an infinite loop, we need to add a recursion guard here. */
    return RecursionManager.doPreventingRecursion(
      Pair.create(referenceTarget, context),
      false,
      () -> evaluateType(pyDecoratable, context, decorators)
    );
  }
@Nullable
  @Override
  public Ref<PyType> getReferenceType(@NotNull PsiElement referenceTarget, @NotNull TypeEvalContext context, @Nullable PsiElement anchor)