Skip to content

Commit e65ec3f

Browse files
committed
Updated GeoComResponse to generic type
1 parent 983742c commit e65ec3f

File tree

2 files changed

+167
-18
lines changed

2 files changed

+167
-18
lines changed

docs/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@
146146
nitpick_ignore = {
147147
("py:class", "optional"),
148148
("py:param", "_E"),
149-
("py:param", "_T")
149+
("py:param", "_T"),
150+
("py:param", "_P")
150151
}
151152
nitpick_ignore_regex = {
152153
("py:obj", r"[a-zA-Z]{3}\.\w+")

src/geocompy/protocols.py

Lines changed: 165 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,24 @@
2020
"""
2121
from enum import IntEnum
2222
from logging import Logger
23-
from typing import Any, Callable, Iterable, Literal, Generic, TypeVar
23+
from typing import (
24+
Any, Callable, Iterable, Literal,
25+
Generic, TypeVar, overload
26+
)
2427

2528
from .communication import Connection, get_logger
2629
from .data import Angle, Byte
2730

2831

2932
_T = TypeVar("_T")
33+
_P = TypeVar("_P", bound=Any)
3034

3135

3236
class GeoComReturnCode(IntEnum):
3337
"""Base class for all GeoCom return code enums."""
3438

3539

36-
class GeoComResponse:
40+
class GeoComResponse(Generic[_P]):
3741
"""
3842
Container class for parsed GeoCom responses.
3943
@@ -47,7 +51,7 @@ def __init__(
4751
comcode: GeoComReturnCode,
4852
rpccode: GeoComReturnCode,
4953
trans: int,
50-
params: dict[str, Any]
54+
params: _P | None = None
5155
):
5256
"""
5357
Parameters
@@ -67,9 +71,9 @@ def __init__(
6771
the command.
6872
trans : int
6973
Parsed transaction ID.
70-
params : dict[str, Any]
74+
params : Any | None, optional
7175
Collection of parsed response parameters. The content
72-
is dependent on the executed function.
76+
is dependent on the executed function. (default: None)
7377
"""
7478
self.rpcname: str = rpcname
7579
"""Name of the GeoCom function, that correspondes to the RPC,
@@ -86,7 +90,7 @@ def __init__(
8690
the command."""
8791
self.trans: int = trans
8892
"""Parsed transaction ID."""
89-
self.params: dict[str, Any] = params
93+
self.params: _P | None = params
9094
"""Collection of parsed response parameters. The content
9195
is dependent on the executed function."""
9296

@@ -129,11 +133,86 @@ def __init__(
129133
logger = get_logger("/dev/null")
130134
self._logger: Logger = logger
131135

136+
@overload
132137
def request(
133138
self,
134139
rpc: int,
135-
params: Iterable[int | float | bool | str | Angle | Byte] = [],
136-
parsers: dict[str, Callable[[str], Any]] | None = None
140+
params: Iterable[int | float | bool | str | Angle | Byte] = (),
141+
parsers: Iterable[Callable[[str], Any]] | None = None
142+
) -> GeoComResponse[Iterable]:
143+
"""
144+
Executes an RPC request and returns the parsed GeoCom response.
145+
146+
Constructs a request (from the given RPC code and parameters),
147+
writes it to the serial line, then reads the response. The
148+
response is then parsed using the provided parser functions.
149+
150+
Parameters
151+
----------
152+
rpc : int
153+
Number of the RPC to execute.
154+
params : Iterable[int | float | bool | str | Angle | Byte], optional
155+
Parameters for the request, by default ()
156+
parsers : Iterable[Callable[[str], Any]] | None, optional
157+
Parser functions for the values in the RPC response,
158+
by default None
159+
160+
Returns
161+
-------
162+
GeoComResponse
163+
Parsed return codes and parameters from the RPC response.
164+
165+
Raises
166+
------
167+
NotImplementedError
168+
If the method is not implemented on the class.
169+
170+
"""
171+
172+
@overload
173+
def request(
174+
self,
175+
rpc: int,
176+
params: Iterable[int | float | bool | str | Angle | Byte] = (),
177+
parsers: Callable[[str], _T] | None = None
178+
) -> GeoComResponse[_T]:
179+
"""
180+
Executes an RPC request and returns the parsed GeoCom response.
181+
182+
Constructs a request (from the given RPC code and parameters),
183+
writes it to the serial line, then reads the response. The
184+
response is then parsed using the provided parser function.
185+
186+
Parameters
187+
----------
188+
rpc : int
189+
Number of the RPC to execute.
190+
params : Iterable[int | float | bool | str | Angle | Byte], optional
191+
Parameters for the request, by default []
192+
parsers : Callable[[str], Any] | None, optional
193+
Parser function for the value in the RPC response,
194+
by default None
195+
196+
Returns
197+
-------
198+
GeoComResponse
199+
Parsed return codes and parameters from the RPC response.
200+
201+
Raises
202+
------
203+
NotImplementedError
204+
If the method is not implemented on the class.
205+
"""
206+
207+
def request(
208+
self,
209+
rpc: int,
210+
params: Iterable[int | float | bool | str | Angle | Byte] = (),
211+
parsers: (
212+
Iterable[Callable[[str], Any]]
213+
| Callable[[str], Any]
214+
| None
215+
) = None
137216
) -> GeoComResponse:
138217
"""
139218
Executes an RPC request and returns the parsed GeoCom response.
@@ -148,9 +227,8 @@ def request(
148227
Number of the RPC to execute.
149228
params : Iterable[int | float | bool | str | Angle | Byte], optional
150229
Parameters for the request, by default []
151-
parsers : dict[str, Callable[[str], Any]] | None, optional
152-
Parser functions for the values in the RPC response
153-
(Maps the parser functions to the names of the parameters),
230+
parsers : Iterable[Callable[[str], Any]] | None, optional
231+
Parser functions for the values in the RPC response,
154232
by default None
155233
156234
Returns
@@ -166,11 +244,79 @@ def request(
166244
"""
167245
raise NotImplementedError()
168246

247+
@overload
248+
def parse_response(
249+
cls,
250+
cmd: str,
251+
response: str,
252+
parsers: Iterable[Callable[[str], Any]] | None = None
253+
) -> GeoComResponse[Iterable]:
254+
"""
255+
Parses RPC response and constructs :class:`GeoComResponse`
256+
instance.
257+
258+
Parameters
259+
----------
260+
cmd : str
261+
Full, serialized request, that invoked the response.
262+
response : str
263+
Full, received response.
264+
parsers : Iterable[Callable[[str], Any]], optional
265+
Parser functions for the values in the RPC response, by
266+
default None
267+
268+
Returns
269+
-------
270+
GeoComResponse
271+
Parsed return codes and parameters from the RPC response.
272+
273+
Raises
274+
------
275+
NotImplementedError
276+
If the method is not implemented on the class.
277+
"""
278+
279+
@overload
169280
def parse_response(
170281
cls,
171282
cmd: str,
172283
response: str,
173-
parsers: dict[str, Callable[[str], Any]]
284+
parsers: Callable[[str], _T] | None = None
285+
) -> GeoComResponse[_T]:
286+
"""
287+
Parses RPC response and constructs :class:`GeoComResponse`
288+
instance.
289+
290+
Parameters
291+
----------
292+
cmd : str
293+
Full, serialized request, that invoked the response.
294+
response : str
295+
Full, received response.
296+
parsers : Callable[[str], Any] | None, optional
297+
Parser function for the value in the RPC response, by
298+
default None
299+
300+
Returns
301+
-------
302+
GeoComResponse
303+
Parsed return codes and parameters from the RPC response.
304+
305+
Raises
306+
------
307+
NotImplementedError
308+
If the method is not implemented on the class.
309+
"""
310+
311+
def parse_response(
312+
cls,
313+
cmd: str,
314+
response: str,
315+
parsers: (
316+
Iterable[Callable[[str], Any]]
317+
| Callable[[str], Any]
318+
| None
319+
) = None
174320
) -> GeoComResponse:
175321
"""
176322
Parses RPC response and constructs :class:`GeoComResponse`
@@ -182,9 +328,11 @@ def parse_response(
182328
Full, serialized request, that invoked the response.
183329
response : str
184330
Full, received response.
185-
parsers : dict[str, Callable[[str], Any]]
186-
Parser functions for the values in the RPC response.
187-
(Maps the parser functions to the names of the parameters.)
331+
parsers : Iterable[Callable[[str], Any]]
332+
| Callable[[str], Any]
333+
| None, optional
334+
Parser functions for the values in the RPC response,
335+
by default None
188336
189337
Returns
190338
-------
@@ -227,7 +375,7 @@ def __init__(
227375
desc: str,
228376
cmd: str,
229377
response: str,
230-
value: _T,
378+
value: _T | None,
231379
comment: str = ""
232380
):
233381
"""
@@ -253,7 +401,7 @@ def __init__(
253401
"""Full, serialized command, that invoked this response."""
254402
self.response: str = response
255403
"""Full, received response."""
256-
self.value: _T = value
404+
self.value: _T | None = value
257405
"""Parsed response value. The content is dependent on the
258406
executed command."""
259407
self.comment: str = comment

0 commit comments

Comments
 (0)