CallTypeKind (@Nullable PyExpression callee) { if (callee instanceof PyReferenceExpression expression) { QualifiedName qName = expression.asQualifiedName(); if (qName == null) { return null; } ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(expression); // Flow-insensitive context is required to prevent recursive control flow access during the resolve process TypeEvalContext context = TypeEvalContext.codeInsightFallback(callee.getProject()); while (scopeOwner != null) { final var result = StreamEx .of(PyResolveUtil.resolveQualifiedNameInScope(qName, scopeOwner, context)) .select(PyFunction.class) .map(function -> { if (PyTypingTypeProvider.isNoReturn(function, context)) { return NoReturnCallKind.INSTANCE; } if (PyTypingTypeProvider.isTypeGuard(function, context)) { return new TypeGuardCallKind(function); } return null; }).findFirst( it -> it != null); if (result.isPresent()) return result.get(); scopeOwner = ScopeUtil.getScopeOwner(scopeOwner); } } return null; }