The with statement block is needed to define *when* cleanup happens (unconditionally at the end of the block).
The "iterwith" generator is currently pointless, as it results in nondeterministic cleanup of the context manager, so you may as well not bother and just rely on the underlying iterable's nondeterministic cleanup.
We're never going to add cleanup semantics directly to for loops because:
- separation of concerns is a good design principle
- Indentation levels are not a limited resource (anyone that thinks they are may be forgetting that factoring out context managers, iterators and subfunctions gives you more of them, and that judicious use of early returns and continue statements can avoid wasting them)
- we already considered it when initially designing the with statement and decided it was a bad idea.
I forget where that last part is written up. If it's not in PEP 343, 342, 346 or 340 (the full set of PEPs that led to the current with statement and contextlib.contextmanager designs), it should be in one of the threads they reference.