soia-client 1.1.9__tar.gz → 1.1.18__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.
Files changed (35) hide show
  1. {soia_client-1.1.9/soia_client.egg-info → soia_client-1.1.18}/PKG-INFO +1 -1
  2. {soia_client-1.1.9 → soia_client-1.1.18}/pyproject.toml +1 -1
  3. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/arrays.py +2 -2
  4. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/enums.py +3 -3
  5. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/primitives.py +24 -10
  6. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/structs.py +11 -12
  7. {soia_client-1.1.9 → soia_client-1.1.18/soia_client.egg-info}/PKG-INFO +1 -1
  8. {soia_client-1.1.9 → soia_client-1.1.18}/tests/test_serializers.py +16 -0
  9. {soia_client-1.1.9 → soia_client-1.1.18}/LICENSE +0 -0
  10. {soia_client-1.1.9 → soia_client-1.1.18}/README.md +0 -0
  11. {soia_client-1.1.9 → soia_client-1.1.18}/setup.cfg +0 -0
  12. {soia_client-1.1.9 → soia_client-1.1.18}/soia/__init__.py +0 -0
  13. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/__init__.py +0 -0
  14. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/binary.py +0 -0
  15. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/function_maker.py +0 -0
  16. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/keep.py +0 -0
  17. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/keyed_items.py +0 -0
  18. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/method.py +0 -0
  19. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/never.py +0 -0
  20. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/optionals.py +0 -0
  21. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/repr.py +0 -0
  22. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/serializer.py +0 -0
  23. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/serializers.py +0 -0
  24. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/service.py +0 -0
  25. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/service_client.py +0 -0
  26. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/timestamp.py +0 -0
  27. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_impl/type_adapter.py +0 -0
  28. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_module_initializer.py +0 -0
  29. {soia_client-1.1.9 → soia_client-1.1.18}/soia/_spec.py +0 -0
  30. {soia_client-1.1.9 → soia_client-1.1.18}/soia/reflection.py +4 -4
  31. {soia_client-1.1.9 → soia_client-1.1.18}/soia_client.egg-info/SOURCES.txt +0 -0
  32. {soia_client-1.1.9 → soia_client-1.1.18}/soia_client.egg-info/dependency_links.txt +0 -0
  33. {soia_client-1.1.9 → soia_client-1.1.18}/soia_client.egg-info/top_level.txt +0 -0
  34. {soia_client-1.1.9 → soia_client-1.1.18}/tests/test_module_initializer.py +0 -0
  35. {soia_client-1.1.9 → soia_client-1.1.18}/tests/test_timestamp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soia-client
3
- Version: 1.1.9
3
+ Version: 1.1.18
4
4
  Author-email: Tyler Fibonacci <gepheum@gmail.com>
5
5
  License: MIT License
6
6
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "soia-client"
7
- version = "1.1.9"
7
+ version = "1.1.18"
8
8
  description = ""
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Tyler Fibonacci", email = "gepheum@gmail.com" }]
@@ -98,9 +98,9 @@ class _ArrayAdapter(Generic[T], TypeAdapter[tuple[T, ...]]):
98
98
  listuple_class_local,
99
99
  "([",
100
100
  self.item_adapter.from_json_expr("_e", keep_unrecognized_expr),
101
- " for _e in ",
101
+ " for _e in (",
102
102
  json_expr,
103
- "] or ",
103
+ " or ())] or ",
104
104
  empty_listuple_local,
105
105
  ")",
106
106
  )
