These are interesting ideas. It looks like you intend the except clause of the for loop to only cover the iter() and next() calls that are implicit in the for loop. You're right that it's awkward to catch exceptions there. However, I worry that when people see this syntax, they will think that the except clause is for handling exceptions in the loop body. (That's certainly what I assumed when I read just your subject line. :-)
On Fri, Jul 26, 2019 at 11:26 AM Serhiy Storchaka storchaka@gmail.com 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). We want to catch and handle exceptions raised when open a connection, when read a data and when write a data in different ways. Currently you need to expand so convenient Python statements "with" and "for" (see PEP 343)
_mgr = connect()
_enter = type(_mgr).__enter__
_exit = type(_mgr).__exit__
_value = _enter(_mgr)
_exc = True
try:
stream = _value
_it = iter(stream)
while True:
try:
data = next(_it)
except StopIteration:
break
write(data)
except:
_exc = False
if not _exit(_mgr, *sys.exc_info()):
raise
finally:
if _exc:
_exit(_mgr, None, None, None)
and then add "try ... except" around corresponding explicit calls of
__enter__()
and next()
.
try:
_mgr = connect()
_enter = type(_mgr).__enter__
_exit = type(_mgr).__exit__
_value = _enter(_mgr)
_exc = True
except OSError:
handle_connection_error()
else:
try:
stream = _value
try:
_it = iter(stream)
except OSError:
handle_read_error()
else:
while True:
try:
data = next(_it)
except StopIteration:
break
except OSError:
handle_read_error()
break
try:
write(data)
except OSError:
handle_write_error()
except:
_exc = False
if not _exit(_mgr, *sys.exc_info()):
raise
finally:
if _exc:
_exit(_mgr, None, None, None)
Does not it look ugly?
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
should be equivalent to
try:
_it = iter(EXPR)
except EXC:
HANDLER
else:
while True:
try:
VAR = next(_it)
except StopIteration:
break
except EXC:
HANDLER
break
BLOCK
and
with EXPR as VAR:
BLOCK
except EXC:
HANDLER
try:
_mgr = EXPR
_enter = type(_mgr).__enter__
_exit = type(_mgr).__exit__
_value = _enter(_mgr)
_exc = True
except EXC:
HANDLER
else:
try:
VAR = _value
BLOCK
except:
_exc = False
if not _exit(_mgr, *sys.exc_info()):
raise
finally:
if _exc:
_exit(_mgr, None, None, None)
And correspondingly for asynchronous versions "async for" and "async with".
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()
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/M76F34... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido) Pronouns: he/him/his **(why is my pronoun here?) http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...