Because of that missing runtime for scheduling and evaluating IO-ful things, tools like superfunctions are necessary.
In other words: IO monads are only as useful as the thing that evaluates them; Python doesn't have a built-in way to do that, so people have to make code that looks "upward" to determine what kind of IO behavior (blocking/nonblocking/concurrent/lazy/etc.) is needed.