protobin 0.0.41__tar.gz → 0.0.43__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: protobin
3
- Version: 0.0.41
3
+ Version: 0.0.43
4
4
  Summary: Python library for encode and decode data in protobin format
5
5
  Project-URL: Homepage, https://github.com/drmelectronic/protobin-python
6
6
  Project-URL: Bug Tracker, https://github.com/drmelectronic/protobin-python/issues
@@ -106,7 +106,7 @@ class ArrayField(FieldBase):
106
106
 
107
107
  def to_binary(self, val):
108
108
  if not isinstance(val, (list, tuple)):
109
- raise ValueError(f'Error in field "{self.key}", a array is expected but "{val}" is received, {type(val)}')
109
+ raise ValueError(f'Error in field ArrayField<{self.key}>, a array is expected but "{val}" is received, {type(val)}')
110
110
  binary = b''
111
111
  length = len(val)
112
112
  binary += length.to_bytes(1, 'big')
@@ -135,7 +135,7 @@ class BitsField(FieldBase):
135
135
  self.bytes = math.ceil(self.length / 8)
136
136
 
137
137
  def __repr__(self):
138
- return f'BitsFIeld<key: {self.key}, length: {self.length}, bytes: {self.bytes}>'
138
+ return f'BitsField<key: {self.key}, length: {self.length}, bytes: {self.bytes}>'
139
139
 
140
140
  def decode(self, binary):
141
141
  self.ensure_length(binary)
@@ -215,7 +215,14 @@ class CharField(FieldBase):
215
215
  def to_binary(self, val):
216
216
  if val is None:
217
217
  return bytes([0])
218
- return (val + ' '*self.bytes)[:self.bytes].encode('utf')
218
+ encoded = val[:self.bytes].encode('utf')
219
+ if self.bytes == 1 and len(encoded) > 1:
220
+ raise ValueError(f'{self} of one byte is possible to encode a utf-8 character')
221
+ i = 0
222
+ while len(encoded) > self.bytes:
223
+ i += 1
224
+ encoded = val[:self.bytes - i].encode('utf')
225
+ return (encoded + b' ' * self.bytes)[:self.bytes]
219
226
 
220
227
  def from_binary(self, binary):
221
228
  val = int.from_bytes(binary[:self.bytes], 'big', signed=False)
@@ -270,7 +277,7 @@ class DateTimeField(FieldBase):
270
277
  if val is None:
271
278
  return bytes([0] * 6)
272
279
  elif not isinstance(val, datetime.datetime):
273
- raise ValueError(f'Error in field "{self.key}", a datetime is expected but "{val}" is received')
280
+ raise ValueError(f'Error in field DateTimeField<{self.key}>, a datetime is expected but "{val}" is received')
274
281
  elif isinstance(val, str):
275
282
  val = datetime.datetime.strptime(val, '%Y-%m-%d %H:%M:%S').date()
