Skip to content

Commit 5aa73f8

Browse files
committed
Readable format in interface definition file, fixed tuple issues.
1 parent d976f25 commit 5aa73f8

File tree

8 files changed

+88
-91
lines changed

8 files changed

+88
-91
lines changed

simple_rpc/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,17 @@ def rpc_list(
6868

6969

7070
def rpc_call(
71-
handle: BinaryIO, device: str, baudrate: int, wait: int, name: str,
72-
args: list, load: TextIO) -> None:
71+
handle: BinaryIO, device: str, baudrate: int, wait: int, load: TextIO,
72+
name: str, args: list) -> None:
7373
"""Execute a method.
7474
7575
:arg handle: Output handle.
7676
:arg device: Device.
7777
:arg baudrate: Baud rate.
7878
:arg wait: Time in seconds before communication starts.
79+
:arg load: Interface definition file.
7980
:arg name: Method name.
8081
:arg args: Method parameters.
81-
:arg load: Interface definition file.
8282
"""
8383
args_ = list(map(lambda x: json_utf8_encode(_loads(x)), args))
8484

simple_rpc/io.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def _read_bytes_until(stream: BinaryIO, delimiter: bytes) -> bytes:
1313
return b''.join(until(lambda x: x == delimiter, stream.read, 1))
1414

1515

16-
def _read_basic(stream: BinaryIO, endianness: bytes, basic_type: bytes) -> any:
16+
def _read_basic(stream: BinaryIO, endianness: str, basic_type: str) -> any:
1717
"""Read a value of basic type from a stream.
1818
1919
:arg stream: Stream object.
@@ -22,16 +22,16 @@ def _read_basic(stream: BinaryIO, endianness: bytes, basic_type: bytes) -> any:
2222
2323
:returns: Value of type {basic_type}.
2424
"""
25-
if basic_type == b's':
25+
if basic_type == 's':
2626
return _read_bytes_until(stream, b'\0')
2727

28-
full_type = endianness + basic_type
28+
full_type = (endianness + basic_type).encode('utf-8')
2929

3030
return unpack(full_type, stream.read(calcsize(full_type)))[0]
3131

3232

3333
def _write_basic(
34-
stream: BinaryIO, endianness: bytes, basic_type: bytes, value: any
34+
stream: BinaryIO, endianness: str, basic_type: str, value: any
3535
) -> None:
3636
"""Write a value of basic type to a stream.
3737
@@ -40,33 +40,33 @@ def _write_basic(
4040
:arg basic_type: Type of {value}.
4141
:arg value: Value to write.
4242
"""
43-
if basic_type == b's':
43+
if basic_type == 's':
4444
stream.write(value + b'\0')
4545
return
4646

47-
full_type = endianness + basic_type
47+
full_type = (endianness + basic_type).encode('utf-8')
4848

4949
stream.write(pack(full_type, cast(basic_type)(value)))
5050

5151

52-
def cast(c_type: bytes) -> object:
52+
def cast(c_type: str) -> object:
5353
"""Select the appropriate casting function given a C type.
5454
5555
:arg c_type: C type.
5656
5757
:returns: Casting function.
5858
"""
59-
if c_type == b'?':
59+
if c_type == '?':
6060
return bool
61-
if c_type in [b'c', b's']:
61+
if c_type in ['c', 's']:
6262
return bytes
63-
if c_type in [b'f', b'd']:
63+
if c_type in ['f', 'd']:
6464
return float
6565
return int
6666

6767

6868
def read(
69-
stream: BinaryIO, endianness: bytes, size_t: bytes, obj_type: any
69+
stream: BinaryIO, endianness: str, size_t: str, obj_type: any
7070
) -> any:
7171
"""Read an object from a stream.
7272
@@ -93,7 +93,7 @@ def read_byte_string(stream: BinaryIO) -> bytes:
9393

9494

9595
def write(
96-
stream: BinaryIO, endianness: bytes, size_t: bytes, obj_type: any,
96+
stream: BinaryIO, endianness: str, size_t: str, obj_type: any,
9797
obj: any) -> None:
9898
"""Write an object to a stream.
9999

