[Python-ideas] Possible PEP 380 tweak (original) (raw)
Jacob Holm jh at improva.dk
Wed Oct 27 09:57:16 CEST 2010
- Previous message: [Python-ideas] Possible PEP 380 tweak
- Next message: [Python-ideas] Possible PEP 380 tweak
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 2010-10-26 19:01, Guido van Rossum wrote:
On Tue, Oct 26, 2010 at 5:22 AM, Jacob Holm <jh at improva.dk> wrote: [...]
Here's a stupid idea... let g.close take an optional argument that it can return if the generator is already exhausted and let it return the value from the StopIteration otherwise.
def close(self, default=None): if self.giframe is None: return default try: self.throw(GeneratorExit) except StopIteration as e: return e.args[0] except GeneratorExit: return None else: raise RuntimeError('generator ignored GeneratorExit') You'll have to explain why None isn't sufficient. It is not really necessary, but seemed "cleaner" somehow. Think of "g.close(default)" as "get me the result if possible, and this default otherwise". Then think of dict.get()... Hm, I'd say there always is a result -- it just sometimes is None. I really don't want to make distinctions between falling off the end of the function, "return" without a value, "return None", "raise StopIteration()", "raise StopIteration(None)", or even (in response to a close() request) "raise GeneratorExit".
None of these cover the distinction I am making. I want to distinguish between a non-exhausted and an exhausted generator.
When calling close on a non-exhausted generator, the generator decides how to return by any one of the means you mentioned. In this case you are right that there is always a result.
When calling close on an exhausted generator, the generator has no choice in the matter as the "true" return value was thrown away. We have to return something, but calling it the "result" of the generator is stretching it too far. Making it possible to return something other than None in this case seems to be analogous to dict.get().
If we chose to use a different method (e.g. Nicks "finish") for getting the "result", I would instead raise a RuntimeError when calling it on an exhausted generator. i.o.w, I would want it defined something like this:
def finish(self): if self.gi_frame is None: raise RuntimeError('generator already finished') try: self.throw(GeneratorExit) except StopIteration as e: return e.args[0] except GeneratorExit: return None # XXX debatable but unimportant to me else: raise RuntimeError('generator ignored GeneratorExit')
(possibly using a new GeneratorReturn exception instead)
You might argue for using a different exception for signaling the exhausted case, e.g.:
class GeneratorFinishedError(StandardError): """finish() called on exhaused generator."""
but that only really makes sense if you think calling finish without knowing whether the generator is exhausted is a reasonable thing to do.
If that is the case, we should also consider adding a 'default' argument to finish which (if provided) could be returned instead of raising the exception (kind of like dict.pop).
- Jacob
- Previous message: [Python-ideas] Possible PEP 380 tweak
- Next message: [Python-ideas] Possible PEP 380 tweak
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]