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+py@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-leave@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-leave@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/