@@ -633,7 +633,7 @@ def _make_decode_fn(
633
633
  builder.append_ln(" ", Expr.local("decode_unused", decode_unused), "(stream)")
634
634
  if removed_numbers:
635
635
  builder.append_ln(
636
- f" if number in {removed_numbers_tuple} or not keep_unrecognized_fields:"
636
+ f" if number in {removed_numbers_tuple} or not stream.keep_unrecognized_fields:"
637
637
  )
638
638
  builder.append_ln(" return ", unknown_constant_local)
639
639
  builder.append_ln(" bytes = stream.buffer[start_offset:stream.position]")
@@ -673,7 +673,7 @@ def _make_decode_fn(
673
673
  # The field was either removed or is an unrecognized field.
674
674
  if removed_numbers:
675
675
  builder.append_ln(
676
- f"if number in {removed_numbers_tuple} or not keep_unrecognized_fields:"
676
+ f"if number in {removed_numbers_tuple} or not stream.keep_unrecognized_fields:"
677
677
  )
678
678
  builder.append_ln(" return ", unknown_constant_local)
679
679
  builder.append_ln("bytes = stream.buffer[start_offset:stream.position]")
@@ -682,7 +682,7 @@ def _make_decode_fn(
682
682
  builder.append_ln(f"if number not in {value_field_numbers}:")
683
683
  if removed_numbers:
684
684
  builder.append_ln(
685
- f" if number in {removed_numbers_tuple} or not keep_unrecognized_fields:"
685
+ f" if number in {removed_numbers_tuple} or not stream.keep_unrecognized_fields:"
686
686
  )
687
687
  builder.append_ln(" return ", unknown_constant_local)
688
688
  builder.append_ln(" bytes = stream.buffer[start_offset:stream.position]")
@@ -66,7 +66,7 @@ class _BoolAdapter(AbstractPrimitiveAdapter[bool]):
66
66
  def from_json_expr(
67
67
  self, json_expr: ExprLike, keep_unrecognized_expr: ExprLike
68
68
  ) -> Expr:
69
- return Expr.join("(True if ", json_expr, " else False)")
69
+ return Expr.join("(", json_expr, " not in (0, '0'))")
70
70
 
71
71
  @staticmethod
72
72
  def encode(
@@ -339,7 +339,7 @@ class _TimestampAdapter(AbstractPrimitiveAdapter[Timestamp]):
339
339
  def _timestamp_from_json(json: Any) -> Timestamp:
340
340
  if json.__class__ is int or isinstance(json, int):
341
341
  return Timestamp(unix_millis=json)
342
- elif isinstance(json, float):
342
+ elif isinstance(json, float) or isinstance(json, str):
343
343
  return Timestamp(unix_millis=int(json))
344
344
  else:
345
345
  return Timestamp(unix_millis=json["unix_millis"])
@@ -386,7 +386,7 @@ class _StringAdapter(AbstractPrimitiveAdapter[str]):
386
386
  @staticmethod
387
387
  def decode(stream: ByteStream) -> str:
388
388
  wire = stream.read(1)[0]
389
- if wire == 242:
389
+ if wire in (0, 242):
390
390
  return ""
391
391
  else:
392
392
  # Should be wire 243
@@ -407,6 +407,13 @@ class _StringAdapter(AbstractPrimitiveAdapter[str]):
407
407
  STRING_ADAPTER: Final[TypeAdapter] = _StringAdapter()
408
408
 
409
409
 
410
+ def _bytes_from_json(json: str) -> bytes:
411
+ if json.startswith("hex:"):
412
+ return bytes.fromhex(json[4:])
413
+ else:
414
+ return base64.b64decode(json)
415
+
416
+
410
417
  class _BytesAdapter(AbstractPrimitiveAdapter[bytes]):
411
418
  def default_expr(self) -> ExprLike:
412
419
  return 'b""'
@@ -422,18 +429,25 @@ class _BytesAdapter(AbstractPrimitiveAdapter[bytes]):
422
429
  in_expr: ExprLike,
423
430
  readable: bool,
424
431
  ) -> Expr:
425
- return Expr.join(
426
- Expr.local("b64encode", base64.b64encode),
427
- "(",
428
- in_expr,
429
- ").decode('utf-8')",
430
- )
432
+ if readable:
433
+ return Expr.join(
434
+ "('hex:' + ",
435
+ in_expr,
436
+ ".hex())",
437
+ )
438
+ else:
439
+ return Expr.join(
440
+ Expr.local("b64encode", base64.b64encode),
441
+ "(",
442
+ in_expr,
443
+ ").decode('utf-8')",
444
+ )
431
445
 
432
446
  def from_json_expr(
433
447
  self, json_expr: ExprLike, keep_unrecognized_expr: ExprLike
434
448
  ) -> Expr:
435
449
  return Expr.join(
436
- Expr.local("b64decode", base64.b64decode), "(", json_expr, ' or "")'
450
+ Expr.local("bytes_from_json", _bytes_from_json), "(", json_expr, ' or "")'
437
451
  )
438
452
 
439
453
  @staticmethod
@@ -852,14 +852,6 @@ def _make_from_json_fn(
852
852
  f" if array_len <= {num_slots_incl_removed} or not keep_unrecognized_fields:"
853
853
  )
854
854
  builder.append_ln(" ret._unrecognized = None")
855
- builder.append_ln(
856
- " ret._array_len = ",
857
- _adjust_array_len_expr(
858
- "array_len",
859
- removed_numbers=removed_numbers,
860
- num_slots_excl_removed=num_slots_excl_removed,
861
- ),
862
- )
863
855
  builder.append_ln(" else:")
864
856
  builder.append_ln(
865
857
  " ret._unrecognized = ",
@@ -868,7 +860,14 @@ def _make_from_json_fn(
868
860
  Expr.local("deepcopy", copy.deepcopy),
869
861
  f"(json[{num_slots_incl_removed}:]), adjusted_json_array_len=array_len)",
870
862
  )
871
- builder.append_ln(f" ret._array_len = {num_slots_excl_removed}")
863
+ builder.append_ln(
864
+ " ret._array_len = ",
865
+ _adjust_array_len_expr(
866
+ "array_len",
867
+ removed_numbers=removed_numbers,
868
+ num_slots_excl_removed=num_slots_excl_removed,
869
+ ),
870
+ )
872
871
 
873
872
  builder.append_ln("else:")
874
873
  builder.append_ln(" array_len = 0")
@@ -946,14 +945,14 @@ def _make_decode_fn(
946
945
 
947
946
  builder.append_ln(f"if array_len > {num_slots_excl_removed}:")
948
947
  builder.append_ln(
949
- f" if array_len > {num_slots_incl_removed} and keep_unrecognized_fields:"
948
+ f" if array_len > {num_slots_incl_removed} and stream.keep_unrecognized_fields:"
950
949
  )
951
950
  for _ in range(num_slots_incl_removed - num_slots_excl_removed):
952
951
  builder.append_ln(
953
952
  " ", Expr.local("decode_unused", decode_unused), "(stream)"
954
953
  )
955
954
  builder.append_ln(" start_offset = stream.position")
956
- builder.append_ln(" for _ in range(array_len - {num_slots_incl_removed}):")
955
+ builder.append_ln(f" for _ in range(array_len - {num_slots_incl_removed}):")
957
956
  builder.append_ln(" ", Expr.local("decode_unused", decode_unused), "(stream)")
958
957
  builder.append_ln(" end_offset = stream.position")
959
958
  builder.append_ln(
@@ -969,7 +968,7 @@ def _make_decode_fn(
969
968
  builder.append_ln(" ret._unrecognized = None")
970
969
 
971
970
  builder.append_ln(
972
- " ret._array_len = ",
971
+ "ret._array_len = ",
973
972
  _adjust_array_len_expr(
974
973
  "array_len",
975
974
  removed_numbers=removed_numbers,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soia-client
3
- Version: 1.1.9
3
+ Version: 1.1.18
4
4
  Author-email: Tyler Fibonacci <gepheum@gmail.com>
5
5
  License: MIT License
6
6
 
@@ -13,6 +13,9 @@ class SerializersTestCase(unittest.TestCase):
13
13
  self.assertEqual(primitive_serializer("bool").from_json_code("true"), True)
14
14
  self.assertEqual(primitive_serializer("bool").from_json_code("false"), False)
15
15
  self.assertEqual(primitive_serializer("bool").from_json_code("0"), False)
16
+ self.assertEqual(primitive_serializer("bool").from_json_code('"0"'), False)
17
+ self.assertEqual(primitive_serializer("bool").from_json_code("1"), True)
18
+ self.assertEqual(primitive_serializer("bool").from_json_code('"1"'), True)
16
19
 
17
20
  self.assertEqual(primitive_serializer("int32").to_json_code(7), "7")
18
21
  self.assertEqual(
@@ -144,6 +147,19 @@ class SerializersTestCase(unittest.TestCase):
144
147
  ),
145
148
  "[\n true,\n false\n]",
146
149
  )
150
+ self.assertEqual(
151
+ array_serializer(primitive_serializer("bool")).from_json_code(
152
+ "[ true, false ]"
153
+ ),
154
+ (
155
+ True,
156
+ False,
157
+ ),
158
+ )
159
+ self.assertEqual(
160
+ array_serializer(primitive_serializer("bool")).from_json_code("0"),
161
+ (),
162
+ )
147
163
 
148
164
  def test_optional_serializer(self):
149
165
  self.assertEqual(
File without changes
File without changes
File without changes
File without changes
@@ -316,15 +316,15 @@ _FIELD_SERIALIZER: Final = _dataclass_serializer(
316
316
  "name",
317
317
  _primitive_serializer(str),
318
318
  ),
319
+ _FieldSerializer(
320
+ "number",
321
+ _primitive_serializer(int),
322
+ ),
319
323
  _FieldSerializer[Optional[Type]](
320
324
  "type",
321
325
  _optional_serializer(_forwarding_serializer(_type_serializer)),
322
326
  default=None,
323
327
  ),
324
- _FieldSerializer(
325
- "number",
326
- _primitive_serializer(int),
327
- ),
328
328
  ],
329
329
  )
330
330