This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: PEP 341 - Unification of try/except and try/finally
Type: Stage:
Components: Interpreter Core Versions: Python 2.5
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: nnorwitz Nosy List: georg.brandl, gvanrossum, krumms, ncoghlan, nnorwitz
Priority: normal Keywords: patch

Created on 2005-11-13 14:59 by krumms, last changed 2022-04-11 14:56 by admin. This issue is now closed.

File name Uploaded Description Edit
PEP-341.patch krumms, 2005-11-13 14:59 Patch implementing PEP 341 krumms, 2005-11-13 15:02 Unit test for new exception handling syntax
pep-341.patch nnorwitz, 2005-11-13 21:27 v2 - contains code and test
PEP-341.patch krumms, 2005-11-13 23:12 v3 - fixes to a few memory leaks Neal missed
PEP-341.patch krumms, 2005-11-14 00:36 v4 - try-finally was causing memory leaks
PEP-341.patch krumms, 2005-11-14 05:18 v5 - fixes for bugs reported by Neal Norwitz, unit test updated
PEP-341.patch krumms, 2005-11-15 04:10 v6 - test-goto-cleanup. use asdl_stmt_seq_free to deallocate asdl_seq instances
PEP-341.patch krumms, 2005-11-15 13:15 v7 - fix for another bug spotted by Neal, do ... while try/except emulation instead of ugly gotos
PEP-341.patch krumms, 2005-11-16 09:40 v8 - fixes for still more leaks discovered by Neal, back to using goto :(
PEP-341.patch krumms, 2005-11-16 13:52 v9 - fixes for even more leaks discovered by Nick
Messages (25)
msg49016 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-13 14:59
Attached is a patch implementing PEP 341 against HEAD
in subversion.

It includes the following changes:
1. Grammar/Grammar updated as per the PEP
2. Python/ast.c wraps try/except blocks inside
try/finally blocks if it detects the extended syntax.

This patch is based heavily upon suggestions by Nick
Coghlan on python-dev. 
msg49017 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-13 15:02
Logged In: YES 

Attaching a unit test checking the various different types
of exception handling syntax.
msg49018 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-11-13 21:27
Logged In: YES 

Updated patch to correct memory leaks.  Put everything in
one file.  Works for me.

There needs to be doc changes done too.
msg49019 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-11-13 23:10
Logged In: YES 

I'm pretty sure this patch causes this problem:

python: Objects/frameobject.c:187: frame_setlineno:
Assertion `blockstack_top > 0' failed.

I'm not sure if it's just my hacked up version or the
original.  Thomas, can you test your version?
msg49020 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-13 23:12
Logged In: YES 

Further correction of memory leaks.

'finally' and 'orelse' need to be deallocated if an error
occurs in the "if (n_except >  0)" branch.
msg49021 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-13 23:12
Logged In: YES 

Further correction of memory leaks.

'finally' and 'orelse' need to be deallocated if an error
occurs in the "if (n_except >  0)" branch.
msg49022 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-14 00:02
Logged In: YES 

Fixed a bad assumption when parsing a try-finally. Should be
fixed now.

I'm not sure if this fixes the problem you're experiencing,
Neal. I'll have a look into it.
msg49023 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-14 05:17
Logged In: YES 

Fix for the problem you encountered in the v5 patch, Nick.

All tests in the suite now pass for me, no assertion
failures when using --with-pydebug.

I was stupidly generating a TryFinally in every scenario.
This breaks down in the 'trace' unit test when no 'finally'
clause is present with the extended syntax. Oops.

Also added a little more error checking code and updated the
unit test to test nested exception handling.

I'm using a few goto statements in the "if (n_except > 0)"
branch to reduce duplication deallocating memory. If there's
any great objections to this feel free to yell & I'll
resubmit a patch without the use of goto.

Can you please verify this works for you, Nick?
msg49024 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-14 05:18
Logged In: YES 

Oops - I mean Neal :)
msg49025 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2005-11-14 08:54
Logged In: YES 

From a code inspection of v5 of the patch (I haven't
actually run the patch anywhere), I'm a little uncomfortable
with the mixture of the two error handling styles (that is,
test-cleanup-return for most of the function, but
test-goto-cleanup for the one specific case). I don't mind
either style (and both are used in the Python source), but
mixing them in one function bothers me :)

Further, there appears to be a bug in the deallocation code,
in that all sequences should be freed with
adsl_seq_stmt_free. The current direct use of adsl_seq_free
means any contained statements are not released.

I suggest putting a single 'error' label at the end of the
function that uses adsl_seq_stmt_free to clean up all the
statement sequences , as well as free_stmt to clean up the
nested except statements. As both of these functions handle
nulls gracefully, the bodies of the current error cleanup
and return branches can all then be replaced with "goto error".

msg49026 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-14 12:14
Logged In: YES 

Thanks for your input Nick - I'll sort out a patch taking
your suggestions into consideration tomorrow & resubmit it.
msg49027 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-15 04:10
Logged In: YES 

Okay, v6 is up. Now using test-goto-cleanup. Also using

Any more suggestions/feedback? Anybody having trouble using
this patch?
msg49028 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-11-15 04:43
Logged In: YES 

Oh, so close, I'm sorry, I see one more problem.  :-)

Thomas, I hope you will write up this experience in coding
this patch.  IMO it clearly demonstrates a problem with the
new AST code that needs to be addressed.  ie, Memory
management is not possible to get right.  I've got a 700+
line patch to ast.c to correct many more memory issues
(hopefully that won't cause conflicts with this patch).  I
would like to hear ideas of how the AST code can be improved
to make it much easier to not leak memory and be safe at the
same time.

The problem is that handlers is not an asdl_seq of stmt's,
but rather an asdl_seq of exceptionhandlers.  There is no
utility function to clean out this seq, so you need to do it

for (i = 0; i < asdl_seq_LEN(handlers); i++)
  free_exceptionhandler(asdl_seq_GET(handlers, i));

I don't see any other problems, but perhaps I will when it
gets checked in or I run valgrind on it.

The Other Nick :-)
msg49029 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-15 04:50
Logged In: YES 

lol thanks Neal/Nick, that's fine. :) Nick Coghlan and
yourself have been extremely helpful throughout this whole
process, and it's been a great learning experience.

I'll implement your suggested fix for 'handlers' right away.

If you like, let me know when you've committed the 700+ line
patch and I'll generate the PEP 341 patch from that.

- Tom
msg49030 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-15 13:15
Logged In: YES 

Here's the v7 patch against revision 41451, with Neal's last
fix :)

Using Marek's suggestion for try/except emulation in C from
python-dev to avoid the "goto" crap.

Any more problems here? *looks hopeful* :)

- Tom
msg49031 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-11-16 05:38
Logged In: YES 

ISTM there are a couple of problems.  Some of these were
likely in there before and I may have told you to do some.
:-(  I probably made the same error too. :-( :-(

One is a new one though.  That starts in the for loop.  You
break in there, but that only breaks out of the for loop,
doesn't it?  So you really need a goto to break out I think.

After setting except_st, it holds references to body,
handlers, and orelse, so if you free except_st, it should
free all the others.  Therefore if except_st was created
(after the if (except_st) break;), you should set body =
handlers = orelse = NULL;  Do you agree?  I think if you
don't you will get a double free.

The same would go for after you asdl_seq_SET(inner, 0,
except_st); you should set except_st = NULL;

OTOH, you fixed a memory leak.  Whenever one does return
TryExcept(); (or any other similar AST call), if TryExcept
fails, we will return NULL and all the local variables will
be leaked.

*sigh*  Sorry you have to deal with this crap.  You've been
a very good guinea pig being the first.  I really hope we do
the arenas as discussed on python-dev.  If you aren't too
burnt out, it would be a really good way to learn the rest
of the AST. :-)
msg49032 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-16 08:35
Logged In: YES 

Arrgh! :)

Well ... I'll fix up this patch & submit it again. I might
fall back to the 'goto' style of doing things just so we
don't have the mix of "do ... break ... while" and goto
(which I imagine could be almost as confusing as the mix of
check-cleanup and goto-cleanup as described by Nick
earlier). Again, if you could check the v8 patch for me it
would be much appreciated.

After that, I might hit python-dev and read up on what
everybody's been saying about pools/arenas & maybe get
started on something we can use for the AST ... anyway, I'll
discuss that on python-dev. This isn't really the place for
it :)
msg49033 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-16 09:23
Logged In: YES 

Okay, here we go: v8!

*sighs* this is devestating for my ego :)
msg49034 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2005-11-16 13:25
Logged In: YES 

Closest yet, but I don't think we're quite there yet.

The 'except_st = NULL' part should be on the line
immediately after except_st is inserted into the inner
sequence. As soon as that insertion happens, we want to
ensure that the statement is only freed once. What's
currently there will technically work, but doesn't really
have the right semantics.

More importantly, the "body = handlers = orelse = NULL" part
should only be executed if the call to TryExcept *succeeds*,
not if it fails.

Neil's right - we seriously need to find a better way to
handle this memory management or it will be a source of
significant pain (well, more pain than you've already
experienced ;)
msg49035 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-16 13:52
Logged In: YES 

You're absolutely right with those bugs Nick. Fixed now. See
how you go with v9 :)
msg49036 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-11-17 05:48
Logged In: YES 

Maybe I'm just tired, but I can't find any problems.
Assuming this patch gets in, it ought to be the least buggy
code in compile.c. :-)
msg49037 - (view) Author: Thomas Lee (krumms) (Python committer) Date: 2005-11-17 06:03
Logged In: YES 

lol ... even if it doesn't get accepted, it was a great
learning experience. The PEP itself hasn't even been
approved as yet, I've just wanted this syntax in Python for
a while :)

Anyway ... might try my hand at a few ideas I have for that
arena/pool stuff as discussed on python-dev when I get home
msg49038 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005-12-16 19:40
Logged In: YES 

Assigning to Guido for final word regarding PEP 341.

I've not checked the patch for errors, I'm not firm enough
with AST etc.
msg49039 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2005-12-16 21:43
Logged In: YES 

PEP 341 is accepted (sorry, I thought I had accepted it in

Assigning to Neal for final verification and checkin.
msg49040 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-12-17 21:34
Logged In: YES 

Thanks Thomas!

Committed revision 41740.
Date User Action Args
2022-04-11 14:56:14adminsetgithub: 42590
2005-11-13 14:59:08krummscreate