2012/8/6 Dino Viehland <di...@microsoft.com>:
> I'm trying to create an object which works like a generator and delegates to 
> a generator for its implementation, but can also participate in yield from 
> using 3.3 beta.  I want my wrapper object to be able to cache some additional 
> information - such as whether or not the generator has completed - as well as 
> have it provide some additional methods for interacting with the state of the 
> generator.  But currently this doesn't seem possible because raising 
> StopIteration from a user defined iterator has its value ignored as far as 
> yield from is concerned.  Here's a simplified example of the problem:
>
> class C:
>     def __iter__(self): return self
>     def __next__(self):
>             raise StopIteration(100)
>
>
> def g():
>     if False:
>         yield 100
>     return 100
>
> def f(val):
>     x = yield from val
>     print('x', x)
>
> print(list(f(C())))
> print(list(f(g())))
>
> Which outputs:
> x None
> []
> x 100
> []
>
> So you can see for the C case the value I raise from StopIteration is 
> ignored, but the value from the generator is propagated out.  From my reading 
> of PEP 380 the behavior here is incorrect for the user defined iterator case. 
>  next(iter(C())) raises StopIteration exception with a value and that should 
> be the resulting value of the yield from expression according to the formal 
> semantics.

Looks like a bug to me. Please file an issue.

>
> Ok, looking at the implementation this seems to be because PyIter_Next clears 
> the exception which prevents it from being seen in the yield from code path.  
>  So should yield from just be doing "(*iter->ob_type->tp_iternext)(iter);" 
> directly and avoid the error checking code?  Or am I wrong and this is the 
> intended behavior?

This is probably the simpliest fix. In C, returning NULL from __next__
with no exception set is shorthand for StopIteration.


-- 
Regards,
Benjamin
_______________________________________________
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

Reply via email to