Optional<Boolean> (@NotNull PyCallableType expected, @NotNull PyCallableType actual, @NotNull MatchContext matchContext) { if (actual instanceof PyFunctionType && expected instanceof PyClassType && FUNCTION.equals(expected.getName()) && expected.equals(PyBuiltinCache.getInstance(actual.getCallable()).getObjectType(FUNCTION))) { return Optional.of(true); } final TypeEvalContext context = matchContext.context; if (expected instanceof PyClassLikeType && !isCallableProtocol((PyClassLikeType)expected, context)) { return PyTypingTypeProvider.CALLABLE.equals(((PyClassLikeType)expected).getClassQName()) ? Optional.of(actual.isCallable()) : Optional.empty(); } if (expected.isCallable() && actual.isCallable()) { final List<PyCallableParameter> expectedParameters = expected.getParameters(context); final List<PyCallableParameter> actualParameters = actual.getParameters(context); if (expectedParameters != null && actualParameters != null) { if (!matchCallableParameters(expectedParameters, actualParameters, matchContext)) { return Optional.of(false); } } if (!match(expected.getReturnType(context), getActualReturnType(actual, context), matchContext).orElse(true)) { return Optional.of(false); } return Optional.of(true); } return Optional.empty(); }