Skip to content

Commit ffcc92b

Browse files
committed
Compatible with cyfunction
1 parent fed5085 commit ffcc92b

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

Diff for: ajsonrpc/manager.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ async def get_response_for_request(self, request: JSONRPC20Request) -> Optional[
3737
)
3838
else:
3939
try:
40-
result = await method(*request.args, **request.kwargs) \
41-
if inspect.iscoroutinefunction(method) \
42-
else method(*request.args, **request.kwargs)
40+
# Compatible with coroutine cyfunction or other kind of functions which return coroutines
41+
# but are not coroutine functions
42+
co_or_ret = method(*request.args, **request.kwargs)
43+
# Maybe `inspect.isawaitable()` is better?
44+
result = await co_or_ret \
45+
if inspect.iscoroutine(co_or_ret) \
46+
else co_or_ret
4347
except JSONRPC20DispatchException as dispatch_error:
4448
# Dispatcher method raised exception with controlled "data"
4549
output = JSONRPC20Response(

Diff for: ajsonrpc/scripts/server.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def data_received(self, data):
3636
_, payload = request_message.split('\r\n\r\n', 1)
3737
task = create_task(self.json_rpc_manager.get_payload_for_payload(payload))
3838
task.add_done_callback(self.handle_task_result)
39-
39+
4040
def handle_task_result(self, task):
4141
res = task.result()
4242
self.transport.write((
@@ -49,6 +49,12 @@ def handle_task_result(self, task):
4949
logger.info('Close the client socket')
5050
self.transport.close()
5151

52+
# Compatible with cyfunction.
53+
# This change helps to work with some modules like `pydantic`, which wraps
54+
# functions (includes coroutine functions) into cyfunctions. The method
55+
# `inspect.isfunction()` cannot recognize them for now.
56+
def is_func_or_cyfunc(object):
57+
return isfunction(object) or (type(object).__name__ == "cython_function_or_method")
5258

5359
def main():
5460
"""Usage: % examples.methods"""
@@ -68,7 +74,7 @@ def main():
6874
module = importlib.util.module_from_spec(spec)
6975
spec.loader.exec_module(module)
7076
# get functions from the module
71-
methods = getmembers(module, isfunction)
77+
methods = getmembers(module, is_func_or_cyfunc)
7278
logger.info('Extracted methods: {}'.format(methods))
7379
dispatcher = Dispatcher(dict(methods))
7480

0 commit comments

Comments
 (0)