Imagine the following very common situation: you have written a long and complicated function and realize that some of the code should be extracted into a seperate function for reuse and/or readability. Usually, this extra function call will not change the semantics of your program.
However, now imagine that your function is a coroutine and the code you want to extract contains at least one asyncronous call. Extracting it into a separate function now suddenly changes your programs semantics by inserting a new point on which the coroutine yields, the event loop takes control and any other coroutine could be scheduled in between.
Example before:
async def complicated_func():
foo()
bar()
await baz()
Example after:
async def complicated_func():
foo()
await extracted_func()
async def extracted_func():
bar()
await baz()
In the example before, the complicated_func
is guaranteed not to be suspended between calling foo()
and calling bar()
. After refactoring, this guarantee is lost.
My question is this: is it possible to call extracted_func()
such that it is executed immediately as if its code would be inline? Or is there some other way to perform such common refactoring tasks without changing the programs semantics?