I don’t think that’s quite the same topic as this thread. That’s dispatch on the callee side, but on the caller side you’d have async functions only. So function color becomes a problem.
I’m not an expert in terms of what’s possible at the outer edge of language design, but it strikes me as problematic if x = y(); await x and await y() have different meanings. At the very least, it doesn’t match the current way that await composes with function calls.
It’s been a long time since I really thought about this problem – webargs has two separate call paths and that works fine – but I think it would be fun and interesting to play with a tool for doing this with codegen. Maybe if I get some of my other projects done this year… With the benefit of time and distance, that looks like the right solution because it’s the only way to change the name of the functions you’re calling. And that mapping of names can be parametrized and fine tuned. I’d implement narrow rules to do function name transforms. Maybe frame it a bit like cog. e.g. imagine this:
# async_foo.py
class AsyncFoo:
async def bar(self) -> AsyncBaz:
return await _async_quux()
# foo.py
# /// async2sync start
# convert("async_foo.py", "AsyncFoo")
# ///
class Foo:
def bar(self) -> Baz:
return _quux()
# /// async2sync end