276
283
  return bytes([
@@ -326,7 +333,7 @@ class FlagsField(FieldBase):
326
333
  for k in self.keys:
327
334
  val = data.get(k)
328
335
  if val is None:
329
- raise ValueError(f'Error in field "{self.key}", a boolean is expected but "None" is received')
336
+ raise ValueError(f'Error in field FlagsField<{self.key}>, a boolean is expected but "None" is received')
330
337
  bits += '1' if data[k] else '0'
331
338
  return int(bits, 2).to_bytes(self.bytes, 'big', signed=False)
332
339
 
@@ -335,9 +342,11 @@ class FloatField(FieldBase):
335
342
 
336
343
  def __init__(self, k, js):
337
344
  super().__init__(k, js)
338
- self.decimals = js['decimals']
345
+ self.decimals = js.get('decimals', None)
339
346
  if self.bytes == None:
340
- raise ValueError(f'FloatField {self.key} needs to have bytes declared')
347
+ raise ValueError(f'FloatField<{self.key}> needs to have bytes declared')
348
+ if self.decimals == None:
349
+ raise ValueError(f'FloatField<{self.key}> needs to have decimals declared')
341
350
 
342
351
  def __repr__(self):
343
352
  return f'FloatField<key: {self.key}, bytes: {self.bytes}, decimals: {self.decimals}>'
@@ -361,7 +370,7 @@ class IdField(FieldBase):
361
370
  max_value = 256 ** self.bytes - 1
362
371
  val = min(val, max_value)
363
372
  if val < 0:
364
- raise ValueError('Negative values not allowed')
373
+ raise ValueError('IdField<{self.key}> does not allow negative values')
365
374
  return int(val).to_bytes(self.bytes, 'big', signed=False)
366
375
 
367
376
  def from_binary(self, binary):
@@ -401,7 +410,7 @@ class StringField(FieldBase):
401
410
  try:
402
411
  return binary.decode('utf')
403
412
  except UnicodeEncodeError:
404
- raise DecodeError(f"Can't decode string: {binary}")
413
+ raise DecodeError(f"{self}: Can't decode string: {binary}")
405
414
 
406
415
  def split(self, binary):
407
416
  if self.bytes:
@@ -441,10 +450,10 @@ class TimeField(FieldBase):
441
450
  else:
442
451
  val = datetime.datetime.strptime(val, '%H:%M').time()
443
452
  except:
444
- raise ValueError(f'Error in field "{self.key}", a datetime or time is expected but "{val}" is received')
453
+ raise ValueError(f'Error in field TimeField<{self.key}>, a datetime or time is expected but "{val}" is received')
445
454
 
446
455
  elif not isinstance(val, datetime.datetime) and not isinstance(val, datetime.time):
447
- raise ValueError(f'Error in field "{self.key}", a datetime or time is expected but "{val}" is received')
456
+ raise ValueError(f'Error in field TimeField<{self.key}>, a datetime or time is expected but "{val}" is received')
448
457
 
449
458
  return bytes([
450
459
  self.to_nible(val.hour),
@@ -495,11 +504,11 @@ class UnsignedField(FieldBase):
495
504
 
496
505
  def to_binary(self, val):
497
506
  if val is None:
498
- raise ValueError(f'Error in field "{self.key}", None is not allowed')
507
+ raise ValueError(f'Error in field UnsignedField<{self.key}>, None is not allowed')
499
508
  max_value = 256 ** self.bytes - 1
500
509
  val = min(val, max_value)
501
510
  if val < 0:
502
- raise ValueError(f'Error in field "{self.key}", positive integers expected but "{val}" is received')
511
+ raise ValueError(f'Error in field UnsignedField<{self.key}>, positive integers expected but "{val}" is received')
503
512
  return int(val).to_bytes(self.bytes, 'big', signed=False)
504
513
 
505
514
  def from_binary(self, binary):
@@ -13,6 +13,5 @@ class ProtobinLoader(object):
13
13
  def get(self, path, server):
14
14
  key = f'{path}|{server}'
15
15
  if key not in self.protocols:
16
- print('load protocol', path, server)
17
16
  self.protocols[key] = Protocol(file=path, server=server)
18
17
  return self.protocols[key]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "protobin"
7
- version = "0.0.41"
7
+ version = "0.0.43"
8
8
  authors = [
9
9
  { name="Daniel Robles", email="drm.electronic@gmail.com" },
10
10
  ]
@@ -112,7 +112,7 @@ class BasicTest(unittest.TestCase):
112
112
  },
113
113
  'float': {
114
114
  "header": "f",
115
- "fields": {'test': {'bytes': 4, 'decimals': 6, 'type': 'float'}}
115
+ "fields": {'test': {'bytes': 4, 'type': 'float', 'decimals': 6}}
116
116
  },
117
117
  'id': {
118
118
  "header": "i",
@@ -202,6 +202,13 @@ class BasicTest(unittest.TestCase):
202
202
  h, recv = self.protocol.decode(binary)
203
203
  self.assertEqual(data, recv)
204
204
 
205
+ def test_char_utf(self):
206
+ data = {'test': 'ñ'}
207
+ binary = self.protocol.encode(data, 'char')
208
+ print('binary', binary)
209
+ h, recv = self.protocol.decode(binary)
210
+ self.assertEqual(data, recv)
211
+
205
212
  def test_char2(self):
206
213
  data = {'test': 'FA', 'prueba': 'DO'}
207
214
  binary = self.protocol.encode(data, 'char2')
@@ -215,6 +222,30 @@ class BasicTest(unittest.TestCase):
215
222
  self.assertEqual(data_corregida, recv)
216
223
  print(recv)
217
224
 
225
+ def test_char2_utf(self):
226
+ data = {'test': 'FA', 'prueba': 'ÑA'}
227
+ binary = self.protocol.encode(data, 'char2')
228
+ h, recv = self.protocol.decode(binary)
229
+ data['prueba'] = 'Ñ'
230
+ self.assertEqual(data, recv)
231
+ data = {'test': '', 'prueba': 'SÍ'}
232
+ binary = self.protocol.encode(data, 'char2')
233
+ print(binary)
234
+ h, recv = self.protocol.decode(binary)
235
+ data['prueba'] ='S '
236
+ data['test'] =' '
237
+ self.assertEqual(data, recv)
238
+ print(recv)
239
+ data = {'test': 'ÉL', 'prueba': 'NO'}
240
+ binary = self.protocol.encode(data, 'char2')
241
+ print(binary)
242
+ h, recv = self.protocol.decode(binary)
243
+ data['test'] ='É'
244
+ self.assertEqual(data, recv)
245
+ print(recv)
246
+
247
+
248
+
218
249
  def test_date(self):
219
250
  data = {'test': datetime.date(2024, 9, 13)}
220
251
  binary = self.protocol.encode(data, 'date')
@@ -273,6 +304,10 @@ class BasicTest(unittest.TestCase):
273
304
  def test_float(self):
274
305
  data = {'test': -11.659812}
275
306
  binary = self.protocol.encode(data, 'float')
307
+ h, recv = self.protocol.decode(binary)
308
+ self.assertEqual(data, recv)
309
+ data = {'test': 0}
310
+ binary = self.protocol.encode(data, 'float')
276
311
  print(binary)
277
312
  h, recv = self.protocol.decode(binary)
278
313
  self.assertEqual(data, recv)
@@ -340,6 +375,11 @@ class BasicTest(unittest.TestCase):
340
375
  binary = self.protocol.encode(data, 'string')
341
376
  h, recv = self.protocol.decode(binary)
342
377
  self.assertEqual(data, recv)
378
+ data = {'test': 'ñandú'}
379
+ binary = self.protocol.encode(data, 'string')
380
+ h, recv = self.protocol.decode(binary)
381
+ print('binary', binary)
382
+ self.assertEqual(data, recv)
343
383
 
344
384
  def test_timestamp(self):
345
385
  data = {'test': datetime.datetime(2024, 9, 13, 15, 23, 51, 265981)}
@@ -810,4 +850,4 @@ report:
810
850
  rasp = b'$=\t\x00\x02\x08\xfbh\xd6\xb9\xffG\xef\xf2\x00F\x02\x07FINAL \x01s\x91\xb0\x90\x96+\x00\x05\x02\xfbg\xe4\xf2\xffH!d\x00F\x02\x07UNIVERITARIA \x01s\x91\xb0\x90\xb6+\x00\x06\x03\xfbhL\x0b\xffH,`\x00F\x02\x07CARCAMO \x01s\x91\xb0\x90\xc0+\x00\x07\x04\xfbhh\xf6\xffH/D\x00F\x02\x072 DE MAYO \x01s\x91\xb0\x90\xc8+\x00\x08\x05\xfbh\x88\x04\xffH\x1d<\x00F\x02\x07PLAZA SAN MARTI\x01s\x91\xb0\x90\xd0+\x00\r\x04\xfbh\x9e\n\xffH\x0f7\x00F\x02\x0fABANCAY \x01s\x91\xb0\x90\xf9+\x00\x0e\x05\xfbh\x8e\x12\xffH\x19\xca\x00F\x02\x0fPLAZA SAN MARTI\x01s\x91\xb0\x91\x01+\x00\x0f\x06\xfbhn\x1e\xffH.\x8d\x00F\x02\x0f2 DE MAYO \x01s\x91\xb0\x91\t+\x00\x11\t\xfbg\xb7t\xffH$\xcb\x00F\x02\x0fTERMINAL \x01s\x91\xb0\x91\x1a+P'
811
851
  self.assertEqual(binary, rasp)
812
852
  h, recv = client.decode(binary)
813
- print(recv)
853
+ print(recv)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes