On Fri, Jul 26, 2019 at 09:26:00PM +0300, Serhiy Storchaka wrote:
Python allows you to write code in tight and readable form. Consider the following example.
with connect() as stream: # connect() or __enter__() can fail. for data in stream: # __next__() can fail write(data) # write() can fail
The problem is that different lines can raise an exception of the same type (for example OSError).
I'm not sure if that is the best example, because as far as I know, errors in opening the file and errors in writing to the file will raise OSErrors with different error numbers, so you can distinguish them.
But your broader point is applicable: different parts of the block may raise the same exception, and we have no good way of telling them apart.
We want to catch and handle exceptions raised when open a connection, when read a data and when write a data in different ways.
Would it help if it were easier to tell the source of an exception? This is just a sketch, not a serious proposal, but something like this?
try: with connect() as stream: # connect() or __enter__() can fail. for data in stream: # __next__() can fail write(data) # write() can fail except OSError as err: if err.source == "connect": ... elif err.source == "stream.__enter__": ... elif err.source == "__next__": ... elif err.source == "write": ... else: raise
I propose to add "except" clause to "for" and "with" statement to catch exceptions in the code that can't be wrapped with "try ... except".
for VAR in EXPR: BLOCK except EXC: HANDLER
[...snip pure-python equivalent...]
That implies that you will always want to treat an exception in EXPR.__iter__ and __next__ the same. What if you need to treat them differently?
So you will be able to add errors handling like in:
with connect() as stream: for data in stream: try: write(data) except OSError: handle_write_error() except OSError: handle_read_error() except OSError: handle_connection_error()
To be really robust, shouldn't you check the error codes, and only handle the codes you know how to handle? But if you're doing that, it seems to me that you only need one "except OSError" handler. Am I wrong?