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
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/