So the renderer changes based on the environment, but provides the same API for all? That is convenient for the end-users and I think it will work well if you can get consistent results across environments. Trying achieve that same standard for a 3D renderer would a serious undertaking. I am currently building a new 3D renderer right now, and I can tell you getting it to work in just one place is a lot of work!
That’s a good compromise. py5’s run_sketch() method also has a sketch_functions parameter, letting you pass a dictionary of functions. I thought there would be times py5’s scheme of inspecting the call stack wouldn’t work quite right and wanted to provide an alternative, but in actual practice, the sketch_functions parameter is rarely necessary.