python / asyncio

asyncio historical repository
https://docs.python.org/3/library/asyncio.html
1.03k stars 178 forks source link

run_in_executor incorrectly identifies xmlrpclib methods as coroutines #458

Closed jimfunk closed 7 years ago

jimfunk commented 7 years ago

If a method from an xmlrpclib ServerProxy instance is passed to loop.run_in_executor() in Python 3.5.1, it incorrectly identifies it as a coroutine.

import asyncio
from xmlrpc.client import ServerProxy

async def nonblocking(loop, proxy):
    return await loop.run_in_executor(None, proxy.system.listMethods)

loop = asyncio.get_event_loop()
proxy = ServerProxy('http://127.0.0.1/RPC2/')
loop.run_until_complete(nonblocking(loop, proxy))
gvanrossum commented 7 years ago

Looks like this is because ServerProxy overrides __gettattr__ to treat any attribute as a potential method.

Can you work around it by wrapping the listMethods call in a lambda? E.g.

async def nonblocking(loop, proxy):
    return await loop.run_in_executor(None, lambda: proxy.system.listMethods())

For a real fix, maybe asyncio.isfuture() should check whether _asyncio_future_blocking is a bool or int? @1st1?

1st1 commented 7 years ago

asyncio.isfuture is a fairly recent addition, there is no stable Python out there with it. And the most recent version of isfuture should handle proxy & mock objects.

The problem is actually in asyncio.iscoroutinefunction, I've opened a PR to fix it: #459.

1st1 commented 7 years ago

Closing the issue, the PR to fix it has just been merged.