[Python-Dev] PEP 492: What is the real goal?

Jim J. Jewett jimjjewett at gmail.com
Fri May 1 23:37:11 CEST 2015

On Thu Apr 30 21:27:09 CEST 2015, Yury Selivanov replied:

On 2015-04-30 2:41 PM, Jim J. Jewett wrote:

>> Bad phrasing on my part.  Is there anything that prevents an
>> asynchronous call (or waiting for one) without the "async with"?

>> If so, I'm missing something important.  Either way, I would
>> prefer different wording in the PEP.

> Yes, you can't use 'yield from' in __exit__/__enter__
> in current Python.

I tried it in 3.4, and it worked.

I'm not sure it would ever be sensible, but it didn't raise any
errors, and it did run.

What do you mean by "can't use"?

>>> For coroutines in PEP 492:
>>> __await__ = __anext__ is the same as __call__ = __next__
>>> __await__ = __aiter__ is the same as __call__ = __iter__

>> That tells me that it will be OK sometimes, but will usually
>> be either a mistake or an API problem -- and it explains why.

>> Please put those 3 lines in the PEP.

> There is a line like that:
> https://www.python.org/dev/peps/pep-0492/#await-expression
> Look for "Also, please note..." line.

It was from reading the PEP that the question came up, and I
just reread that section.

Having those 3 explicit lines goes a long way towards explaining
how an asychio coroutine differs from a regular callable, in a
way that the existing PEP doesn't, at least for me.

>>> This is OK. The point is that you can use 'await log' in
>>> __aenter__.  If you don't need awaits in __aenter__ you can
>>> use them in __aexit__. If you don't need them there too,
>>> then just define a regular context manager.

>> Is it an error to use "async with" on a regular context manager?
>> If so, why?  If it is just that doing so could be misleading,
>> then what about "async with mgr1, mgr2, mgr3" -- is it enough
>> that one of the three might suspend itself?

> 'with' requires an object with __enter__ and __exit__

> 'async with' requires an object with __aenter__ and __aexit__

> You can have an object that implements both interfaces.

I'm not still not seeing why with (let alone await with) can't
just run whichever one it finds.  "await with" won't actually let
the BLOCK run until the future is resolved.  So if a context
manager only supplies __enter__ instead of __aenter__, then at most
you've lost a chance to switch tasks while waiting -- and that is no
worse than if the context manager just happened to be really slow.

>>>>> For debugging this kind of mistakes there is a special debug mode in

>> Is the intent to do anything more than preface execution with:

>> import asynchio.coroutines
>> asynchio.coroutines._DEBUG = True

> This won't work, unfortunately.  You need to set the
> debug flag *before* you import asyncio package (otherwise
> we would have an unavoidable performance cost for debug
> features).  If you enable it after you import asyncio,
> then asyncio itself won't be instrumented.  Please
> see the implementation of asyncio.coroutine for details.

Why does asynchio itself have to wrapped?  Is that really something
normal developers need to debug, or is it only for developing the
stdlib itself?  If it if only for developing the stdlib, than I
would rather see workarounds like shoving _DEBUG into builtins
when needed, as opposed to adding multiple attributes to sys.



If there are still threading problems with my replies, please
email me with details, so that I can try to resolve them.  -jJ

More information about the Python-Dev mailing list