Extend obj->iternext to handle not just __next__(), but also send() method
For generators (generalization of iterators), .__next__() method is defined as .send(None). It's only natural to extend C-level ->iternext() method to accept send argument, to allow implementation of C-level generators optimally. Caveat: so far, none of such exist. But work on optimizing uasyncio may lead to need for such. Or maybe not, maybe "virtual" awaitable methods will be used instead: https://github.com/micropython/micropython/issues/2622 .
This ticket is created to be referenced by in-code TODO comments (yes, I think we reached that code complexity that need to reference tickets straight from code).
RFC: Implementing generic generator protocol
So, we now have complete implementation of generator protocol - but for generators themselves. Here's proposal how to extend it to other compatible objects.
So, let there be
mp_vm_return_kind_t mp_resume(mp_obj_t self_in,
mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val)
function which dispatch to mp_obj_gen_resume() if object is generator, to mp_iternext() if object supports C-level iterator protocol, and otherwise assume that it's ducktype generator and use dynamic method lookup.
Note that generator protocol is superset of iterator protocol, so the 2nd part of the proposal is to move ducktyping implementation from mp_iternext() to mp_resume(), and use the latter consistently in the interpreter.