simple_rpc/protocol.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def _parse_type(type_str: bytes) -> any:
1010
1111
:returns: Type object.
1212
"""
13-
def _construct_type(tokens):
13+
def _construct_type(tokens: tuple):
1414
obj_type = []
1515

1616
for token in tokens:
@@ -21,7 +21,7 @@ def _construct_type(tokens):
2121
elif token in (b')', b']'):
2222
break
2323
else:
24-
obj_type.append(token)
24+
obj_type.append(token.decode())
2525

2626
return obj_type
2727

@@ -30,14 +30,14 @@ def _construct_type(tokens):
3030
if len(obj_type) > 1:
3131
raise ValueError('top level type can not be tuple')
3232
if not obj_type:
33-
return b''
33+
return ''
3434
return obj_type[0]
3535

3636

37-
def _type_name(obj_type: bytes) -> str:
38-
"""Python type name of a C type.
37+
def _type_name(obj_type: any) -> str:
38+
"""Python type name of a C object type.
3939
40-
:arg c_type: C type.
40+
:arg obj_type: C object type.
4141
4242
:returns: Python type name.
4343
"""
@@ -84,7 +84,7 @@ def _strip_split(string: str, delimiter: str) -> list:
8484
return list(map(lambda x: x.strip(), string.split(delimiter)))
8585

8686

87-
def _add_doc(method: dict, doc: str) -> None:
87+
def _add_doc(method: dict, doc: bytes) -> None:
8888
"""Add documentation to a method object.
8989
9090
:arg method: Method object.

simple_rpc/simple_rpc.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
from serial import serial_for_url
77
from serial.serialutil import SerialException
8-
from yaml import safe_dump, safe_load
8+
from yaml import dump, load
99

1010
from .extras import make_function
1111
from .io import read, read_byte_string, until, write
1212
from .protocol import parse_line
1313

1414

15-
_protocol = b'simpleRPC'
16-
_version = (3, 0, 0) # TODO: Replace tuples with lists for serialisation.
15+
_protocol = 'simpleRPC'
16+
_version = (3, 0, 0)
1717

1818
_list_req = 0xff
1919

@@ -37,8 +37,8 @@ def __init__(
3737
self._load = load
3838
# TODO: Put all of these in one object.
3939
self._version = (0, 0, 0)
40-
self._endianness = b'<'
41-
self._size_t = b'H'
40+
self._endianness = '<'
41+
self._size_t = 'H'
4242
self.methods = {}
4343

4444
if autoconnect:
@@ -65,9 +65,9 @@ def _select(self: object, index: int) -> None:
6565
6666
:arg index: Method index.
6767
"""
68-
self._write(b'B', index)
68+
self._write('B', index)
6969

