Stefan Behnel added the comment:

PEP 342 isn't really conclusive here as it intended to define the protocol 
based on the de-facto design of a yield-based generator function. Trying to 
abstract from that poses the question how a class based generator 
implementation should look like. Specifically, it is not clear in this case 
what "raise an exception *inside* the generator" even means.

As Antoine pointed out, there definitely has to be more than an Iterator. 
However, it's not clear that throw() and close() are always required for an 
implementation. Simple Generators might get away without special error handling 
and cleanup.

Similarly, a Generator may not allow (or expect) values to be passed in and 
only make use of close() for cleanup (and potentially also throw()).

So, there seem to be at least three use cases for the Generator protocol here:

1) an Iterator that can accept input values via send()
2) an Iterator that needs to safely do certain cleanup operations after use 
(throw/close)
3) a complete Generator that accepts input values and cleans up after it

Given that there used to be only one implementation, I think we can assume that 
a lot of code depends on the complete protocol. Some recipients will certainly 
be aware of the exact subset of the protocol that the Generator they have in 
their hands makes use of, but if they don't, they'll just have to assume it 
supports everything and requires proper cleanup on errors and on termination.

Therefore, I think it's important to cover the complete protocol in the 
Generator ABC. I also think it's helpful to not require users to override 
throw() in a subclass, as they might not need it. "Throwing an exception inside 
of them" might simply not have a meaning for them. If they do need it, however, 
then the current implementation might help them to properly raise the 
exception, given that the 3-argument raise statement is no longer available in 
Py3.

Both reasons (whether you need throw() or not) make me think that it should not 
be abstract. The same applies to close(), which has a meaningful implementation 
now that subclasses can make use of in order to avoid having to implement both 
close() and throw().

And yes, this is about sneaking past generator type checks because most of them 
are actually *not* there for a reason. Asyncio is just one example.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue24018>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to