[Python-ideas] Proposal: Allowing any variable to be used in a 'with... as...' expression

Terry Reedy tjreedy at udel.edu
Sat May 18 21:38:12 EDT 2019


On 5/18/2019 8:13 PM, Yonatan Zunger wrote:
> Hi everyone,
> 
> I'd like to bounce this proposal off everyone and see if it's worth 
> formulating as a PEP. I haven't found any prior discussion of it, but as 
> we all know, searches can easily miss things, so if this is old hat 
> please LMK.
> 
> *Summary: *The construction
> 
> with expr1 as var1, expr2 as var2, ...:
>      body
> 
> fails (with an AttributeError) unless each expression returns a value 
> satisfying the context manager protocol. Instead, we should permit any 
> expression to be used. If a value does not expose an __enter__ method, 
> it should behave as though its __enter__ method is return self; if it 
> does not have an __exit__ method, it should behave as though that method 
> is return False.

So far, -1.  I think trying to use a non-context manager, in particular 
None, as a context manager, *should* raise.  Since 'with' was 
introduced, we have gradually added the CM methods to most everything 
that *should* be a CM.  If you think something else specific needs 
conversion, please open a new thread.


> *Rationale: *The with statement has proven to be a valued extension to 
> Python. In addition to providing improved readability for block scoping, 
> it has strongly encouraged the use of scoped cleanups for objects which 
> require them, such as files and mutices, in the process eliminating a 
> lot of annoying bugs. I would argue that at present, whenever dealing 
> with an object which requires such cleanup at a known time, with should 
> be the default way of doing it, and /not/ doing so is the sort of thing 
> one should be explaining in a code comment. However, the current syntax 
> makes a few common patterns harder to implement than they should be.
> 
> For example, this is a good pattern:
> 
> with functionReturningFile(...) as input:
>     doSomething(input)
> 
> There are many cases where an Optional[file] makes sense as a parameter, 
> as well; for example, an optional debug output stream, or an input 
> source which may either be a file (if provided) or some non-file source 
> (by default). Likewise, there are many cases where a function may 
> naturally return an Optional[file], e.g. "open the file if the user has 
> provided the filename." However, the following is /not/ valid Python:
> 
> with functionReturningOptionalFile(...) as input:
>     doSomething(input)
> 
> To handle this case, one has a few options. One may only use the 'with' 
> in the known safe cases:
> 
> inputFile = functionReturningOptionalFile(...)
> if inputFile:

Or more expicitly, 'if inputFile is not None:'

>      with inputFile as input:
>          doSomething(input)
> else:
>      doSomething(None)


When a function returns something useful or None, I think an immediate 
test is generally good practice.  It will usually make the code clearer 
to readers.

-- 
Terry Jan Reedy




More information about the Python-ideas mailing list