Find the highest number satisfying a condition in an infinite range
if/else inside the loop doesn't look clean. Consider splitting the code into two parts:

    # Find the "good" range

    while condition(hi):
        lo, hi = hi, hi * 2

    # At this point it is known that condition(lo) is True,
    # and condition(hi) is False. A normal bisection search
    # follows.

   return binary_search(lo, hi, condition)


It would be also worthy to factor the setup loop out in its own function.