[Python-ideas] Is this PEP-able? "with" statement inside genexps / list comprehensions

Oscar Benjamin oscar.j.benjamin at gmail.com
Mon Jul 30 17:26:39 EDT 2018


On 30 July 2018 at 20:15, Rudy Matela <rudy at matela.com.br> wrote:
> Hello,

Hi Rudy,

> Do you think it would be nice to allow with statements inside genexps or
> list comprehensions?  The functions __enter__ and __exit__ would be
> automatically called as iterables are traversed.  I am thinking of
> drafting a PEP about this.  Examples:
>
>
> This
>
>         g = (f.read() for fn in filenames with open(fn) as f)
>
> would be equivalent to the following use of a generator function:
>
>         def __gen():
>                 for fn in filenames:
>                         with open(fn) as f:
>                                 yield f.read()
>         g = __gen()

Yielding from a with block should be discouraged rather than given
special syntax. There is essentially a contradiction between the
meaning/purpose of yield (suspend indefinitely) and with (definitely
call __exit__).

If I partially iterate over g as in

    for line in g:
        break

then at this point g is suspended and f.__exit__ has not been called,
so the file is not closed. I may choose to iterate over g later or
not, so it has to remain in suspension just in case. In practice if
you do this in CPython then f.__exit__ will *probably* be invoked
indirectly by g.__del__ if/when the gc collects g. This defeats the
main point of using with-open though which is to avoid depending on
the gc for closing files.

--
Oscar


More information about the Python-ideas mailing list