[Tutor] Yielding from a with block

Steven D'Aprano steve at pearwood.info
Fri May 29 15:29:05 CEST 2015


On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote:

> Even if you limit yourself to CPython there is another effect: the order of 
> execution may not meet one's expectations/requirements:

[snip example]

That's an interesting example, and I can't tell if that's a 
problem with your (and my) expectations, or a bug in the context 
manager implementation.

PEP 343 clearly warns that the finally clause may not run immediately:

    Note that we're not guaranteeing that the finally-clause is
    executed immediately after the generator object becomes unused

https://www.python.org/dev/peps/pep-0343/

but the documentation for the with-statement suggests strongly that the 
__exit__ method will run immediately after the block is exited, before 
any additional code (including before any exception is raised. E.g.:

    5. The suite is executed.

    6. The context manager’s __exit__() method is invoked. If an 
       exception caused the suite to be exited, its type, value, and 
       traceback are passed as arguments to __exit__(). Otherwise, 
       three None arguments are supplied.

https://docs.python.org/2/reference/compound_stmts.html#the-with-statement



> PS: I'm still looking for a fairly elegant rewrite of the problematic
> 
> def lines(files):
>     for file in files:
>         with open(files) as f:
>             yield from f
> 
> (see Oscar's comment in 
> <https://mail.python.org/pipermail/tutor/2015-May/105448.html>)

Oscar's comment includes a syntax error, which makes it hard to run his 
code:

        print("__exit__ called")__del__.

I can't even begin to guess what that is supposed to be, and reading the 
next few messages in the thread doesn't enlighten.


-- 
Steve


More information about the Tutor mailing list