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/

Reply via email to