forked from M-Labs/artiq
pc_rpc: fix #1186. annotations -> str(annotations)
Turn annotations into a string which PYON can encode.
This commit is contained in:
parent
0b43ec4719
commit
b173f4f5b9
@ -11,12 +11,13 @@ client passes a list as a parameter of an RPC method, and that method
|
|||||||
client's list.
|
client's list.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import socket
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import inspect
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import logging
|
import typing
|
||||||
import inspect
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from artiq.monkey_patches import *
|
from artiq.monkey_patches import *
|
||||||
@ -24,7 +25,6 @@ from artiq.protocols import pyon
|
|||||||
from artiq.protocols.asyncio_server import AsyncioServer as _AsyncioServer
|
from artiq.protocols.asyncio_server import AsyncioServer as _AsyncioServer
|
||||||
from artiq.protocols.packed_exceptions import *
|
from artiq.protocols.packed_exceptions import *
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -487,6 +487,17 @@ class Server(_AsyncioServer):
|
|||||||
else:
|
else:
|
||||||
self._noparallel = asyncio.Lock()
|
self._noparallel = asyncio.Lock()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _document_function(function: typing.Callable) -> typing.Tuple[dict, str]:
|
||||||
|
"""Turn a function into a tuple of its arguments and documentation.
|
||||||
|
|
||||||
|
Allows remote inspection of what methods are available on a local device."""
|
||||||
|
argspec_dict = dict(inspect.getfullargspec(function)._asdict())
|
||||||
|
# Fix issue #1186: PYON can't serialize type annotations.
|
||||||
|
if any(argspec_dict.get("annotations", {})):
|
||||||
|
argspec_dict["annotations"] = str(argspec_dict["annotations"])
|
||||||
|
return (argspec_dict, inspect.getdoc(function))
|
||||||
|
|
||||||
async def _process_action(self, target, obj):
|
async def _process_action(self, target, obj):
|
||||||
if self._noparallel is not None:
|
if self._noparallel is not None:
|
||||||
await self._noparallel.acquire()
|
await self._noparallel.acquire()
|
||||||
@ -501,9 +512,7 @@ class Server(_AsyncioServer):
|
|||||||
if name.startswith("_"):
|
if name.startswith("_"):
|
||||||
continue
|
continue
|
||||||
method = getattr(target, name)
|
method = getattr(target, name)
|
||||||
argspec = inspect.getfullargspec(method)
|
doc["methods"][name] = self._document_function(method)
|
||||||
doc["methods"][name] = (dict(argspec._asdict()),
|
|
||||||
inspect.getdoc(method))
|
|
||||||
if self.builtin_terminate:
|
if self.builtin_terminate:
|
||||||
doc["methods"]["terminate"] = (
|
doc["methods"]["terminate"] = (
|
||||||
{
|
{
|
||||||
@ -515,6 +524,7 @@ class Server(_AsyncioServer):
|
|||||||
"kwonlydefaults": [],
|
"kwonlydefaults": [],
|
||||||
},
|
},
|
||||||
"Terminate the server.")
|
"Terminate the server.")
|
||||||
|
logger.debug("RPC docs for %s: %s", target, doc)
|
||||||
return {"status": "ok", "ret": doc}
|
return {"status": "ok", "ret": doc}
|
||||||
elif obj["action"] == "call":
|
elif obj["action"] == "call":
|
||||||
logger.debug("calling %s", _PrettyPrintCall(obj))
|
logger.debug("calling %s", _PrettyPrintCall(obj))
|
||||||
|
Loading…
Reference in New Issue
Block a user