I have a function which accepts both regular and asynchronous functions (not coroutines, but functions returning coroutines).
Internally it uses asyncio.iscoroutinefunction()
test to see which type of function it got.
Recently it broke down when I attempted to create a partial async function.
In this demonstration, ptest
is not recognized as a couroutine function, even if it returns a coroutine, i.e. ptest()
is a coroutine.
import asyncio
import functools
async def test(arg): pass
print(asyncio.iscoroutinefunction(test)) # True
ptest = functools.partial(test, None)
print(asyncio.iscoroutinefunction(ptest)) # False!!
print(asyncio.iscoroutine(ptest())) # True
The problem cause is clear, but the solution is not.
How to dynamically create a partial async func which passes the test?
OR
How to test the func wrapped inside a partial object?
Either answer would solve the problem.
Asynchronous user-defined functions must keep track of a handle and use that handle when informing Excel that the function call is finished. An asynchronous user-defined function is split into two pieces. The first piece is the standard UDF entry point, which will launch a second, separate asynchronous operation.
Handling Asynchronous Function Errors First of all, there are two common ways in creating an asynchronous function. The first one is by using Promise and second one is using async-await. A catch () function will be executed if either the promise rejects or an async function throws an error.
This without blocking the application. Because Async functions can only be declared at the top level or inside a block, the correct way to test this in your browser’s console is as follows: Enter this.waitAndInform (); to test the async function.
Async functions should not be confused with asynchronous loading of UI5 components. Also, the fact that async functions enable us to call functions synchronous works confusing. In this blog I show in detail how to use async functions. Async functions are part of version 8 of JavaScript a.k.a. EcmaScript8, ES8 or ES2017.
Using Python versions < 3.8 you can't make a partial()
object pass that test, because the test requires there to be a __code__
object attached directly to the object you pass to inspect.iscoroutinefunction()
.
You should instead test the function object that partial
wraps, accessible via the partial.func
attribute:
>>> asyncio.iscoroutinefunction(ptest.func)
True
If you also need to test for partial()
objects, then test against functools.partial
:
def iscoroutinefunction_or_partial(object):
while isinstance(object, functools.partial):
object = object.func
return inspect.iscoroutinefunction(object)
In Python 3.8 (and newer), the relevant code in the inspect
module (that asyncio.iscoroutinefunction()
delegates to) was updated to handle partial()
objects, and you no longer have to unwrap partial()
objects yourself. The implementation uses the same while isinstance(..., functools.partial)
loop.
I solved this by replacing all instances of partial
with async_partial
:
def async_partial(f, *args):
async def f2(*args2):
result = f(*args, *args2)
if asyncio.iscoroutinefunction(f):
result = await result
return result
return f2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With