runtimepy 5.10.2__py3-none-any.whl → 5.11.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runtimepy/__init__.py +2 -2
- runtimepy/channel/environment/array.py +4 -4
- runtimepy/channel/environment/telemetry.py +3 -3
- runtimepy/channel/event/__init__.py +1 -1
- runtimepy/codec/protocol/__init__.py +3 -2
- runtimepy/codec/protocol/base.py +97 -54
- runtimepy/codec/protocol/json.py +18 -13
- runtimepy/codec/system/__init__.py +5 -7
- runtimepy/net/udp/tftp/__init__.py +0 -1
- runtimepy/primitives/array/__init__.py +28 -9
- runtimepy/primitives/bool.py +13 -6
- runtimepy/primitives/float.py +5 -0
- runtimepy/primitives/int.py +8 -0
- runtimepy/primitives/serializable/__init__.py +1 -1
- runtimepy/primitives/serializable/base.py +50 -15
- runtimepy/primitives/types/bounds.py +5 -0
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/METADATA +5 -5
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/RECORD +22 -22
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/WHEEL +1 -1
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/entry_points.txt +0 -0
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/licenses/LICENSE +0 -0
- {runtimepy-5.10.2.dist-info → runtimepy-5.11.1.dist-info}/top_level.txt +0 -0
runtimepy/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =====================================
|
|
2
2
|
# generator=datazen
|
|
3
3
|
# version=3.1.4
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=da21068ff2c7240dc103642dedb80cf5
|
|
5
5
|
# =====================================
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
|
|
|
10
10
|
|
|
11
11
|
DESCRIPTION = "A framework for implementing Python services."
|
|
12
12
|
PKG_NAME = "runtimepy"
|
|
13
|
-
VERSION = "5.
|
|
13
|
+
VERSION = "5.11.1"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -95,10 +95,10 @@ class ArrayChannelEnvironment(_BaseChannelEnvironment):
|
|
|
95
95
|
|
|
96
96
|
# Begin handling a new bit-fields primitive.
|
|
97
97
|
if curr_fields is None:
|
|
98
|
-
|
|
99
|
-
assert
|
|
100
|
-
result.array.add(
|
|
101
|
-
available_field_names = set(
|
|
98
|
+
curr_fields = self.fields.get_fields(name)
|
|
99
|
+
assert curr_fields is not None, f"Unknown bit-field '{name}'!"
|
|
100
|
+
result.array.add(curr_fields.raw)
|
|
101
|
+
available_field_names = set(curr_fields.names)
|
|
102
102
|
|
|
103
103
|
# Keep track of field names processed in the current bit-fields
|
|
104
104
|
# primitive.
|
|
@@ -99,7 +99,7 @@ class TelemetryChannelEnvironment(_BaseChannelEnvironment):
|
|
|
99
99
|
cast(int, channels.event_header["timestamp"]),
|
|
100
100
|
kind.decode(
|
|
101
101
|
data,
|
|
102
|
-
byte_order=channels.event_header.
|
|
102
|
+
byte_order=channels.event_header.byte_order,
|
|
103
103
|
),
|
|
104
104
|
)
|
|
105
105
|
|
|
@@ -120,7 +120,7 @@ class TelemetryChannelEnvironment(_BaseChannelEnvironment):
|
|
|
120
120
|
cast(int, self.channels.event_header["timestamp"]),
|
|
121
121
|
kind.decode(
|
|
122
122
|
data,
|
|
123
|
-
byte_order=self.channels.event_header.
|
|
123
|
+
byte_order=self.channels.event_header.byte_order,
|
|
124
124
|
),
|
|
125
125
|
)
|
|
126
126
|
|
|
@@ -146,7 +146,7 @@ class TelemetryChannelEnvironment(_BaseChannelEnvironment):
|
|
|
146
146
|
read_size = channels.event_header.size
|
|
147
147
|
data = channels.event_fifo.pop(read_size)
|
|
148
148
|
if data is not None:
|
|
149
|
-
channels.event_header.
|
|
149
|
+
channels.event_header.update(data)
|
|
150
150
|
|
|
151
151
|
# Update local variables.
|
|
152
152
|
ident = cast(int, channels.event_header["identifier"])
|
|
@@ -90,7 +90,7 @@ class PrimitiveEvent:
|
|
|
90
90
|
self.header["timestamp"] = curr_ns
|
|
91
91
|
|
|
92
92
|
# Write header then value.
|
|
93
|
-
array = self.header
|
|
93
|
+
array = self.header
|
|
94
94
|
written += array.to_stream(stream)
|
|
95
95
|
written += raw.to_stream(stream, byte_order=array.byte_order)
|
|
96
96
|
if flush:
|
|
@@ -4,7 +4,6 @@ A module implementing an interface to build communication protocols.
|
|
|
4
4
|
|
|
5
5
|
# built-in
|
|
6
6
|
from abc import ABC, abstractmethod
|
|
7
|
-
from copy import copy
|
|
8
7
|
from typing import Optional
|
|
9
8
|
|
|
10
9
|
# internal
|
|
@@ -40,10 +39,12 @@ class ProtocolFactory(ABC):
|
|
|
40
39
|
|
|
41
40
|
# We only need to run the routine that populates the protocol once.
|
|
42
41
|
if not cls.initialized:
|
|
42
|
+
if not cls.protocol.alias:
|
|
43
|
+
cls.protocol.alias = cls.__name__
|
|
43
44
|
cls.initialize(cls.protocol)
|
|
44
45
|
cls.initialized = True
|
|
45
46
|
|
|
46
|
-
return
|
|
47
|
+
return cls.protocol.copy()
|
|
47
48
|
|
|
48
49
|
@classmethod
|
|
49
50
|
def singleton(cls) -> Protocol:
|
runtimepy/codec/protocol/base.py
CHANGED
|
@@ -3,8 +3,9 @@ A module implementing an interface to build communication protocols.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
# built-in
|
|
6
|
-
from contextlib import contextmanager
|
|
6
|
+
from contextlib import contextmanager, suppress
|
|
7
7
|
from copy import copy as _copy
|
|
8
|
+
from io import StringIO
|
|
8
9
|
from typing import Iterator as _Iterator
|
|
9
10
|
from typing import NamedTuple
|
|
10
11
|
from typing import Optional as _Optional
|
|
@@ -57,9 +58,10 @@ class FieldSpec(NamedTuple):
|
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
T = _TypeVar("T", bound="ProtocolBase")
|
|
61
|
+
ProtocolBuild = list[_Union[int, FieldSpec, tuple[str, int]]]
|
|
60
62
|
|
|
61
63
|
|
|
62
|
-
class ProtocolBase:
|
|
64
|
+
class ProtocolBase(PrimitiveArray):
|
|
63
65
|
"""A class for defining runtime communication protocols."""
|
|
64
66
|
|
|
65
67
|
def __init__(
|
|
@@ -67,14 +69,16 @@ class ProtocolBase:
|
|
|
67
69
|
enum_registry: _EnumRegistry,
|
|
68
70
|
names: _NameRegistry = None,
|
|
69
71
|
fields: BitFieldsManager = None,
|
|
70
|
-
build:
|
|
72
|
+
build: ProtocolBuild = None,
|
|
71
73
|
identifier: int = 1,
|
|
72
74
|
byte_order: _Union[_ByteOrder, _RegistryKey] = _DEFAULT_BYTE_ORDER,
|
|
73
75
|
serializables: SerializableMap = None,
|
|
76
|
+
alias: str = None,
|
|
74
77
|
) -> None:
|
|
75
78
|
"""Initialize this protocol."""
|
|
76
79
|
|
|
77
80
|
self.id = identifier
|
|
81
|
+
self.alias = alias
|
|
78
82
|
|
|
79
83
|
# Register the byte-order enumeration if it's not present.
|
|
80
84
|
self._enum_registry = enum_registry
|
|
@@ -86,7 +90,8 @@ class ProtocolBase:
|
|
|
86
90
|
byte_order = _ByteOrder(
|
|
87
91
|
self._enum_registry["ByteOrder"].get_int(byte_order)
|
|
88
92
|
)
|
|
89
|
-
|
|
93
|
+
|
|
94
|
+
super().__init__(byte_order=byte_order)
|
|
90
95
|
|
|
91
96
|
if names is None:
|
|
92
97
|
names = _NameRegistry()
|
|
@@ -96,11 +101,11 @@ class ProtocolBase:
|
|
|
96
101
|
fields = BitFieldsManager(self.names, self._enum_registry)
|
|
97
102
|
self._fields = fields
|
|
98
103
|
|
|
99
|
-
self._regular_fields: dict[str, _AnyPrimitive] = {}
|
|
104
|
+
self._regular_fields: dict[str, list[_AnyPrimitive]] = {}
|
|
100
105
|
self._enum_fields: dict[str, _RuntimeEnum] = {}
|
|
101
106
|
|
|
102
107
|
# Keep track of the order that the protocol was created.
|
|
103
|
-
self._build:
|
|
108
|
+
self._build: ProtocolBuild = []
|
|
104
109
|
|
|
105
110
|
# Keep track of named serializables.
|
|
106
111
|
self.serializables: SerializableMap = {}
|
|
@@ -110,24 +115,28 @@ class ProtocolBase:
|
|
|
110
115
|
build = []
|
|
111
116
|
for item in build:
|
|
112
117
|
if isinstance(item, int):
|
|
113
|
-
self._add_bit_fields(self._fields.fields[item]
|
|
114
|
-
elif isinstance(item,
|
|
115
|
-
assert serializables, (item, serializables)
|
|
116
|
-
self.add_field(item, serializable=serializables[item])
|
|
117
|
-
del serializables[item]
|
|
118
|
-
else:
|
|
118
|
+
self._add_bit_fields(self._fields.fields[item])
|
|
119
|
+
elif isinstance(item, FieldSpec):
|
|
119
120
|
self.add_field(
|
|
120
121
|
item.name,
|
|
121
122
|
item.kind,
|
|
122
123
|
enum=item.enum,
|
|
123
|
-
track=False,
|
|
124
124
|
array_length=item.array_length,
|
|
125
125
|
)
|
|
126
|
+
else:
|
|
127
|
+
assert serializables, (item, serializables)
|
|
128
|
+
name = item[0]
|
|
129
|
+
self.add_serializable(
|
|
130
|
+
name,
|
|
131
|
+
serializables[name][0],
|
|
132
|
+
array_length=None if item[1] == 1 else item[1],
|
|
133
|
+
)
|
|
134
|
+
del serializables[name]
|
|
126
135
|
|
|
127
136
|
# Ensure all serializables were handled via build.
|
|
128
137
|
assert not serializables, serializables
|
|
129
138
|
|
|
130
|
-
def
|
|
139
|
+
def _copy_impl(self: T) -> T:
|
|
131
140
|
"""Create another protocol instance from this one."""
|
|
132
141
|
|
|
133
142
|
return self.__class__(
|
|
@@ -135,11 +144,12 @@ class ProtocolBase:
|
|
|
135
144
|
names=self.names,
|
|
136
145
|
fields=_copy(self._fields),
|
|
137
146
|
build=self._build,
|
|
138
|
-
byte_order=self.
|
|
147
|
+
byte_order=self.byte_order,
|
|
139
148
|
serializables={
|
|
140
|
-
key: val.copy_without_chain()
|
|
149
|
+
key: [val[0].copy_without_chain()]
|
|
141
150
|
for key, val in self.serializables.items()
|
|
142
151
|
},
|
|
152
|
+
alias=self.alias,
|
|
143
153
|
)
|
|
144
154
|
|
|
145
155
|
def register_name(self, name: str) -> int:
|
|
@@ -151,13 +161,14 @@ class ProtocolBase:
|
|
|
151
161
|
|
|
152
162
|
def add_serializable(
|
|
153
163
|
self, name: str, serializable: Serializable, array_length: int = None
|
|
154
|
-
) ->
|
|
164
|
+
) -> None:
|
|
155
165
|
"""Add a serializable instance."""
|
|
156
166
|
|
|
157
167
|
self.register_name(name)
|
|
158
|
-
|
|
159
|
-
self.
|
|
160
|
-
|
|
168
|
+
|
|
169
|
+
instances = self.add_to_end(serializable, array_length=array_length)
|
|
170
|
+
self._build.append((name, len(instances)))
|
|
171
|
+
self.serializables[name] = instances
|
|
161
172
|
|
|
162
173
|
def add_field(
|
|
163
174
|
self,
|
|
@@ -165,17 +176,17 @@ class ProtocolBase:
|
|
|
165
176
|
kind: _Primitivelike = None,
|
|
166
177
|
enum: _RegistryKey = None,
|
|
167
178
|
serializable: Serializable = None,
|
|
168
|
-
track: bool = True,
|
|
169
179
|
array_length: int = None,
|
|
170
|
-
) ->
|
|
180
|
+
) -> None:
|
|
171
181
|
"""Add a new field to the protocol."""
|
|
172
182
|
|
|
173
183
|
# Add the serializable to the end of this protocol.
|
|
174
184
|
if serializable is not None:
|
|
175
185
|
assert kind is None and enum is None
|
|
176
|
-
|
|
186
|
+
self.add_serializable(
|
|
177
187
|
name, serializable, array_length=array_length
|
|
178
188
|
)
|
|
189
|
+
return
|
|
179
190
|
|
|
180
191
|
self.register_name(name)
|
|
181
192
|
|
|
@@ -189,25 +200,20 @@ class ProtocolBase:
|
|
|
189
200
|
kind = runtime_enum.primitive
|
|
190
201
|
|
|
191
202
|
assert kind is not None
|
|
192
|
-
new = _create(kind)
|
|
193
|
-
|
|
194
|
-
result = self.array.add(new, array_length=array_length)
|
|
195
|
-
self._regular_fields[name] = new
|
|
196
203
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
)
|
|
204
|
+
self._regular_fields[name] = self.add(
|
|
205
|
+
_create(kind), array_length=array_length
|
|
206
|
+
)
|
|
201
207
|
|
|
202
|
-
|
|
208
|
+
self._build.append(
|
|
209
|
+
FieldSpec(name, kind, enum, array_length=array_length)
|
|
210
|
+
)
|
|
203
211
|
|
|
204
|
-
def _add_bit_fields(self, fields: _BitFields
|
|
212
|
+
def _add_bit_fields(self, fields: _BitFields) -> None:
|
|
205
213
|
"""Add a bit-fields instance."""
|
|
206
214
|
|
|
207
|
-
|
|
208
|
-
self.
|
|
209
|
-
if track:
|
|
210
|
-
self._build.append(idx)
|
|
215
|
+
self._build.append(self._fields.add(fields))
|
|
216
|
+
self.add(fields.raw)
|
|
211
217
|
|
|
212
218
|
@contextmanager
|
|
213
219
|
def add_bit_fields(
|
|
@@ -219,55 +225,92 @@ class ProtocolBase:
|
|
|
219
225
|
yield new
|
|
220
226
|
self._add_bit_fields(new)
|
|
221
227
|
|
|
222
|
-
def value(
|
|
228
|
+
def value(
|
|
229
|
+
self, name: str, resolve_enum: bool = True, index: int = 0
|
|
230
|
+
) -> ProtocolPrimitive:
|
|
223
231
|
"""Get the value of a field belonging to the protocol."""
|
|
224
232
|
|
|
225
233
|
val: ProtocolPrimitive = 0
|
|
226
234
|
|
|
227
235
|
if name in self._regular_fields:
|
|
228
|
-
val = self._regular_fields[name].value
|
|
236
|
+
val = self._regular_fields[name][index].value
|
|
229
237
|
|
|
230
238
|
# Resolve the enum value.
|
|
231
239
|
if resolve_enum and name in self._enum_fields:
|
|
232
|
-
|
|
240
|
+
with suppress(KeyError):
|
|
241
|
+
val = self._enum_fields[name].get_str(val) # type: ignore
|
|
233
242
|
|
|
234
243
|
return val
|
|
235
244
|
|
|
236
245
|
return self._fields.get(name, resolve_enum=resolve_enum)
|
|
237
246
|
|
|
238
|
-
@property
|
|
239
|
-
def size(self) -> int:
|
|
240
|
-
"""Get this protocol's size in bytes."""
|
|
241
|
-
return self.array.length()
|
|
242
|
-
|
|
243
247
|
def trace_size(self, logger: LoggerType) -> None:
|
|
244
248
|
"""Log a size trace."""
|
|
245
|
-
logger.info("%s: %s", self, self.
|
|
249
|
+
logger.info("%s: %s", self, self.length_trace(alias=self.alias))
|
|
246
250
|
|
|
247
251
|
def __str__(self) -> str:
|
|
248
252
|
"""Get this instance as a string."""
|
|
249
253
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
254
|
+
with StringIO() as stream:
|
|
255
|
+
stream.write(
|
|
256
|
+
"{"
|
|
257
|
+
+ f"{self.resolve_alias(alias=self.alias)}({self.length()}): "
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
parts = []
|
|
261
|
+
for name in self.names.registered_order:
|
|
262
|
+
part = name
|
|
263
|
+
count = 1
|
|
264
|
+
|
|
265
|
+
if name in self.serializables:
|
|
266
|
+
count = len(self.serializables[name])
|
|
267
|
+
part += f"<{self.serializables[name][0].resolve_alias()}>"
|
|
268
|
+
elif name in self._regular_fields:
|
|
269
|
+
count = len(self._regular_fields[name])
|
|
270
|
+
|
|
271
|
+
part += f"<{self._regular_fields[name][0].kind}>"
|
|
272
|
+
|
|
273
|
+
if count > 1:
|
|
274
|
+
part += f"[{count}] = ["
|
|
275
|
+
if name in self._regular_fields:
|
|
276
|
+
part += ", ".join(
|
|
277
|
+
str(x.value) for x in self._regular_fields[name]
|
|
278
|
+
)
|
|
279
|
+
else:
|
|
280
|
+
part += ", ".join("..." for _ in range(count))
|
|
281
|
+
part += "]"
|
|
282
|
+
else:
|
|
283
|
+
part += f" = {self[name]}"
|
|
284
|
+
|
|
285
|
+
parts.append(part)
|
|
253
286
|
|
|
254
|
-
|
|
287
|
+
stream.write(", ".join(parts))
|
|
288
|
+
|
|
289
|
+
stream.write("}")
|
|
290
|
+
|
|
291
|
+
return stream.getvalue()
|
|
292
|
+
|
|
293
|
+
def __getitem__(self, name: str) -> ProtocolPrimitive: # type: ignore
|
|
255
294
|
"""Get the value of a protocol field."""
|
|
256
295
|
|
|
257
296
|
if name in self.serializables:
|
|
258
|
-
return str(self.serializables[name])
|
|
297
|
+
return str(self.serializables[name][0])
|
|
259
298
|
|
|
260
299
|
return self.value(name)
|
|
261
300
|
|
|
262
|
-
def
|
|
301
|
+
def set(self, name: str, val: ProtocolPrimitive, index: int = 0) -> None:
|
|
263
302
|
"""Set a value of a field belonging to the protocol."""
|
|
264
303
|
|
|
265
304
|
if name in self._regular_fields:
|
|
266
305
|
# Resolve an enum value.
|
|
267
306
|
if isinstance(val, str):
|
|
268
307
|
val = self._enum_fields[name].get_int(val)
|
|
269
|
-
self._regular_fields[name].value = val
|
|
308
|
+
self._regular_fields[name][index].value = val
|
|
270
309
|
elif name in self.serializables and isinstance(val, str):
|
|
271
|
-
self.serializables[name].update_str(val)
|
|
310
|
+
self.serializables[name][index].update_str(val)
|
|
272
311
|
else:
|
|
273
312
|
self._fields.set(name, val) # type: ignore
|
|
313
|
+
|
|
314
|
+
def __setitem__(self, name: str, val: ProtocolPrimitive) -> None:
|
|
315
|
+
"""Set a value of a field belonging to the protocol."""
|
|
316
|
+
self.set(name, val)
|
runtimepy/codec/protocol/json.py
CHANGED
|
@@ -14,7 +14,11 @@ from vcorelib.io.types import JsonObject as _JsonObject
|
|
|
14
14
|
from vcorelib.io.types import JsonValue as _JsonValue
|
|
15
15
|
|
|
16
16
|
# internal
|
|
17
|
-
from runtimepy.codec.protocol.base import
|
|
17
|
+
from runtimepy.codec.protocol.base import (
|
|
18
|
+
FieldSpec,
|
|
19
|
+
ProtocolBase,
|
|
20
|
+
ProtocolBuild,
|
|
21
|
+
)
|
|
18
22
|
from runtimepy.primitives.field.manager import (
|
|
19
23
|
ENUMS_KEY,
|
|
20
24
|
NAMES_KEY,
|
|
@@ -46,9 +50,11 @@ class JsonProtocol(ProtocolBase):
|
|
|
46
50
|
"""Export this protocol's data to JSON."""
|
|
47
51
|
|
|
48
52
|
data = self._fields.export_json(resolve_enum=resolve_enum)
|
|
53
|
+
|
|
49
54
|
data[META_KEY] = {
|
|
50
55
|
"id": self.id,
|
|
51
|
-
"byte_order": self.
|
|
56
|
+
"byte_order": self.byte_order.name.lower(),
|
|
57
|
+
"alias": self.alias,
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
# Export regular-field names.
|
|
@@ -72,12 +78,12 @@ class JsonProtocol(ProtocolBase):
|
|
|
72
78
|
)
|
|
73
79
|
|
|
74
80
|
# Export the build specification.
|
|
75
|
-
build: list[_Union[int, _JsonObject, str]] = []
|
|
81
|
+
build: list[_Union[int, _JsonObject, str, tuple[str, int]]] = []
|
|
76
82
|
for item in self._build:
|
|
77
|
-
if isinstance(item,
|
|
78
|
-
build.append(item)
|
|
79
|
-
else:
|
|
83
|
+
if isinstance(item, FieldSpec):
|
|
80
84
|
build.append(item.asdict())
|
|
85
|
+
else:
|
|
86
|
+
build.append(item)
|
|
81
87
|
data[BUILD_KEY] = _cast(_JsonObject, build)
|
|
82
88
|
|
|
83
89
|
# Export regular-field values.
|
|
@@ -101,18 +107,16 @@ class JsonProtocol(ProtocolBase):
|
|
|
101
107
|
fields = BitFieldsManager.import_json(data)
|
|
102
108
|
|
|
103
109
|
# Create the build specification.
|
|
104
|
-
build:
|
|
110
|
+
build: ProtocolBuild = []
|
|
105
111
|
for item in data[BUILD_KEY]:
|
|
106
|
-
if isinstance(item,
|
|
107
|
-
build.append(item)
|
|
108
|
-
else:
|
|
112
|
+
if isinstance(item, dict):
|
|
109
113
|
build.append(
|
|
110
114
|
FieldSpec(
|
|
111
|
-
item["name"],
|
|
112
|
-
item["kind"], # type: ignore
|
|
113
|
-
enum=item.get("enum"), # type: ignore
|
|
115
|
+
item["name"], item["kind"], enum=item.get("enum")
|
|
114
116
|
)
|
|
115
117
|
)
|
|
118
|
+
else:
|
|
119
|
+
build.append(item) # type: ignore
|
|
116
120
|
|
|
117
121
|
result = cls(
|
|
118
122
|
fields.enums,
|
|
@@ -121,6 +125,7 @@ class JsonProtocol(ProtocolBase):
|
|
|
121
125
|
build=build,
|
|
122
126
|
identifier=_cast(int, data[META_KEY]["id"]),
|
|
123
127
|
byte_order=_cast(str, data[META_KEY]["byte_order"]),
|
|
128
|
+
alias=data[META_KEY]["alias"], # type: ignore
|
|
124
129
|
)
|
|
125
130
|
|
|
126
131
|
# Set values.
|
|
@@ -101,10 +101,9 @@ class TypeSystem(LoggerMixin):
|
|
|
101
101
|
def register(self, name: str, *namespace: str) -> Protocol:
|
|
102
102
|
"""Register a custom type."""
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
self.
|
|
106
|
-
|
|
107
|
-
)
|
|
104
|
+
resolved = self._name(name, *namespace, check_available=True)
|
|
105
|
+
new_type = Protocol(self._enums, alias=resolved)
|
|
106
|
+
self.custom[resolved] = new_type
|
|
108
107
|
return new_type
|
|
109
108
|
|
|
110
109
|
def get_protocol(
|
|
@@ -146,7 +145,7 @@ class TypeSystem(LoggerMixin):
|
|
|
146
145
|
if field_type_name in self.custom:
|
|
147
146
|
custom.add_serializable(
|
|
148
147
|
field_name,
|
|
149
|
-
self.custom[field_type_name].
|
|
148
|
+
self.custom[field_type_name].copy(),
|
|
150
149
|
array_length=array_length,
|
|
151
150
|
)
|
|
152
151
|
else:
|
|
@@ -227,8 +226,7 @@ class TypeSystem(LoggerMixin):
|
|
|
227
226
|
if found in self.primitives:
|
|
228
227
|
return self.primitives[found].size
|
|
229
228
|
|
|
230
|
-
result = self.custom[found].size
|
|
231
229
|
if trace:
|
|
232
230
|
self.custom[found].trace_size(self.logger)
|
|
233
231
|
|
|
234
|
-
return
|
|
232
|
+
return self.custom[found].length()
|
|
@@ -180,44 +180,50 @@ class PrimitiveArray(Serializable):
|
|
|
180
180
|
|
|
181
181
|
def add_primitive(
|
|
182
182
|
self, kind: _Primitivelike, array_length: int = None
|
|
183
|
-
) ->
|
|
183
|
+
) -> list[_AnyPrimitive]:
|
|
184
184
|
"""Add to the array by specifying the type of element to add."""
|
|
185
|
+
|
|
185
186
|
return self.add(_create(kind), array_length=array_length)
|
|
186
187
|
|
|
187
|
-
def add(
|
|
188
|
+
def add(
|
|
189
|
+
self, primitive: _AnyPrimitive, array_length: int = None
|
|
190
|
+
) -> list[_AnyPrimitive]:
|
|
188
191
|
"""Add another primitive to manage."""
|
|
189
192
|
|
|
193
|
+
result = []
|
|
194
|
+
|
|
190
195
|
end = self.end
|
|
191
196
|
if isinstance(end, PrimitiveArray):
|
|
192
197
|
if end is self:
|
|
193
198
|
self._primitives.append(primitive)
|
|
194
199
|
self._format += primitive.kind.format
|
|
195
200
|
self.size += primitive.size
|
|
201
|
+
result.append(primitive)
|
|
196
202
|
|
|
197
203
|
# Handle array length.
|
|
198
204
|
if array_length is not None:
|
|
199
205
|
for _ in range(array_length - 1):
|
|
206
|
+
inst = primitive.copy()
|
|
200
207
|
self._primitives.append(
|
|
201
|
-
|
|
208
|
+
inst, # type: ignore
|
|
202
209
|
)
|
|
203
|
-
self._format +=
|
|
204
|
-
self.size +=
|
|
210
|
+
self._format += inst.kind.format
|
|
211
|
+
self.size += inst.size
|
|
212
|
+
result.append(inst) # type: ignore
|
|
205
213
|
|
|
206
214
|
# Add tracking information for the current tail.
|
|
207
215
|
curr_idx = len(self._primitives)
|
|
208
216
|
self._bytes_to_index[self.size] = curr_idx
|
|
209
217
|
self._index_to_bytes[curr_idx] = self.size
|
|
210
|
-
result = self.size
|
|
211
218
|
else:
|
|
212
|
-
result
|
|
219
|
+
result.extend(end.add(primitive, array_length=array_length))
|
|
213
220
|
|
|
214
221
|
# Add a new primitive array to the end of this chain for this
|
|
215
222
|
# primitive.
|
|
216
223
|
else:
|
|
217
224
|
new_array = PrimitiveArray(byte_order=self.byte_order)
|
|
218
225
|
end.assign(new_array)
|
|
219
|
-
|
|
220
|
-
result = new_array.add(primitive, array_length=array_length)
|
|
226
|
+
result.extend(new_array.add(primitive, array_length=array_length))
|
|
221
227
|
|
|
222
228
|
return result
|
|
223
229
|
|
|
@@ -245,3 +251,16 @@ class PrimitiveArray(Serializable):
|
|
|
245
251
|
) -> None:
|
|
246
252
|
"""Update a fragment by index."""
|
|
247
253
|
self._fragments[index].update(data, timestamp_ns=timestamp_ns)
|
|
254
|
+
|
|
255
|
+
def randomize(self, timestamp_ns: int = None, chain: bool = True) -> None:
|
|
256
|
+
"""Randomize array contents."""
|
|
257
|
+
|
|
258
|
+
for prim in self._primitives:
|
|
259
|
+
prim.randomize(timestamp_ns=timestamp_ns)
|
|
260
|
+
|
|
261
|
+
if (
|
|
262
|
+
chain
|
|
263
|
+
and self.chain is not None
|
|
264
|
+
and isinstance(self.chain, PrimitiveArray)
|
|
265
|
+
):
|
|
266
|
+
self.chain.randomize(timestamp_ns=timestamp_ns, chain=chain)
|
runtimepy/primitives/bool.py
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
A module implementing a boolean-primitive interface.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
# built-in
|
|
6
|
+
from random import getrandbits
|
|
7
|
+
|
|
5
8
|
# internal
|
|
6
9
|
from runtimepy.primitives.base import Primitive as _Primitive
|
|
7
10
|
from runtimepy.primitives.evaluation import EvalResult, evaluate
|
|
@@ -18,17 +21,21 @@ class BooleanPrimitive(_Primitive[bool]):
|
|
|
18
21
|
"""Initialize this boolean primitive."""
|
|
19
22
|
super().__init__(value=value, **kwargs)
|
|
20
23
|
|
|
21
|
-
def
|
|
24
|
+
def randomize(self, timestamp_ns: int = None) -> None:
|
|
25
|
+
"""Set this primitive to a random integer."""
|
|
26
|
+
self.set_value(bool(getrandbits(1)), timestamp_ns=timestamp_ns)
|
|
27
|
+
|
|
28
|
+
def toggle(self, timestamp_ns: int = None) -> None:
|
|
22
29
|
"""Toggle the underlying value."""
|
|
23
|
-
self.
|
|
30
|
+
self.set_value(not self.raw.value, timestamp_ns=timestamp_ns)
|
|
24
31
|
|
|
25
|
-
def set(self) -> None:
|
|
32
|
+
def set(self, timestamp_ns: int = None) -> None:
|
|
26
33
|
"""Coerce the underlying value to true."""
|
|
27
|
-
self.
|
|
34
|
+
self.set_value(True, timestamp_ns=timestamp_ns)
|
|
28
35
|
|
|
29
|
-
def clear(self) -> None:
|
|
36
|
+
def clear(self, timestamp_ns: int = None) -> None:
|
|
30
37
|
"""Coerce the underlying value to false."""
|
|
31
|
-
self.
|
|
38
|
+
self.set_value(False, timestamp_ns=timestamp_ns)
|
|
32
39
|
|
|
33
40
|
async def wait_for_state(self, state: bool, timeout: float) -> EvalResult:
|
|
34
41
|
"""Wait for this primitive to reach a specified state."""
|
runtimepy/primitives/float.py
CHANGED
|
@@ -4,6 +4,7 @@ A module implementing a floating-point primitive interface.
|
|
|
4
4
|
|
|
5
5
|
# built-in
|
|
6
6
|
import math
|
|
7
|
+
from random import random
|
|
7
8
|
|
|
8
9
|
# internal
|
|
9
10
|
from runtimepy.primitives.evaluation import (
|
|
@@ -27,6 +28,10 @@ class BaseFloatPrimitive(PrimitiveIsCloseMixin[float]):
|
|
|
27
28
|
"""Initialize this floating-point primitive."""
|
|
28
29
|
super().__init__(value=value, scaling=scaling, **kwargs)
|
|
29
30
|
|
|
31
|
+
def randomize(self, timestamp_ns: int = None) -> None:
|
|
32
|
+
"""Set this primitive to a random integer."""
|
|
33
|
+
self.set_value(random(), timestamp_ns=timestamp_ns)
|
|
34
|
+
|
|
30
35
|
def _check_callbacks(self, curr: float, new: float) -> None:
|
|
31
36
|
"""Determine if any callbacks should be serviced."""
|
|
32
37
|
|
runtimepy/primitives/int.py
CHANGED
|
@@ -33,6 +33,14 @@ class BaseIntPrimitive(PrimitiveIsCloseMixin[int]):
|
|
|
33
33
|
|
|
34
34
|
super().__init__(value=value, scaling=scaling, **kwargs)
|
|
35
35
|
|
|
36
|
+
def randomize(self, timestamp_ns: int = None) -> None:
|
|
37
|
+
"""Set this primitive to a random integer."""
|
|
38
|
+
|
|
39
|
+
assert self.kind.int_bounds is not None
|
|
40
|
+
self.set_value(
|
|
41
|
+
self.kind.int_bounds.random(), timestamp_ns=timestamp_ns
|
|
42
|
+
)
|
|
43
|
+
|
|
36
44
|
def increment(self, amount: int = 1, timestamp_ns: int = None) -> int:
|
|
37
45
|
"""Increment this primitive by some amount and return the new value."""
|
|
38
46
|
|
|
@@ -7,5 +7,5 @@ from runtimepy.primitives.serializable.base import Serializable
|
|
|
7
7
|
from runtimepy.primitives.serializable.fixed import FixedChunk
|
|
8
8
|
from runtimepy.primitives.serializable.prefixed import PrefixedChunk
|
|
9
9
|
|
|
10
|
-
SerializableMap = dict[str, Serializable]
|
|
10
|
+
SerializableMap = dict[str, list[Serializable]]
|
|
11
11
|
__all__ = ["Serializable", "SerializableMap", "FixedChunk", "PrefixedChunk"]
|
|
@@ -5,6 +5,7 @@ A module defining a base interface fore serializable objects.
|
|
|
5
5
|
# built-in
|
|
6
6
|
from abc import ABC, abstractmethod
|
|
7
7
|
from copy import copy as _copy
|
|
8
|
+
from io import BytesIO as _BytesIO
|
|
8
9
|
from typing import BinaryIO as _BinaryIO
|
|
9
10
|
from typing import TypeVar
|
|
10
11
|
|
|
@@ -46,10 +47,17 @@ class Serializable(ABC):
|
|
|
46
47
|
result += self.chain.length()
|
|
47
48
|
return result
|
|
48
49
|
|
|
49
|
-
def
|
|
50
|
+
def resolve_alias(self, alias: str = None) -> str:
|
|
51
|
+
"""Resolve a possible alias string."""
|
|
52
|
+
|
|
53
|
+
if not alias:
|
|
54
|
+
alias = getattr(self, "alias") or self.__class__.__name__
|
|
55
|
+
return alias
|
|
56
|
+
|
|
57
|
+
def length_trace(self, alias: str = None) -> str:
|
|
50
58
|
"""Get a length-tracing string for this instance."""
|
|
51
59
|
|
|
52
|
-
current = f"{self.
|
|
60
|
+
current = f"{self.resolve_alias(alias=alias)}({self.size})"
|
|
53
61
|
if self.chain is not None:
|
|
54
62
|
current += " -> " + self.chain.length_trace()
|
|
55
63
|
return current
|
|
@@ -71,7 +79,6 @@ class Serializable(ABC):
|
|
|
71
79
|
"""A method for copying instances without chain references."""
|
|
72
80
|
|
|
73
81
|
orig = self._copy_impl()
|
|
74
|
-
assert orig.chain is None
|
|
75
82
|
orig.byte_order = self.byte_order
|
|
76
83
|
return orig
|
|
77
84
|
|
|
@@ -80,7 +87,7 @@ class Serializable(ABC):
|
|
|
80
87
|
|
|
81
88
|
result = self.copy_without_chain()
|
|
82
89
|
|
|
83
|
-
if self.chain is not None:
|
|
90
|
+
if self.chain is not None and result.chain is None:
|
|
84
91
|
result.assign(self.chain.copy())
|
|
85
92
|
|
|
86
93
|
return result
|
|
@@ -104,6 +111,27 @@ class Serializable(ABC):
|
|
|
104
111
|
|
|
105
112
|
return result
|
|
106
113
|
|
|
114
|
+
def chain_bytes(self) -> bytes:
|
|
115
|
+
"""Get the fully encoded chain."""
|
|
116
|
+
with _BytesIO() as stream:
|
|
117
|
+
self.to_stream(stream)
|
|
118
|
+
return stream.getvalue()
|
|
119
|
+
|
|
120
|
+
def __eq__(self, other) -> bool:
|
|
121
|
+
"""Equivalent if full byte chains are equal."""
|
|
122
|
+
|
|
123
|
+
result = False
|
|
124
|
+
if isinstance(other, Serializable):
|
|
125
|
+
result = self.chain_bytes() == other.chain_bytes()
|
|
126
|
+
return result
|
|
127
|
+
|
|
128
|
+
def update_with(self: T, other: T, timestamp_ns: int = None) -> int:
|
|
129
|
+
"""Update this instance from another of the same type."""
|
|
130
|
+
|
|
131
|
+
return self.update_chain(
|
|
132
|
+
other.chain_bytes(), timestamp_ns=timestamp_ns
|
|
133
|
+
)
|
|
134
|
+
|
|
107
135
|
@abstractmethod
|
|
108
136
|
def update(self, data: bytes, timestamp_ns: int = None) -> int:
|
|
109
137
|
"""Update this serializable from a bytes instance."""
|
|
@@ -130,32 +158,39 @@ class Serializable(ABC):
|
|
|
130
158
|
|
|
131
159
|
return result
|
|
132
160
|
|
|
133
|
-
def
|
|
161
|
+
def update_chain(self, data: bytes, timestamp_ns: int = None) -> int:
|
|
162
|
+
"""Update this serializable from a bytes instance."""
|
|
163
|
+
|
|
164
|
+
with _BytesIO(data) as stream:
|
|
165
|
+
return self.from_stream(stream, timestamp_ns=timestamp_ns)
|
|
166
|
+
|
|
167
|
+
def assign(self, chain: T) -> None:
|
|
134
168
|
"""Assign a next serializable."""
|
|
135
169
|
|
|
136
170
|
assert self.chain is None, self.chain
|
|
137
|
-
|
|
138
171
|
# mypy regression?
|
|
139
172
|
self.chain = chain # type: ignore
|
|
140
|
-
assert self.chain is not None
|
|
141
|
-
|
|
142
|
-
return self.chain.size
|
|
143
173
|
|
|
144
|
-
def add_to_end(self, chain: T, array_length: int = None) ->
|
|
174
|
+
def add_to_end(self, chain: T, array_length: int = None) -> list[T]:
|
|
145
175
|
"""Add a new serializable to the end of this chain."""
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
177
|
+
result = []
|
|
178
|
+
|
|
179
|
+
# Copy the chain element before it becomes part of the current chain if
|
|
180
|
+
# an array is created.
|
|
149
181
|
copy_base = None
|
|
150
182
|
if array_length is not None:
|
|
151
183
|
copy_base = chain.copy()
|
|
152
184
|
|
|
153
|
-
|
|
185
|
+
self.end.assign(chain)
|
|
186
|
+
result.append(chain)
|
|
154
187
|
|
|
155
188
|
# Add additional array elements as copies.
|
|
156
189
|
if array_length is not None:
|
|
157
190
|
assert copy_base is not None
|
|
158
191
|
for _ in range(array_length - 1):
|
|
159
|
-
|
|
192
|
+
inst = copy_base.copy()
|
|
193
|
+
self.end.assign(inst)
|
|
194
|
+
result.append(inst)
|
|
160
195
|
|
|
161
|
-
return
|
|
196
|
+
return result
|
|
@@ -4,6 +4,7 @@ bounds (based on bit width).
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
# built-in
|
|
7
|
+
from random import randint
|
|
7
8
|
from typing import NamedTuple
|
|
8
9
|
|
|
9
10
|
|
|
@@ -13,6 +14,10 @@ class IntegerBounds(NamedTuple):
|
|
|
13
14
|
min: int
|
|
14
15
|
max: int
|
|
15
16
|
|
|
17
|
+
def random(self) -> int:
|
|
18
|
+
"""Get a random integer."""
|
|
19
|
+
return randint(self.min, self.max)
|
|
20
|
+
|
|
16
21
|
def validate(self, val: int) -> bool:
|
|
17
22
|
"""Determine if the value is within bounds."""
|
|
18
23
|
return self.min <= val <= self.max
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.11.1
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/vkottler/runtimepy
|
|
6
6
|
Author: Vaughn Kottler
|
|
@@ -18,10 +18,10 @@ Requires-Python: >=3.12
|
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
20
|
Requires-Dist: psutil
|
|
21
|
-
Requires-Dist: websockets
|
|
22
|
-
Requires-Dist: aiofiles
|
|
23
21
|
Requires-Dist: vcorelib>=3.5.1
|
|
22
|
+
Requires-Dist: aiofiles
|
|
24
23
|
Requires-Dist: svgen>=0.7.4
|
|
24
|
+
Requires-Dist: websockets
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint; extra == "test"
|
|
27
27
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -50,11 +50,11 @@ Dynamic: requires-python
|
|
|
50
50
|
=====================================
|
|
51
51
|
generator=datazen
|
|
52
52
|
version=3.1.4
|
|
53
|
-
hash=
|
|
53
|
+
hash=4ef876633bf905b103835e81db45e721
|
|
54
54
|
=====================================
|
|
55
55
|
-->
|
|
56
56
|
|
|
57
|
-
# runtimepy ([5.
|
|
57
|
+
# runtimepy ([5.11.1](https://pypi.org/project/runtimepy/))
|
|
58
58
|
|
|
59
59
|
[](https://pypi.org/project/runtimepy/)
|
|
60
60
|

|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
runtimepy/__init__.py,sha256=
|
|
1
|
+
runtimepy/__init__.py,sha256=jnVk66eyyfxqRlrnXybadQhrpwK0h8K50mULrq-N3xg,391
|
|
2
2
|
runtimepy/__main__.py,sha256=OPAed6hggoQdw-6QAR62mqLC-rCkdDhOq0wyeS2vDRI,332
|
|
3
3
|
runtimepy/app.py,sha256=sTvatbsGZ2Hdel36Si_WUbNMtg9CzsJyExr5xjIcxDE,970
|
|
4
4
|
runtimepy/dev_requirements.txt,sha256=j0dh11ztJAzfaUL0iFheGjaZj9ppDzmTkclTT8YKO8c,230
|
|
@@ -11,23 +11,23 @@ runtimepy/util.py,sha256=GuyIHVFGMS02OR6-O3LnlV3DqG5hj4-IUud0QM6WicA,1684
|
|
|
11
11
|
runtimepy/channel/__init__.py,sha256=pf0RJ5g37_FVV8xoUNgzFGuIfbZEYSBA_cQlJSDTPDo,4774
|
|
12
12
|
runtimepy/channel/registry.py,sha256=nk36qM_Bf6qK6AFR0plaZHR1PU7b4LZqbQ0feJqk4lc,4784
|
|
13
13
|
runtimepy/channel/environment/__init__.py,sha256=0Jj8g7Y4bdDvmWtzpegB9D4milGPhsZokoYxmps5zgU,1612
|
|
14
|
-
runtimepy/channel/environment/array.py,sha256=
|
|
14
|
+
runtimepy/channel/environment/array.py,sha256=f9cWaYsRXUw8qE629h6jQxbYKDpOwC2GLBo4QaMa1JM,3748
|
|
15
15
|
runtimepy/channel/environment/base.py,sha256=tpD_6OHJv1bpfXmfFCNckoNo8ATOOi-XX66NQrkSNYU,14331
|
|
16
16
|
runtimepy/channel/environment/create.py,sha256=DHjoNmzZsARjfB_CfutXQ1PDdxPETi6yQoRMhM0FbwA,5319
|
|
17
17
|
runtimepy/channel/environment/file.py,sha256=PV05KZ3-CvftbKUM8acQmawOMeGGCcMrEESEBuymykg,6949
|
|
18
18
|
runtimepy/channel/environment/sample.py,sha256=Geinp2Q_qYkzYKpUJroepv6A4JWypUnAPl57jn_r_R4,4976
|
|
19
|
-
runtimepy/channel/environment/telemetry.py,sha256=
|
|
19
|
+
runtimepy/channel/environment/telemetry.py,sha256=3A7Xcp-4eHJWz_oR1SnI6rsl4o8wiSUaiMHrnK1IaQ8,5338
|
|
20
20
|
runtimepy/channel/environment/command/__init__.py,sha256=mymqk5roA-7evUovXlD2dmWaprSzrPb_3ae6bA9oEZ0,8162
|
|
21
21
|
runtimepy/channel/environment/command/parser.py,sha256=cMOsEsXnfFlATiWTNSxlgvc_XoICsJlcZigFJlQ47tk,1804
|
|
22
22
|
runtimepy/channel/environment/command/processor.py,sha256=NiiWRdwBHOFEisjqNOW5oawprxcpR25ONNABoZpELdg,7122
|
|
23
23
|
runtimepy/channel/environment/command/result.py,sha256=Ko5lK4d04Z266WuCi2sHQItbUHJFYv7qUdrDi-OVKOU,624
|
|
24
|
-
runtimepy/channel/event/__init__.py,sha256=
|
|
24
|
+
runtimepy/channel/event/__init__.py,sha256=9LCSNa1Iiwr6Q6JkwQGELDQ7rWfU_xjAMh6qM1I-ueM,2793
|
|
25
25
|
runtimepy/channel/event/header.py,sha256=eDRZgzzM5HZQ8QtV4DjyAsrAhEZyM7IfwqK6WB5ACEw,868
|
|
26
26
|
runtimepy/codec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
-
runtimepy/codec/protocol/__init__.py,sha256=
|
|
28
|
-
runtimepy/codec/protocol/base.py,sha256
|
|
29
|
-
runtimepy/codec/protocol/json.py,sha256=
|
|
30
|
-
runtimepy/codec/system/__init__.py,sha256=
|
|
27
|
+
runtimepy/codec/protocol/__init__.py,sha256=Rg7RSKGn2UBpGMpwq1aCLUBA5h4pORdh53NfR7Cjw0U,1530
|
|
28
|
+
runtimepy/codec/protocol/base.py,sha256=NRLB1ld0oB2IED5QRkwDwYsnHFG8gKtg3T7OHJ9_VkQ,10432
|
|
29
|
+
runtimepy/codec/protocol/json.py,sha256=oiaJLCzptJ5uajnpO8EDYET8gIspZIrVuyLjLuAC5dw,4142
|
|
30
|
+
runtimepy/codec/system/__init__.py,sha256=1Yy4RkNoh8tf6MTKZO1EszlCnE6jTevN2du4LU_-vxw,6933
|
|
31
31
|
runtimepy/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
runtimepy/commands/all.py,sha256=jH2dsmkqyBFe_2ZlPFpko0UCMW3fFfJsuGIbeJFbDoQ,1619
|
|
33
33
|
runtimepy/commands/arbiter.py,sha256=CtTMRYpqCAN3vWHkkr9jqWpoF7JGNXafKIBFmkarAfc,1567
|
|
@@ -222,7 +222,7 @@ runtimepy/net/udp/connection.py,sha256=Hv963vT9tnglpZOx4KUFuoYTBPr2rltYQWDNV3mhY
|
|
|
222
222
|
runtimepy/net/udp/create.py,sha256=84YDfJbNBlN0ZwbNpvh6Dl7ZPecbZfmpjMNRRWcvJDk,2005
|
|
223
223
|
runtimepy/net/udp/protocol.py,sha256=A4SRHf0CgcL2zDs1nAsGDqz0RxKBy1soS8wtNdS5S0I,1492
|
|
224
224
|
runtimepy/net/udp/queue.py,sha256=DF-YscxQcGbGCYQLz_l_BMaSRfraZOhRwieTEdXLMds,637
|
|
225
|
-
runtimepy/net/udp/tftp/__init__.py,sha256=
|
|
225
|
+
runtimepy/net/udp/tftp/__init__.py,sha256=lR8_bFo8ECHMQygWsmbnNpsLqmwu6818k-cjKRE57yk,8983
|
|
226
226
|
runtimepy/net/udp/tftp/base.py,sha256=vpvjitZSD8R4Ggb21eIMNIsm54VkLBbBrTgMo65gn2o,11331
|
|
227
227
|
runtimepy/net/udp/tftp/endpoint.py,sha256=so60LdPTG66N5tdhHhiX7j_TBHvNOTi4JIgLcg2MAm0,10890
|
|
228
228
|
runtimepy/net/udp/tftp/enums.py,sha256=06juMd__pJZsyL8zO8p3hRucnOratt1qtz9zcxzMg4s,1579
|
|
@@ -232,27 +232,27 @@ runtimepy/net/websocket/connection.py,sha256=BMR58bLpHuulCdbLGnmMdFJOF53wVxYcUe5
|
|
|
232
232
|
runtimepy/noise/__init__.py,sha256=EJM7h3t_z74wwrn6FAFQwYE2yUcOZQ1K1IQqOb8Z0AI,384
|
|
233
233
|
runtimepy/primitives/__init__.py,sha256=nwWJH1e0KN2NsVwQ3wvRtUpl9s9Ap8Q32NNZLGol0wU,2323
|
|
234
234
|
runtimepy/primitives/base.py,sha256=BaGPUTeVMnLnTPcpjqnS2lzPN74Pe5C0XaQdgrTfW7A,9185
|
|
235
|
-
runtimepy/primitives/bool.py,sha256=
|
|
235
|
+
runtimepy/primitives/bool.py,sha256=lATPgb1e62rjLn5XlJX8lP3tVYR3DlxV8RT9HpOMdT0,1640
|
|
236
236
|
runtimepy/primitives/byte_order.py,sha256=80mMk1Sj_l49XvAtvrPmoYFpFYSM1HgYuwR2-P7os3Q,767
|
|
237
237
|
runtimepy/primitives/evaluation.py,sha256=0N7mT8uoiJaY-coF2PeEXU2WO-FmbyN2Io9_EaghO9Q,4657
|
|
238
|
-
runtimepy/primitives/float.py,sha256=
|
|
239
|
-
runtimepy/primitives/int.py,sha256=
|
|
238
|
+
runtimepy/primitives/float.py,sha256=6vzNKnnLzzM4vP10V4E0PHZQH6vTvIl34pId1oFtlqc,2146
|
|
239
|
+
runtimepy/primitives/int.py,sha256=Ia2vtzXXfBb8fj1mgwu_PFpblrL2qzsN4Qwjvk5NhT4,3618
|
|
240
240
|
runtimepy/primitives/scaling.py,sha256=Vtxp2CSBahqPp4i2-IS4wjbcC023xwf-dqZMbYWf3V4,1144
|
|
241
241
|
runtimepy/primitives/string.py,sha256=ic5VKhXCSIwEOUfqIb1VUpZPwjdAcBul-cLLIihVkQI,2532
|
|
242
|
-
runtimepy/primitives/array/__init__.py,sha256=
|
|
242
|
+
runtimepy/primitives/array/__init__.py,sha256=ZVJt4810hTFYMdolY_R75lRRHHaNKxZ4comBvuK_69E,8956
|
|
243
243
|
runtimepy/primitives/field/__init__.py,sha256=iHZSQBozMpfiv_5KE_GIX1FAvDB9unUO0xmWZHiA_Jk,4491
|
|
244
244
|
runtimepy/primitives/field/fields.py,sha256=jDNi1tl2Xc3GBmt6QJuqxbhP8MtxgertGbPFmDXa7b4,7481
|
|
245
245
|
runtimepy/primitives/field/manager/__init__.py,sha256=BCRi6-_5OOJ8kz78JHkiLp8cZ71KA1uiF2zq5FFe9js,2586
|
|
246
246
|
runtimepy/primitives/field/manager/base.py,sha256=EyWs5D9_reKOTLkh8PuW45ySjCh31fY_qrtFIcmIOV4,6914
|
|
247
|
-
runtimepy/primitives/serializable/__init__.py,sha256=
|
|
248
|
-
runtimepy/primitives/serializable/base.py,sha256=
|
|
247
|
+
runtimepy/primitives/serializable/__init__.py,sha256=R9_derxnK1OCaYyqBZA4CCjPkXCBw6InkE8-3Zy75Uk,399
|
|
248
|
+
runtimepy/primitives/serializable/base.py,sha256=EIj7Ao0sZaXCXgZari35kimjkr3SzFWGy3rNjxgsv1E,5727
|
|
249
249
|
runtimepy/primitives/serializable/fixed.py,sha256=rhr6uVbo0Lvazk4fLI7iei-vVNEwP1J8-LoUjW1NaMI,1077
|
|
250
250
|
runtimepy/primitives/serializable/framer.py,sha256=rsoGQz6vD7v_EMu67aqxVqbvmbs6hjytXZ8dHLBM0SQ,1815
|
|
251
251
|
runtimepy/primitives/serializable/prefixed.py,sha256=oQXW0pGRovKolheL5ZL2m9aNVMCtKTAi5OlC9KW0iKI,2855
|
|
252
252
|
runtimepy/primitives/types/__init__.py,sha256=JUJpDFIjDUYo-Jnx5sZnkmbGLVjIHVsRcvBjVlJ7fsA,1588
|
|
253
253
|
runtimepy/primitives/types/base.py,sha256=rR1JkExMV2FJmvU-WfgnikG-UtFfsXGs_eBCIV6II1A,4879
|
|
254
254
|
runtimepy/primitives/types/bool.py,sha256=J0SYdp-9eIRs337d9qnw2f7IXTPQj_F21ugMIJ8-Hy4,547
|
|
255
|
-
runtimepy/primitives/types/bounds.py,sha256=
|
|
255
|
+
runtimepy/primitives/types/bounds.py,sha256=Hc2GWu4qJMEAF8IiDWFA_6VCNUtrNf5RmiEbSJ76dJI,1145
|
|
256
256
|
runtimepy/primitives/types/float.py,sha256=yjiU1AGzekY8PjDcLNdoXMGDsdP5aDYWjLb3_RntRpA,1388
|
|
257
257
|
runtimepy/primitives/types/int.py,sha256=Gjro7RgPL1girVVXhvDErvRwxlfHclMr7tZEFYj-Uj4,3807
|
|
258
258
|
runtimepy/registry/__init__.py,sha256=NpMxvdmjRtE3jCCOuYU_CPpYWqCZ5byXWhJNTB6jZUk,3425
|
|
@@ -285,9 +285,9 @@ runtimepy/tui/task.py,sha256=nUZo9fuOC-k1Wpqdzkv9v1tQirCI28fZVgcC13Ijvus,1093
|
|
|
285
285
|
runtimepy/tui/channels/__init__.py,sha256=evDaiIn-YS9uGhdo8ZGtP9VK1ek6sr_P1nJ9JuSET0o,4536
|
|
286
286
|
runtimepy/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
287
287
|
runtimepy/ui/controls.py,sha256=yvT7h3thbYaitsakcIAJ90EwKzJ4b-jnc6p3UuVf_XE,1241
|
|
288
|
-
runtimepy-5.
|
|
289
|
-
runtimepy-5.
|
|
290
|
-
runtimepy-5.
|
|
291
|
-
runtimepy-5.
|
|
292
|
-
runtimepy-5.
|
|
293
|
-
runtimepy-5.
|
|
288
|
+
runtimepy-5.11.1.dist-info/licenses/LICENSE,sha256=yKBRwbO-cOPBrlpsZmJkkSa33DfY31aE8t7lZ0DwlUo,1071
|
|
289
|
+
runtimepy-5.11.1.dist-info/METADATA,sha256=nTdV1gy7arFtuBI5Y-yZvzR5mao4DJwlu2dgKv14ra4,9395
|
|
290
|
+
runtimepy-5.11.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
291
|
+
runtimepy-5.11.1.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
|
|
292
|
+
runtimepy-5.11.1.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
|
|
293
|
+
runtimepy-5.11.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|