maybeDeferred analog with asyncio

Viewed 799

I am coding a framework, where the framework will call a user-supplied function.

I want to allow the used supplied function to be any of the following:

  • a plain function
  • a function returning asyncio.Future
  • a asyncio.coroutine

That is, the user function can be either synchronous or asynchronous, and the framework does not know in advance, but needs to cope with all variants.

Twisted has defer.maybeDeferred for this. What would be the asyncio way?

I have something like the following (full code here):

import types
types.GeneratorType

def maybe_async(value):
   if isinstance(value, types.GeneratorType) or \
      isinstance(value, asyncio.futures.Future):
      return value
   else:
      future = asyncio.Future()
      future.set_result(value)
      return future

and then call the user supplied function f like this in the framework:

res = yield from maybe_async(f(x))

This wraps any plain function return value into a Future - always. And I am wary of the performance or other impacts of this.

Is above the "recommended" way?

Also, the "inline" version of above code does not have this overhead. How could I achieve the best of both: no overhead for the "plain" case, but no code duplication for checking for async returns all over the framework?

2 Answers
Related