In hindsight all this seems really obvious. If the mainloop is dumb, ignore it and use your own. One reason it took so long for me to figure this out was my heavy use of Tkinter. Tkinter's mainloop is not written in Python and can not be ignored or replaced. There is no
loop_once() for you to hack with. But I am fond of Tk's canvas (though I wish it could do AA and transparency) and really wanted to make a simple physics game in it. Most mailing list archives will say "Can't do that, use PyGame." But PyGame is overkill and there is a hidden gem in the canvas docs:
canvas.after(). Properly misused, it lets you tuck a second mainloop inside Tkinter's invariable loop. Use is simple: provide
after() with a number of milliseconds and a function to call. What is interesting is that the implementation is properly tail recursive. A function can call itself forever. Once again, lots of missing boilerplate but hopefully the point is made.