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 <storch...@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-le...@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/M76F3434TXNO2EUMZZ647EABTCNXYGXA/
> 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/>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/7IPBZ2WKAZZ2QYS55SGT65XUEVDCITZQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to