Thanks Nick. I definitely see your point about iterwith(); have been thinking about that since someone asked where __exit__() would be invoked.
I meant the following as a more compact way of expressing
for line in file with open(path) as file: process(line)
As a more compact way of expressing
with open(path) as file: for line in file: process(line)
Not a change to the semantics of for-loops; a point my iterwith() function has confuses greatly, I realize now. I'm not seeing a loss of separation of concerns there.
Indentation levels aren't limited, but flatter is better ;-)
I saw a bunch of back and forth regarding iteration and context management in the PEP, but didn't notice anything along these lines in particular . I'll have to go back and take a closer look.
Nick Coghlan wrote:
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.