Hi Justin,

> On Nov 10, 2016, at 6:59 PM, Justin Mayfield <too...@gmail.com> wrote:
> 
> Thank you for your thoughtful and informative reply Yury.
> 
> I'm mostly convinced that doc updates (to which you have already made 
> several) informing users of potential peril is the safest thing to do.  So I 
> won't harp on the issue going passed this reply.
> 
> With that being said, I am still a bit stuck on this belief that 
> CO_ITERABLE_COROUTINE and as you now pointed out collections.abc.Coroutine 
> types should be given the same treatment as native coros where the question 
> being asked is, "Can this be used like a coroutine?”

Yes, and that’s what why we have ‘inspect.isawaitable’ and 
‘asyncio.iscoroutine’ functions.

We still can’t change ‘inspect.iscoroutine' to return ‘True’ for 
CO_ITERABLE_COROUTINE and collection.abc.Coroutine instances.  Reason 1: that 
would break the contract for many programs that are our there right now.  The 
following code will break (and I know such code is out there because I’ve 
written some similar code myself):

  if inspect.iscoroutine(obj):
      if obj.cr_running:
          do_something(obj.cr_await)

Reason 2: is* functions in the inspect module return ‘True’ only for built-in 
types.  We don’t use collections.abc.Generator for inspect.isgenerator(), and 
we don’t want to change that.  Changing only inspect.iscoroutine to use 
collections.abc doesn’t make a lot of sense.


>  From a high level perspective a user won't tend to care if the underlying 
> implementation of a coro is generator based when asking questions about coro 
> protocol.  They just want to know things like if they need to call `await 
> foo()` or `foo()`.  Put another way, it is an implementation detail that some 
> coros are generator based or otherwise (see Cython collections.abc.Coroutine 
> subtypes).
> 
> It's my belief that by increasing the breadth of a test like 
> inspect.iscoroutinefunction() you don't undermine the fact that some of those 
> functions are also generator functions, you merely complement it.  One can 
> still ask if a coro is a generator if needed and by answering yes to an 
> object being a coroutine you aren't (or shouldn't be) altering its generator 
> protocol.  To me that would be the deciding factor for any calls that might 
> be extending their breadth in this regard.  For example, I ask myself, what 
> harm comes from changing the check in `_PyGen_Finalize` to look for all types 
> of coros, or just calling a more open minded implementation of 
> `inspect.iscoroutine`, as a determinant for that super awesome "coroutine __ 
> was never awaited" message?  As far as I can tell it only increases 
> consistency and determinism by reducing variance.

Maybe we could update _PyGen_Finalize to issue warnings for 
CO_ITERABLE_COROUTINE.  We’ll have to make sure that the change makes sense for 
frameworks like curio, which uses generators decorated with types.coroutine to 
implement some core machinery.  And the thing is, it’s too late to make it 
happen in Python 3.6.  

Updating finalization (and inspect.iscoroutine fwiw) in 3.7 won’t affect much, 
because when 3.7 is released I hope almost everybody will switch to async/await 
(and forget about generator-based coroutines).

> 
> Again, thank you for taking the time to walk through this with me.  I'm a 
> huge asyncio fan and love building things with it.  Now it's time to get back 
> to doing just that…

NP!  Please continue working with asyncio and asking questions!

Yury

Reply via email to