[Python-Dev] Re: anonymous blocks

Phillip J. Eby pje at telecommunity.com
Thu Apr 28 02:01:38 CEST 2005


At 03:58 PM 4/27/05 -0700, Guido van Rossum wrote:
>OK, I sort of get it, at a very high-level, although I still feel this
>is wildly out of my league.
>
>I guess I should try it first. ;-)

It's not unlike David Mertz' articles on implementing coroutines and 
multitasking using generators, except that I'm adding more "debugging 
sugar", if you will, by making the tracebacks look normal.  It's just that 
the *how* requires me to pass the traceback into the generator.  At the 
moment, I accomplish that by doing a 3-argument raise inside of 
'events.resume()', but it would be really nice to be able to get rid of 
'events.resume()' in a future version of Python.


> > Of course, it seems to me that you also have the problem of adding to the
> > traceback when the same error is reraised...
>
>I think when it is re-raised, no traceback entry should be added; the
>place that re-raises it should not show up in the traceback, only the
>place that raised it in the first place. To me that's the essence of
>re-raising (and I think that's how it works when you use raise without
>arguments).

I think maybe I misspoke.  I mean adding to the traceback *so* that when 
the same error is reraised, the intervening frames are included, rather 
than lost.

In other words, IIRC, the traceback chain is normally increased by one 
entry for each frame the exception escapes.  However, if you start hiding 
that inside of the exception instance, you'll have to modify it instead of 
just modifying the threadstate.  Does that make sense, or am I missing 
something?


> > For that matter, I don't see a lot of value in
> > hand-writing new objects with resume/error, instead of just using a 
> generator.
>
>Not a lot, but I expect that there may be a few, like an optimized
>version of lock synchronization.

My point was mainly that we can err on the side of caller convenience 
rather than callee convenience, if there are fewer implementations.  So, 
e.g. multiple methods aren't a big deal if it makes the 'block' 
implementation simpler, if only generators and a handful of special 
template objects are going need to implement the block API.


> > So, I guess I'm thinking you'd have something like tp_block_resume and
> > tp_block_error type slots, and generators' tp_iter_next would just be the
> > same as tp_block_resume(None).
>
>I hadn't thought much about the C-level slots yet, but this is a
>reasonable proposal.

Note that it also doesn't require a 'next()' builtin, or a next vs. 
__next__ distinction, if you don't try to overload iteration and 
templating.  The fact that a generator can be used for templating, doesn't 
have to imply that any iterator should be usable as a template, or that the 
iteration protocol is involved in any way.  You could just have 
__resume__/__error__ matching the tp_block_* slots.

This also has the benefit of making the delineation between template blocks 
and for loops more concrete.  For example, this:

     block open("filename") as f:
         ...

could be an immediate TypeError (due to the lack of a __resume__) instead 
of biting you later on in the block when you try to do something with f, or 
because the block is repeating for each line of the file, etc.



More information about the Python-Dev mailing list