How can async support dispatch between sync and async variants of the same code?

I think the reason this hasn’t been solved in its full generality is that there’s no perfect solution. Adding another keyword to the language (maybe_async) just isn’t in the cards.

Library and framework authors are usually best off having an opinionated convention aided by a decorator or metaclass fitted to the needs of the library or framework. (I believe I’ve seen a metaclass that looked for methods named async_spam and added a synchronous version named spam for each such.)