> but we don't need special syntax for "else" on a for or while loop (or try 
> block) either, you could always set a sentinel for those too.
> which to me is a case for adding else to a "with" block as well, for all the 
> same reasons it's there for the other block construct.

That's part of my opinion too, afaik, only `with` is currently missing
an `else` part.

> Though I don't think I'd advocate it in this case, as the Exception is not 
> really a clear part of the context manger API, like "break" is
> to the loops.

Well part of the __exit__ documentation, you can read the following:


    Returning a true value from this method will cause the with
statement to suppress the exception and continue execution with the
    statement immediately following the with statement. Otherwise the
exception continues propagating after this method has finished
    executing.


So exceptions are quite part of the context manager API. Based on that
I actually created a context manager using this property:


    class savepoint(object):

        def __init__(self, tm):
            self._sp = None
            self._tm = tm


        def __enter__(self) -> bool:
            """Save the current state of the transaction."""
            try:
                self._sp = self._tm.savepoint()
            except TypeError:
                return False
            else:
                return self._sp.valid


        def __exit__(self, exc_type, exc_val: ty.Any, exc_tb):
            """Save the sub-transaction or roll it back in case an
error occurred."""
            if exc_type is not None and issubclass(exc_type, DatabaseError):
                self._sp.rollback()
                return False
            elif exc_type is not None:
                raise exc_type(exc_val)
            return True


The issue is that I have to enclose usage of the manager into a try/catch block:


    try:
        with savepoint(request.tm) as sp:
            if not sp:
                raise TypeError('Unsupported database.')

            url = insert_url(request.db, u_url)
            request.db.flush()
    except IntegrityError:
        url = lookup_url(request.db, u_url)


Having with/else I could do the following instead:


    with savepoint(request.tm) as sp:
        if not sp:
            raise TypeError('Unsupported database.')

        url = insert_url(request.db, u_url)
        request.db.flush()
    else:
        url = lookup_url(request.db, u_url)


I therefore save some lines and indentations.
_______________________________________________
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/PILLQVANNANGZ3P7G3ZTT7LAHKFE35K3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to