On 5 May 2015 at 21:38, Guido van Rossum email@example.com wrote:
Jumping in to correct one fact.
On Tue, May 5, 2015 at 12:44 PM, Brett Cannon firstname.lastname@example.org wrote:
On Tue, May 5, 2015 at 3:14 PM Paul Moore email@example.com wrote:
Well, twisted always had defer_to_thread. Asyncio has run_in_executor, but that seems to be callback-based rather than coroutine-based?
The run_in_executor call is not callback-based -- the confusion probably stems from the name of the function argument ('callback'). It actually returns a Future representing the result (or error) of an operation, where the operation is represented by the function argument. So if you have e.g. a function
def factorial(n): return 1 if n <= 0 else n*factorial(n-1)
you can run it in an executor from your async(io) code like this:
loop = asyncio.get_event_loop() result = yield from loop.run_in_executor(factorial, 100)
(In a PEP 492 coroutine substitute await for yield from.)
Thanks, that's an important correction. Given that, run_in_executor is the link to blocking calls that I was searching for. And yes, the "callback" terminology does make this far from obvious, unfortunately. As does the point at which it's introduced (before futures have been described) and the fact that it says "this method is a coroutine" rather than "this method returns a Future".
 I'm still struggling to understand the terminology, so if those two statements are equivalent, that's not yet obvious to me.