The idea on the OP can be fully implemented with ~10 lines of code in a decorator - which could be further factored out into a decorator-for-decorators:
``` import asyncio, inspect def hybrid_decorator(func): coro = inspect.iscoroutinefunction(func) if coro: async def inner(*args, **kw): return await func(*args, **kw) else: def inner(*args, **kw): return func(*args, **kw) def wrapper(*args, **kw): ... value = inner(*args, **kw) ... return value if coro: wrapper = asyncio.coroutine(wrapper) return wrapper ``` The thing is that just in Python 3.8 the `@courotine` decorator has been deprecated - not sure if there is another "in language" way of changing an already defined, no "await" in body, function to a coroutine function. One way or another, this approach seems quite feasible for whoever wants to make use of such a feature with no need for new syntax (but maybe need for having an "undeprecated" way of doing what `@coroutine` does) Here is the approach factored out to a "decorator decorator" that does the dirty job: ``` def hybrid_async(deco): @wraps(deco) def wrapper(func): coro = inspect.iscoroutinefunction(func) if coro: async def inner(*args, **kw): return await func(*args, **kw) else: inner = func wrapped = wraps(func)(deco(inner)) if coro: wrapped = asyncio.coroutine(wrapped) return wrapped return wrapper @hybrid_async def log_run(func): @wraps(func) def wrapper(*args, **kw): print("start", flush=True) v = func(*args, **kw) print("stop", flush=True) return v return wrapper ``` On Tue, 11 Feb 2020 at 11:59, Soni L. <fakedme...@gmail.com> wrote: > > > On 2020-02-11 4:33 a.m., Ben Rudiak-Gould wrote: > > On Mon, Feb 10, 2020 at 9:50 AM Andrew Barnert via Python-ideas > > <python-ideas@python.org> wrote: > > > It’s a well-known problem that async is “contagious”: [...] > > > > > > But C# and every other language that’s borrowed the idea has the same > problem, and as far as I know, nobody’s thought of a good answer yet. > > > > Threads don't have that problem: you can use non-thread-aware code > > with callbacks in your threaded program if you do your own locking. > > Haskell (GHC) doesn't have that problem: it has fibers that use a > > programming interface like C#/Python threads, but they're multiplexed > > by user-mode code within a single OS thread. 16-bit Windows didn't > > have that problem. Stackless and greenlet don't have that problem. > > > > It's a problem that can be solved by just doing the obvious thing, the > > thing that Python already did with threads: don't define a novel > > syntax for coroutines, but instead use the syntax that already > > existed. > > > > Async/await syntax is a static type system with two types, may-yield > > and will-not-yield. There's no provision for writing > > generic/polymorphic code over those types, so you have to write > > everything twice. Like any static type system it has some benefits, > > but I don't think it's worth the cost, especially in Python, which has > > always eschewed mandatory static typing. > > > > I don't know how to fix Python now that it's gone so thoroughly down > > this path (starting with the yield keyword 18 years ago). But it's not > > a problem that ever needed to exist. Coroutines aren't that hard. > > I would suggest having an "await in" operator. Or an "autowait" function: > > def autowait(value): > if is_awaitable(value): return value > async def force_await(): > return value > return force_await() > > This would allow one to write "async-ready" code while calling non-async > functions. > > > -- Ben > > _______________________________________________ > > Python-ideas mailing list -- python-ideas@python.org > > To unsubscribe send an email to python-ideas-le...@python.org > > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/ZDQIZ5ORHLOEQO7OD2FTZNYPUSXMUTUU/ > > Code of Conduct: http://python.org/psf/codeofconduct/ > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/P4SHOVNIALCGZJX3JHSKMOC6USC2PR3Q/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/BNEAOKFZ6OBXQMP37CLRMUPDEXAQJOCB/ Code of Conduct: http://python.org/psf/codeofconduct/