70-
def _write(self: object, obj_type: bytes, obj: any) -> None:
70+
def _write(self: object, obj_type: any, obj: any) -> None:
7171
"""Provide parameters for a remote procedure call.
7272
7373
:arg obj_type: Type of the parameter.
@@ -78,7 +78,7 @@ def _write(self: object, obj_type: bytes, obj: any) -> None:
7878
def _read_byte_string(self: object) -> bytes:
7979
return read_byte_string(self._connection)
8080

81-
def _read(self: object, obj_type: str) -> any:
81+
def _read(self: object, obj_type: any) -> any:
8282
"""Read a return value from a remote procedure call.
8383
8484
:arg obj_type: Return type.
@@ -94,18 +94,18 @@ def _get_methods(self: object) -> dict:
9494
"""
9595
self._select(_list_req)
9696

97-
if self._read_byte_string() != _protocol:
97+
if self._read_byte_string().decode() != _protocol:
9898
raise ValueError('missing protocol header')
9999

100-
self._version = tuple(self._read(b'B') for _ in range(3))
100+
self._version = tuple(self._read('B') for _ in range(3))
101101
if self._version[0] != _version[0] or self._version[1] > _version[1]:
102102
raise ValueError(
103103
'version mismatch (device: {}, client: {})'.format(
104104
'.'.join(map(str, self._version)),
105105
'.'.join(map(str, _version))))
106106

107107
self._endianness, self._size_t = (
108-
bytes([c]) for c in self._read_byte_string())
108+
chr(c) for c in self._read_byte_string())
109109

110110
methods = {}
111111
for index, line in enumerate(
@@ -173,7 +173,7 @@ def save(self: object, handle: TextIO) -> None:
173173
174174
:arg handle: Open file handle.
175175
"""
176-
safe_dump(
176+
dump(
177177
{
178178
'version': self._version,
179179
'endianness': self._endianness,
@@ -183,11 +183,8 @@ def save(self: object, handle: TextIO) -> None:
183183
handle, width=76, default_flow_style=False)
184184

185185
def load(self: object) -> None:
186-
"""Load the interface definition from a file.
187-
188-
:arg handle: Open file handle.
189-
"""
190-
definition = safe_load(self._load)
186+
"""Load the interface definition from a file."""
187+
definition = load(self._load)
191188
self._version = definition['version']
192189
self._endianness = definition['endianness']
193190
self._size_t = definition['size_t']

tests/test_cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ def test_describe_method() -> None:
3535
def test_rpc_list() -> None:
3636
handle = StringIO()
3737

38-
rpc_list(handle, _devices['serial'], 9600, 1)
38+
rpc_list(handle, _devices['serial'], 9600, 1, None)
3939
assert 'ping data\n Echo a value.\n' in handle.getvalue()
4040

4141

4242
@mark.test_device('serial')
4343
def test_rpc_call() -> None:
4444
handle = StringIO()
4545

46-
rpc_call(handle, _devices['serial'], 9600, 1, 'ping', ['10'])
46+
rpc_call(handle, _devices['serial'], 9600, 1, None, 'ping', ['10'])
4747
assert handle.getvalue() == '10\n'

tests/test_device.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ def test_type_1(self: object) -> None:
2626
assert self._interface.methods['ping']['return']['typename'] == 'int'
2727

2828
def test_fmt_1(self: object) -> None:
29-
assert self._interface.methods['ping']['return']['fmt'] == b'B'
29+
assert self._interface.methods['ping']['return']['fmt'] == 'B'
3030

3131
def test_param_1(self: object) -> None:
3232
assert (
3333
self._interface.methods['ping']['parameters'][0]['typename'] ==
3434
'int')
3535

3636
def test_param_2(self: object) -> None:
37-
assert self._interface.methods['ping']['parameters'][0]['fmt'] == b'B'
37+
assert self._interface.methods['ping']['parameters'][0]['fmt'] == 'B'
3838

3939
def test_param_3(self: object) -> None:
4040
assert (

tests/test_io.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66

77
def _test_invariance_basic(
8-
f_read: callable, f_write: callable, endianness: bytes,
9-
basic_type: bytes, data: bytes, value: any) -> None:
8+
f_read: callable, f_write: callable, endianness: str, basic_type: str,
9+
data: bytes, value: any) -> None:
1010
stream = BytesIO(data)
1111
value_ = f_read(stream, endianness, basic_type)
1212
assert value_ == value
@@ -17,7 +17,7 @@ def _test_invariance_basic(
1717

1818

1919
def _test_invariance(
20-
f_read: callable, f_write: callable, endianness: bytes, size_t: bytes,
20+
f_read: callable, f_write: callable, endianness: str, size_t: str,
2121
obj_def: any, data: bytes, obj: any) -> None:
2222
stream = BytesIO(data)
2323
obj_ = f_read(stream, endianness, size_t, obj_def)
@@ -29,13 +29,13 @@ def _test_invariance(
2929

3030

3131
def test_cast() -> None:
32-
assert cast(b'?') == bool
33-
assert cast(b'c') == bytes
34-
assert cast(b's') == bytes
35-
assert cast(b'f') == float
36-
assert cast(b'd') == float
37-
assert cast(b'h') == int
38-
assert cast(b'i') == int
32+
assert cast('?') == bool
33+
assert cast('c') == bytes
34+
assert cast('s') == bytes
35+
assert cast('f') == float
36+
assert cast('d') == float
37+
assert cast('h') == int
38+
assert cast('i') == int
3939

4040

4141
def test_read_bytes_until() -> None:
@@ -46,65 +46,65 @@ def test_read_bytes_until() -> None:
4646

4747
def test_basic_string() -> None:
4848
_test_invariance_basic(
49-
_read_basic, _write_basic, b'<', b's', b'abcdef\0', b'abcdef')
49+
_read_basic, _write_basic, '<', 's', b'abcdef\0', b'abcdef')
5050

5151

5252
def test_basic_int_le() -> None:
5353
_test_invariance_basic(
54-
_read_basic, _write_basic, b'<', b'i', b'\2\0\0\0', 2)
54+
_read_basic, _write_basic, '<', 'i', b'\2\0\0\0', 2)
5555

5656

5757
def test_basic_int_be() -> None:
5858
_test_invariance_basic(
59-
_read_basic, _write_basic, b'>', b'i', b'\0\0\0\2', 2)
59+
_read_basic, _write_basic, '>', 'i', b'\0\0\0\2', 2)
6060

6161

6262
def test_list_char() -> None:
6363
_test_invariance(
64-
read, write, b'<', b'h', [b'c'], b'\3\0a\0c', [b'a', b'\0', b'c'])
64+
read, write, '<', 'h', ['c'], b'\3\0a\0c', [b'a', b'\0', b'c'])
6565

