But you were probably calling run_until_complete() without an explicit timeout. In that case, it should not call run() but run_forever(), and it should never raise TimeoutError.
Right, this was actually the case. I'll submit a code review addressing this.
You could still get a TimeoutError if a timeout was given; in that case, I think you can fix this case by passing call_later() a helper function that sets a nonlocal variable which you then inspect.
Sure, but then what should we do: return like nothing has happened or raise an exception so that the caller knows that the future is not complete?
You could also use a different mechanism, e.g. call cancel() on a Future when the timeout occurs. (But I think that might be less reliable, since I think Tasks can catch cancellations.)
Yeah, that would not work, in my example the task is already started, I don't think cancel() will work midway.