boolean (@Nullable PyCallable resolved, @NotNull PyExpression qualifier, @NotNull TypeEvalContext context) { final PyType qualifierType = context.getType(qualifier); if (qualifierType instanceof PyClassType qualifierClassType) { return qualifierClassType.isDefinition() && belongsToSpecifiedClassHierarchy(resolved, qualifierClassType.getPyClass(), context); } else if (qualifierType instanceof PyClassLikeType) { return ((PyClassLikeType)qualifierType).isDefinition(); // Any definition means callable is classmethod } else if (qualifierType instanceof PyUnionType) { final Collection<PyType> members = ((PyUnionType)qualifierType).getMembers(); if (ContainerUtil.all(members, type -> type == null || type instanceof PyNoneType || type instanceof PyClassType)) { return StreamEx .of(members) .select(PyClassType.class) .filter(type -> belongsToSpecifiedClassHierarchy(resolved, type.getPyClass(), context)) .allMatch(PyClassType::isDefinition); } } return false; }