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-change-the-world/>