[Python-Dev] Implementation of PEP 341

Thomas Lee krumms at gmail.com
Sun Nov 13 11:34:44 CET 2005


Hi all,

I've been using Python for a few years and, as of a few days ago, 
finally decided to put the effort into contributing code back to the 
project.

I'm attempting to implement PEP 341 (unification of try/except and 
try/finally) against HEAD. However, this being my first attempt at a 
change to the syntax there's been a bit of a learning curve.

I've modified Grammar/Grammer to use the new try_stmt grammar, updated 
Parser/Python.asdl to accept a stmt* finalbody for TryExcept instances 
and modified Python/ast.c to handle the changes to Python.asdl - 
generating an AST for the finalbody.

All that remains as far as I can see is to modify Python/compile.c to 
generate the necessary code and update Modules/parsermodule.c to 
accommodate the changes to the grammar. (If anybody has further input as 
to what needs to be done here, I'm all ears!)

The difficulty I'm having is in Python/compile.c: currently there are 
two functions which generate the code for the two existing try_stmt 
paths. compiler_try_finally doesn't need any changes as far as I can 
see. compiler_try_except, however, now needs to generate code to handle 
TryExcept.finalbody (which I added to Parser/Python.asdl).

This sounds easy enough, but the following is causing me difficulty:

/* BEGIN */

ADDOP_JREL(c, SETUP_EXCEPT, except);
compiler_use_next_block(c, body);
if (!compiler_push_fblock(c, EXCEPT, body))
    return 0;
VISIT_SEQ(c, stmt, s->v.TryExcept.body);
ADDOP(c, POP_BLOCK);
compiler_pop_fblock(c, EXCEPT, body);

/* END */

A couple of things confuse me here:
1. What's the purpose of the push_fblock/pop_fblock calls?
2. Do I need to add "ADDOP_JREL(c, SETUP_FINALLY, end);" before/after 
SETUP_EXCEPT? Or will this conflict with the SETUP_EXCEPT op? I don't 
know enough about the internals of SETUP_EXCEPT/SETUP_FINALLY to know 
what to do here.

Also, in compiler_try_finally we see this code:

/* BEGIN */

ADDOP_JREL(c, SETUP_FINALLY, end);
compiler_use_next_block(c, body);
if (!compiler_push_fblock(c, FINALLY_TRY, body))
    return 0;
VISIT_SEQ(c, stmt, s->v.TryFinally.body);
ADDOP(c, POP_BLOCK);
compiler_pop_fblock(c, FINALLY_TRY, body);

ADDOP_O(c, LOAD_CONST, Py_None, consts);

/* END */

Why the LOAD_CONST Py_None? Does this serve any purpose? some sort of 
weird pseudo return value? Or does it have a semantic purpose that I'll 
have to reproduce in compiler_try_except?

Cheers, and thanks for any help you can provide :)

Tom




More information about the Python-Dev mailing list