6666

6767
def test_list_nibble() -> None:
6868
_test_invariance(
69-
read, write, b'<', b'h', [b'h'], b'\3\0\1\0\2\0\3\0', [1, 2, 3])
69+
read, write, '<', 'h', ['h'], b'\3\0\1\0\2\0\3\0', [1, 2, 3])
7070

7171

7272
def test_list_list() -> None:
7373
_test_invariance(
74-
read, write, b'<', b'h', [[b'b']], b'\2\0\2\0\0\1\2\0\2\3',
74+
read, write, '<', 'h', [['b']], b'\2\0\2\0\0\1\2\0\2\3',
7575
[[0, 1], [2, 3]])
7676

7777

7878
def test_object_char_int() -> None:
7979
_test_invariance(
80-
read, write, b'<', b'h', (b'c', b'i'), b'a\3\0\0\0', (b'a', 3))
80+
read, write, '<', 'h', ('c', 'i'), b'a\3\0\0\0', (b'a', 3))
8181

8282

8383
def test_object_nibble_string_char() -> None:
8484
_test_invariance(
85-
read, write, b'<', b'h', (b'h', b's', b'c'), b'\2\0abcdef\0x',
85+
read, write, '<', 'h', ('h', 's', 'c'), b'\2\0abcdef\0x',
8686
(2, b'abcdef', b'x'))
8787

8888

8989
def test_object_object() -> None:
9090
_test_invariance(
91-
read, write, b'<', b'h', (((b'c', ), ), (b'c', ), ), b'ab',
91+
read, write, '<', 'h', ((('c', ), ), ('c', ), ), b'ab',
9292
(((b'a', ), ), (b'b', )))
9393

9494

9595
def test_list_tuple() -> None:
9696
_test_invariance(
97-
read, write, b'<', b'h', [b'c', b'c', b'c'], b'\2\0abcabc',
97+
read, write, '<', 'h', ['c', 'c', 'c'], b'\2\0abcabc',
9898
[b'a', b'b', b'c', b'a', b'b', b'c'])
9999

100100

101101
def test_list_object() -> None:
102102
_test_invariance(
103-
read, write, b'<', b'h', [(b'c', b'c', b'c')], b'\2\0abcabc',
103+
read, write, '<', 'h', [('c', 'c', 'c')], b'\2\0abcabc',
104104
[(b'a', b'b', b'c'), (b'a', b'b', b'c')])
105105

106106

107107
def test_list_object_tuple() -> None:
108108
_test_invariance(
109-
read, write, b'<', b'h', [(b'c', b'c'), b'c'], b'\2\0abcabc',
109+
read, write, '<', 'h', [('c', 'c'), 'c'], b'\2\0abcabc',
110110
[(b'a', b'b'), b'c', (b'a', b'b'), b'c'])

0 commit comments

Comments
 (0)