PEP: 341
Title: Unifying try-except and try-finally
Version: $Revision: 41719 $
Last-Modified: $Date: 2005-12-16 13:28:04 -0800 (Fri, 16 Dec 2005) $
Author: Reinhold Birkenfeld <reinhold-birkenfeld-nospam at wolke7.net>
Status: Accepted
Type: Standards Track
Content-Type: text/plain
Created: 04-May-2005
Post-History: 

Abstract

    This PEP proposes a change in the syntax and semantics of try
    statements to allow combined try-except-finally blocks. This
    means in short that it would be valid to write

        try:
            <do something>
        except Exception:
            <handle the error>
        finally:
            <cleanup>


Rationale/Proposal

    There are many use cases for the try-except statement and
    for the try-finally statement per se; however, often one needs
    to catch exceptions and execute some cleanup code afterwards.
    It is slightly annoying and not very intelligible that
    one has to write

        f = None
        try:
            try:
                f = open(filename)
                text = f.read()
            except IOError:
                print 'An error occured'
        finally:
            if f:
                f.close()

    So it is proposed that a construction like this

        try:
            <suite 1>
        except Ex1:
            <suite 2>
        <more except: clauses>
        else:
            <suite 3>
        finally:
            <suite 4>

    be exactly the same as the legacy

        try:
            try:
                <suite 1>
            except Ex1:
                <suite 2>
            <more except: clauses>
            else:
                <suite 3>
        finally:
            <suite 4>

    This is backwards compatible, and every try statement that is
    legal today would continue to work.


Changes to the grammar

    The grammar for the try statement, which is currently

        try_stmt: ('try' ':' suite (except_clause ':' suite)+
                   ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)

    would have to become

        try_stmt: 'try' ':' suite
                  (
                    (except_clause ':' suite)+
                    ['else' ':' suite]
                    ['finally' ':' suite]
                  |
                    'finally' ':' suite
                  )

Implementation

    As the PEP author currently does not have sufficient knowledge
    of the CPython implementation, he is unfortunately not able
    to deliver one.  Thomas Lee has submitted a patch[2].

    However, according to Guido, it should be a piece of cake to
    implement[1] -- at least for a core hacker.


References

    [1] http://mail.python.org/pipermail/python-dev/2005-May/053319.html
    [2] http://python.org/sf/1355913


Copyright

    This document has been placed in the public domain.