[Python-ideas] Make "yield" inside a with statement a SyntaxError
Rhodri James
rhodri at kynesim.co.uk
Wed Aug 8 08:35:56 EDT 2018
On 08/08/18 07:14, Ken Hilton wrote:
> Now, let's take a look at the following scenario:
>
> def read_multiple(*filenames):
> for filename in filenames:
> with open(filename) as f:
> yield f.read()
>
> Can you spot the problem? The "with open(filename)" statement is supposed
> to ensure that the file object is disposed of properly. However, the "yield
> f.read()" statement suspends execution within the with block, so if this
> happened:
>
> for contents in read_multiple('chunk1', 'chunk2', 'chunk3'):
> if contents == 'hello':
> break
>
> and the contents of "chunk2" were "hello" then the loop would exit, and
> "chunk2" would never be closed! Yielding inside a with block, therefore,
> doesn't make sense and can only lead to obscure bugs.
An incomplete analysis and therefore an incorrect conclusion. Until the
garbage collector comes out to play, read_multiple() will keep the file
open, keep the tuple of filenames in memory and of course keep the
environment of the generator around. That's all leakage caused by the
_break_, and following your logic the obvious solution would be to ban
breaks in loops that are reading from generators. But that wouldn't be
helpful, obviously.
--
Rhodri James *-* Kynesim Ltd
More information about the Python-ideas
mailing list