Skip to content

Commit 3c71ce6

Browse files
committed
refactor(jsonrpc): fix some spellings and split up some methods
1 parent be9466a commit 3c71ce6

File tree

2 files changed

+157
-61
lines changed

2 files changed

+157
-61
lines changed

packages/debugger/src/robotcode/debugger/protocol.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from robotcode.jsonrpc2.protocol import (
2727
JsonRPCException,
2828
JsonRPCProtocolBase,
29-
SendedRequestEntry,
29+
SentRequestEntry,
3030
)
3131

3232
from .dap_types import (
@@ -78,7 +78,7 @@ class DebugAdapterProtocol(JsonRPCProtocolBase):
7878
def __init__(self) -> None:
7979
super().__init__()
8080
self._sended_request_lock = threading.RLock()
81-
self._sended_request: OrderedDict[int, SendedRequestEntry] = OrderedDict()
81+
self._sended_request: OrderedDict[int, SentRequestEntry] = OrderedDict()
8282
self._received_request_lock = threading.RLock()
8383
self._received_request: OrderedDict[int, asyncio.Future[Any]] = OrderedDict()
8484
self._initialized = False
@@ -307,7 +307,7 @@ def send_request(self, request: Request, return_type: Optional[Type[TResult]] =
307307
result: Task[TResult] = Task()
308308

309309
with self._sended_request_lock:
310-
self._sended_request[request.seq] = SendedRequestEntry(result, return_type)
310+
self._sended_request[request.seq] = SentRequestEntry(result, return_type)
311311

312312
self.send_message(request)
313313

packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py

Lines changed: 154 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def get_param_type(self, name: str) -> Optional[Type[Any]]:
348348
return result.param_type
349349

350350

351-
class SendedRequestEntry:
351+
class SentRequestEntry:
352352
def __init__(self, future: Task[Any], result_type: Optional[Type[Any]]) -> None:
353353
self.future = future
354354
self.result_type = result_type
@@ -420,6 +420,8 @@ def eof_received(self) -> Optional[bool]:
420420
re.DOTALL,
421421
)
422422

423+
DEFAULT_MESSAGE_LENGTH: Final = 1
424+
423425
def data_received(self, data: bytes) -> None:
424426
while len(data):
425427
# Append the incoming chunk to the message buffer
@@ -429,7 +431,7 @@ def data_received(self, data: bytes) -> None:
429431
found = self.MESSAGE_PATTERN.match(self._message_buf)
430432

431433
body = found.group("body") if found else b""
432-
length = int(found.group("length")) if found else 1
434+
length = int(found.group("length")) if found else self.DEFAULT_MESSAGE_LENGTH
433435

434436
charset = (
435437
found.group("charset").decode("ascii") if found and found.group("charset") is not None else self.CHARSET
@@ -453,9 +455,9 @@ class JsonRPCProtocol(JsonRPCProtocolBase):
453455

454456
def __init__(self) -> None:
455457
super().__init__()
456-
self._sended_request_lock = threading.RLock()
457-
self._sended_request: OrderedDict[Union[str, int], SendedRequestEntry] = OrderedDict()
458-
self._sended_request_count = 0
458+
self._sent_request_lock = threading.RLock()
459+
self._sent_request: OrderedDict[Union[str, int], SentRequestEntry] = OrderedDict()
460+
self._sent_request_count = 0
459461
self._received_request: OrderedDict[Union[str, int, None], ReceivedRequestEntry] = OrderedDict()
460462
self._received_request_lock = threading.RLock()
461463
self._signature_cache: Dict[Callable[..., Any], inspect.Signature] = {}
@@ -567,11 +569,11 @@ def send_request(
567569
) -> Task[_TResult]:
568570
result: Task[_TResult] = Task()
569571

570-
with self._sended_request_lock:
571-
self._sended_request_count += 1
572-
id = self._sended_request_count
572+
with self._sent_request_lock:
573+
self._sent_request_count += 1
574+
id = self._sent_request_count
573575

574-
self._sended_request[id] = SendedRequestEntry(result, return_type)
576+
self._sent_request[id] = SentRequestEntry(result, return_type)
575577

576578
request = JsonRPCRequest(id=id, method=method, params=params)
577579
self.send_message(request)
@@ -598,8 +600,8 @@ async def handle_response(self, message: JsonRPCResponse) -> None:
598600
self.send_error(JsonRPCErrors.INTERNAL_ERROR, error)
599601
return
600602

601-
with self._sended_request_lock:
602-
entry = self._sended_request.pop(message.id, None)
603+
with self._sent_request_lock:
604+
entry = self._sent_request.pop(message.id, None)
603605

604606
if entry is None:
605607
error = f"Invalid response. Could not find id '{message.id}' in request list."
@@ -628,8 +630,8 @@ async def handle_error(self, message: JsonRPCError) -> None:
628630
self.__logger.warning(error)
629631
raise JsonRPCErrorException(message.error.code, message.error.message, message.error.data)
630632

631-
with self._sended_request_lock:
632-
entry = self._sended_request.pop(message.id, None)
633+
with self._sent_request_lock:
634+
entry = self._sent_request.pop(message.id, None)
633635

634636
if entry is None:
635637
error = f"Invalid response. Could not find id '{message.id}' in request list."
@@ -660,71 +662,158 @@ def _convert_params(
660662
params_type: Optional[Type[Any]],
661663
params: Any,
662664
) -> Tuple[List[Any], Dict[str, Any]]:
665+
"""Convert JSON-RPC parameters to function arguments.
666+
667+
Args:
668+
callable: The target function to call
669+
params_type: Expected parameter type for conversion
670+
params: Raw parameters from JSON-RPC message
671+
672+
Returns:
673+
Tuple of (positional_args, keyword_args) for function call
674+
"""
663675
if params is None:
664676
return [], {}
677+
665678
if params_type is None:
666-
if isinstance(params, Mapping):
667-
return [], dict(**params)
679+
return self._handle_untyped_params(params)
680+
681+
return self._handle_typed_params(callable, params_type, params)
668682

669-
return [params], {}
683+
def _handle_untyped_params(self, params: Any) -> Tuple[List[Any], Dict[str, Any]]:
684+
"""Handle parameters when no specific type is expected."""
685+
if isinstance(params, Mapping):
686+
return [], dict(**params)
687+
return [params], {}
670688

671-
# try to convert the dict to correct type
689+
def _handle_typed_params(
690+
self,
691+
callable: Callable[..., Any],
692+
params_type: Type[Any],
693+
params: Any,
694+
) -> Tuple[List[Any], Dict[str, Any]]:
695+
"""Handle parameters with type conversion and signature matching."""
696+
# Convert the parameters to the expected type
672697
converted_params = from_dict(params, params_type)
673698

674-
# get the signature of the callable
699+
# Get cached signature or create new one
700+
signature = self._get_cached_signature(callable)
701+
702+
# Extract field names from converted parameters
703+
field_names = self._extract_field_names(converted_params)
704+
705+
# Process signature parameters
706+
return self._process_signature_parameters(signature, converted_params, params, field_names)
707+
708+
def _get_cached_signature(self, callable: Callable[..., Any]) -> inspect.Signature:
709+
"""Get or cache the signature of a callable."""
675710
if callable in self._signature_cache:
676-
signature = self._signature_cache[callable]
677-
else:
678-
signature = inspect.signature(callable)
679-
self._signature_cache[callable] = signature
711+
return self._signature_cache[callable]
712+
713+
signature = inspect.signature(callable)
714+
self._signature_cache[callable] = signature
715+
return signature
680716

717+
def _extract_field_names(self, converted_params: Any) -> List[str]:
718+
"""Extract field names from converted parameters."""
719+
if is_dataclass(converted_params):
720+
return [f.name for f in fields(converted_params)]
721+
return list(converted_params.__dict__.keys())
722+
723+
def _process_signature_parameters(
724+
self,
725+
signature: inspect.Signature,
726+
converted_params: Any,
727+
params: Any,
728+
field_names: List[str],
729+
) -> Tuple[List[Any], Dict[str, Any]]:
730+
"""Process function signature parameters and map them to arguments."""
681731
has_var_kw = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values())
682732

683-
kw_args = {}
684-
args = []
733+
kw_args: Dict[str, Any] = {}
734+
args: List[Any] = []
685735
params_added = False
686736

687-
field_names = (
688-
[f.name for f in fields(converted_params)]
689-
if is_dataclass(converted_params)
690-
else list(converted_params.__dict__.keys())
691-
)
692-
693737
rest = set(field_names)
694738
if isinstance(params, dict):
695739
rest = set.union(rest, params.keys())
696740

697-
for v in signature.parameters.values():
698-
if v.name in field_names:
699-
if v.kind == inspect.Parameter.POSITIONAL_ONLY:
700-
args.append(getattr(converted_params, v.name))
701-
else:
702-
kw_args[v.name] = getattr(converted_params, v.name)
703-
704-
rest.remove(v.name)
705-
elif v.name == "params":
706-
if v.kind == inspect.Parameter.POSITIONAL_ONLY:
707-
args.append(converted_params)
708-
params_added = True
709-
else:
710-
kw_args[v.name] = converted_params
711-
params_added = True
712-
elif isinstance(params, dict) and v.name in params:
713-
if v.kind == inspect.Parameter.POSITIONAL_ONLY:
714-
args.append(params[v.name])
715-
else:
716-
kw_args[v.name] = params[v.name]
741+
# Map signature parameters to arguments
742+
for param in signature.parameters.values():
743+
if param.name in field_names:
744+
self._add_field_parameter(param, converted_params, args, kw_args)
745+
rest.remove(param.name)
746+
elif param.name == "params":
747+
self._add_params_parameter(param, converted_params, args, kw_args)
748+
params_added = True
749+
elif isinstance(params, dict) and param.name in params:
750+
self._add_dict_parameter(param, params, args, kw_args)
751+
752+
# Handle remaining parameters if function accepts **kwargs
717753
if has_var_kw:
718-
for r in rest:
719-
if hasattr(converted_params, r):
720-
kw_args[r] = getattr(converted_params, r)
721-
elif isinstance(params, dict) and r in params:
722-
kw_args[r] = params[r]
723-
724-
if not params_added:
725-
kw_args["params"] = converted_params
754+
self._handle_var_keywords(rest, converted_params, params, kw_args, params_added)
755+
726756
return args, kw_args
727757

758+
def _add_field_parameter(
759+
self,
760+
param: inspect.Parameter,
761+
converted_params: Any,
762+
args: List[Any],
763+
kw_args: Dict[str, Any],
764+
) -> None:
765+
"""Add a parameter from converted_params fields."""
766+
value = getattr(converted_params, param.name)
767+
if param.kind == inspect.Parameter.POSITIONAL_ONLY:
768+
args.append(value)
769+
else:
770+
kw_args[param.name] = value
771+
772+
def _add_params_parameter(
773+
self,
774+
param: inspect.Parameter,
775+
converted_params: Any,
776+
args: List[Any],
777+
kw_args: Dict[str, Any],
778+
) -> None:
779+
"""Add the entire converted_params as 'params' parameter."""
780+
if param.kind == inspect.Parameter.POSITIONAL_ONLY:
781+
args.append(converted_params)
782+
else:
783+
kw_args[param.name] = converted_params
784+
785+
def _add_dict_parameter(
786+
self,
787+
param: inspect.Parameter,
788+
params: Dict[str, Any],
789+
args: List[Any],
790+
kw_args: Dict[str, Any],
791+
) -> None:
792+
"""Add a parameter from the original params dict."""
793+
value = params[param.name]
794+
if param.kind == inspect.Parameter.POSITIONAL_ONLY:
795+
args.append(value)
796+
else:
797+
kw_args[param.name] = value
798+
799+
def _handle_var_keywords(
800+
self,
801+
rest: Set[str],
802+
converted_params: Any,
803+
params: Any,
804+
kw_args: Dict[str, Any],
805+
params_added: bool,
806+
) -> None:
807+
"""Handle remaining parameters for functions with **kwargs."""
808+
for name in rest:
809+
if hasattr(converted_params, name):
810+
kw_args[name] = getattr(converted_params, name)
811+
elif isinstance(params, dict) and name in params:
812+
kw_args[name] = params[name]
813+
814+
if not params_added:
815+
kw_args["params"] = converted_params
816+
728817
async def handle_request(self, message: JsonRPCRequest) -> None:
729818
try:
730819
e = self.registry.get_entry(message.method)
@@ -859,7 +948,14 @@ async def handle_notification(self, message: JsonRPCNotification) -> None:
859948
pass
860949
except (SystemExit, KeyboardInterrupt):
861950
raise
951+
except JsonRPCErrorException:
952+
# Specific RPC errors should be re-raised
953+
raise
954+
except (ValueError, TypeError) as e:
955+
# Parameter validation errors
956+
self.__logger.warning(lambda: f"Parameter validation failed for {message.method}: {e}", exc_info=e)
862957
except BaseException as e:
958+
# Unexpected errors
863959
self.__logger.exception(e)
864960

865961

0 commit comments

Comments
 (0)