private static @Nullable PyCallableType toCallableType(@NotNull PyCallSiteExpression callSite,
                                                         @NotNull ClarifiedResolveResult resolveResult,
                                                         @NotNull TypeEvalContext context) {
    final PsiElement clarifiedResolved = resolveResult.myClarifiedResolved;
    if (!(clarifiedResolved instanceof PyTypedElement)) return null;

    final PyCallableType callableType = PyUtil.as(context.getType((PyTypedElement)clarifiedResolved), PyCallableType.class);
    if (callableType == null) return null;

    if (clarifiedResolved instanceof PyCallable callable) {

      final PyFunction.Modifier originalModifier = callable instanceof PyFunction ? ((PyFunction)callable).getModifier() : null;
      final PyFunction.Modifier resolvedModifier = ObjectUtils.chooseNotNull(originalModifier, resolveResult.myWrappedModifier);

      final boolean isConstructorCall = resolveResult.myIsConstructor;
      final List<PyExpression> qualifiers = resolveResult.myOriginalResolveResult.getQualifiers();

      final boolean isByInstance = isConstructorCall
                                   || isQualifiedByInstance(callable, qualifiers, context)
                                   || callable instanceof PyBoundFunction;

      final PyExpression lastQualifier = ContainerUtil.getLastItem(qualifiers);
      final boolean isByClass = lastQualifier != null && isQualifiedByClass(callable, lastQualifier, context);

      final int resolvedImplicitOffset =
        getImplicitArgumentCount(callable, resolvedModifier, isConstructorCall, isByInstance, isByClass);

      final PyType clarifiedConstructorCallType =
        PyUtil.isInitOrNewMethod(clarifiedResolved) ? clarifyConstructorCallType(resolveResult, callSite, context) : null;

      if (callableType.getModifier() == resolvedModifier &&
          callableType.getImplicitOffset() == resolvedImplicitOffset &&
          clarifiedConstructorCallType == null) {
        return callableType;
      }

      return new PyCallableTypeImpl(
        callableType.getParameters(context),
        ObjectUtils.chooseNotNull(clarifiedConstructorCallType, callableType.getCallType(context, callSite)),
        callable,
        resolvedModifier,
        Math.max(0, resolvedImplicitOffset)); // wrong source can trigger strange behaviour
    }

    return callableType;
  }
private static @Nullable PyCallableType toCallableType(@NotNull PyCallSiteExpression callSite,
                                                         @NotNull ClarifiedResolveResult resolveResult,
                                                         @NotNull TypeEvalContext context)