python/asyncio

run_in_executor incorrectly identifies xmlrpclib methods as coroutines

jimfunk opened this issue · 3 comments

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))

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

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

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