[Python-Dev] PyEval_GetFrame() revisited

Christian Tismer tismer@tismer.com
Sat, 15 Mar 2003 00:29:26 +0100


Fred L. Drake, Jr. wrote:
> Christian Tismer writes:
...

>  > Does it make sense to think about an API for
>  > modifying the frame? Or are we at a dead end here?
> 
> What's being modified isn't the frame but the tstate, but it may be
> reasonable to provide some API to manipulate the "current" frame.

That was what I intended to say.

> I think pyexpat is unique in doing this, but it actually makes a lot
> of sense; there are other modules for which a similar behavior is
> likely to be appropriate (one example I can think of is Fredrik's
> sgmlop module).

I just looked into MHammond's files and found AXDebug.cpp reading
tstate's frame, too, line 192:

	PyFrameObject *frame = state ? state->frame : NULL;

WOuld be another candidate to use PyEval_GetFrame()

> What pyexpat is trying to achieve is fairly simple, and I don't think
> there's a better way currently.  When Python code calls the Parse() or
> ParseFile() method of a parser object (returned from
> pyexpat.ParserCreate()), the parser can generate many different
> callbacks into Python code.  pyexpat generates an artificial code
> object and frame that can be used to generate more useful tracebacks
> when exceptions are raise within callbacks; the code object indicates
> which callback Expat triggered, separately from the function assigned
> to handle that callback.  This makes it much easier to debug handler
> functions.

Yes, this makes very much sense, to just wrap a frame around
something to get useful tracebacks.

> If there were API functions to get/set the frame, pyexpat wouldn't
> need to poke into the tstate at all.  Would that alleviate the
> difficulties this creates for Stackless / Psycho?

I think so.
For internal functions, inside the main Python implementation,
it is no problem to maintain a number of patches, or to even
use interface functions whenre they make sense like enabling
Psyco.
For external modules, it would be nicer if certain implementation
details could be hidden, to give more freedom to implement
somethign differently, without breaking unknown modules.
PyExpat is in a grey zone, since it is already in the
Python distribution, and I had no problem to patch it.

The reason why I'm asking is that in Stackless 2.0 and above,
tstate is always carrying a so-called tasklet object which
holds the current frame. There can be many of these, while
there is only one current one per tstate, and they
can be switched at certain times. At the moment, I always have
to take care to preserve a valid tstate->frame variable,
whenever I'm switching tasklets. It would make the code much
smaller and cleaner, if I could simply redefine the current
frame to be just the frame held in the current tasklet.

Something like PyEval_SetFrame() would make sense, but there is
a problem with the protocol: After changing the frame, the
currently running interpreter would not know to execute it,
but continue to run the running one.
For normal Python, PyEval_SetFrame() would only make sense,
if the calling code would also make sure that the new frame
is run, or popped off after a special action was done.

PyExpat, as I understand, uses this frame just as a wrapper
for the case of an exception, when the frame would be used
only when a failing function returns NULL.
Stackless extends this and also knows to return a special
value instead of NULL, in order to tell the calling
interpreter to stop its action and let the new frame run.

Even in PyExpat's use, it would hard to explain the use
of such a function, I fear. But I'd really like to have it.

cheers - chris

-- 
Christian Tismer             :^)   <mailto:tismer@tismer.com>
Mission Impossible 5oftware  :     Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a     :    *Starship* http://starship.python.net/
14109 Berlin                 :     PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34  home +49 30 802 86 56  pager +49 173 24 18 776
PGP 0x57F3BF04       9064 F4E1 D754 C2FF 1619  305B C09C 5A3B 57F3 BF04
      whom do you want to sponsor today?   http://www.stackless.com/