[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