[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