[Guido (responding to Fredrik Lundh's "intuitive -1" on PEP 343)] > > Would it be better if we pulled back in the generator exit handling > > from PEP 340? That's a pretty self-contained thing, and would let you > > write try/finally around the yield.
[Nick Coghlan] > That would be good, in my opinion. I updated PEP 3XX to use this idea: > http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html > > With that update (to version 1.6), PEP 3XX is basically PEP 343, but injecting > exceptions that occur into the template generator's internal frame instead of > invoking next(). I'm in favor of the general idea, but would like to separate the error injection and finalization API for generators into a separate PEP, which would then compete with PEP 288 and PEP 325. I think the API *should* be made public if it is available internally; I don't see any implementation reasons why it would simplify the implementation if it was only available internally. Here are some issues to resolve in such a PEP. - What does _inject_exception() return? It seems that it should raise the exception that was passed into it, but I can't find this written out explicitly. - What should happen if a generator, in a finally or except clause reached from _inject_exception(), executes another yield? I'm tempted to make this a legitimate outcome (from the generator's perspective) and reserve it for some future statement that implements the looping semantics of PEP 340; the *_template decorator's wrapper class however should consider it an error, just like other protocol mismatches like not yielding the first time or yielding more than once in response to next(). Nick's code in fact does all this right, Ijust think it should be made explicit. - TerminateIteration is a lousy name, since "terminate" means about the same as "stop", so there could be legitimate confusion with StopIteration. In PEP 340 I used StopIteration for this purpose, but someone explained this was a poor choice since existing generators may contain code that traps StopIteration for other purposes. Perhaps we could use SystemExit for this purpose? Pretty much everybody is supposed to let this one pass through since its purpose is only to allow cleanup upon program (or thread) exit. - I really don't like reusing __del__ as the method name for any kind of destructor; __del__ has all sorts of special semantics (the GC treats objects with a __del__ method specially). - The all_lines() example jars me. Somehow it bugs me that its caller has to remember to care about finalizing it. Maybe it's just not a good example; I don't see what this offers over just writing the obviously correct: for fn in filenames: with opening(fn) as f: for line in f: update_config(line) even if using the template saves a line. I doubt the use case comes up frequently enough to warrant abstracting it out. If I have to import the template to save a line here, I just made my program a bit less readable (since the first-time reader has to look up the definition of the imported all_lines template) and I didn't even save a line unless the template is used at least twice. (Note that Nick's PEP contains two typos here -- it says "print lines" where it should say "print line" and a bit later "print f" where again it should say "print line".) -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com