soia-client 1.1.8__py3-none-any.whl → 1.1.20__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.
soia/_impl/arrays.py CHANGED
@@ -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
  )
soia/_impl/enums.py CHANGED
@@ -630,10 +630,9 @@ def _make_decode_fn(
630
630
  builder.append_ln(" try:")
631
631
  builder.append_ln(" return ", number_to_constant_local, "[number]")
632
632
  builder.append_ln(" except:")
633
- builder.append_ln(" ", Expr.local("decode_unused", decode_unused), "(stream)")
634
633
  if removed_numbers:
635
634
  builder.append_ln(
636
- f" if number in {removed_numbers_tuple} or not keep_unrecognized_fields:"
635
+ f" if number in {removed_numbers_tuple} or not stream.keep_unrecognized_fields:"
637
636
  )
638
637
  builder.append_ln(" return ", unknown_constant_local)
639
638
  builder.append_ln(" bytes = stream.buffer[start_offset:stream.position]")
@@ -671,18 +670,20 @@ def _make_decode_fn(
671
670
 
672
671
  if not value_fields:
673
672
  # The field was either removed or is an unrecognized field.
673
+ builder.append_ln(Expr.local("decode_unused", decode_unused), "(stream)")
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]")
680
680
  builder.append_ln("return ", unrecognized_class_local, "(0, bytes)")
681
681
  else:
682
682
  builder.append_ln(f"if number not in {value_field_numbers}:")
683
+ builder.append_ln(" ", Expr.local("decode_unused", decode_unused), "(stream)")
683
684
  if removed_numbers:
684
685
  builder.append_ln(
685
- f" if number in {removed_numbers_tuple} or not keep_unrecognized_fields:"
686
+ f" if number in {removed_numbers_tuple} or not stream.keep_unrecognized_fields:"
686
687
  )
687
688
  builder.append_ln(" return ", unknown_constant_local)
688
689
  builder.append_ln(" bytes = stream.buffer[start_offset:stream.position]")
soia/_impl/primitives.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import base64
2
+ import math
2
3
  import struct
3
4
  from collections.abc import Callable
4
5
  from dataclasses import dataclass
@@ -66,7 +67,7 @@ class _BoolAdapter(AbstractPrimitiveAdapter[bool]):
66
67
  def from_json_expr(
67
68
  self, json_expr: ExprLike, keep_unrecognized_expr: ExprLike
68
69
  ) -> Expr:
69
- return Expr.join("(True if ", json_expr, " else False)")
70
+ return Expr.join("(", json_expr, " not in (0, '0'))")
70
71
 
71
72
  @staticmethod
72
73
  def encode(
@@ -210,6 +211,20 @@ INT64_ADAPTER: Final[TypeAdapter[int]] = _Int64Adapter()
210
211
  UINT64_ADAPTER: Final[TypeAdapter[int]] = _Uint64Adapter()
211
212
 
212
213
 
214
+ _SPECIAL_FLOAT_TO_STRING: Final[dict[str, str]] = {
215
+ "nan": "NaN",
216
+ "inf": "Infinity",
217
+ "-inf": "-Infinity",
218
+ }
219
+
220
+
221
+ _STRING_TO_SPECIAL_FLOAT: Final[dict[str, float]] = {
222
+ "NaN": float("nan"),
223
+ "Infinity": float("inf"),
224
+ "-Infinity": float("-inf"),
225
+ }
226
+
227
+
213
228
  @dataclass(frozen=True)
214
229
  class _AbstractFloatAdapter(AbstractPrimitiveAdapter[float]):
215
230
  """Type adapter implementation for float32 and float64."""
@@ -224,12 +239,40 @@ class _AbstractFloatAdapter(AbstractPrimitiveAdapter[float]):
224
239
  return arg_expr
225
240
 
226
241
  def to_json_expr(self, in_expr: ExprLike, readable: bool) -> ExprLike:
227
- return in_expr
242
+ return Expr.join(
243
+ "(",
244
+ in_expr,
245
+ " if ",
246
+ Expr.local("_isfinite", math.isfinite),
247
+ "(",
248
+ in_expr,
249
+ ") else ",
250
+ Expr.local(
251
+ "_SPECIAL_FLOAT_TO_STRING",
252
+ _SPECIAL_FLOAT_TO_STRING,
253
+ ),
254
+ "[f'{",
255
+ in_expr,
256
+ "}'])",
257
+ )
228
258
 
229
259
  def from_json_expr(
230
260
  self, json_expr: ExprLike, keep_unrecognized_expr: ExprLike
231
261
  ) -> Expr:
232
- return Expr.join("(", json_expr, " + 0.0)")
262
+ return Expr.join(
263
+ "(",
264
+ Expr.local(
265
+ "_STRING_TO_SPECIAL_FLOAT",
266
+ _STRING_TO_SPECIAL_FLOAT,
267
+ ),
268
+ "[",
269
+ json_expr,
270
+ "] if ",
271
+ json_expr,
272
+ " in ('NaN', 'Infinity', '-Infinity') else (",
273
+ json_expr,
274
+ " + 0.0))",
275
+ )
233
276
 
234
277
  def decode_fn(self) -> Callable[[ByteStream], float]:
235
278
  return decode_float
@@ -339,6 +382,8 @@ class _TimestampAdapter(AbstractPrimitiveAdapter[Timestamp]):
339
382
  def _timestamp_from_json(json: Any) -> Timestamp:
340
383
  if json.__class__ is int or isinstance(json, int):
341
384
  return Timestamp(unix_millis=json)
385
+ elif isinstance(json, float) or isinstance(json, str):
386
+ return Timestamp(unix_millis=int(json))
342
387
  else:
343
388
  return Timestamp(unix_millis=json["unix_millis"])
344
389
 
@@ -384,7 +429,7 @@ class _StringAdapter(AbstractPrimitiveAdapter[str]):
384
429
  @staticmethod
385
430
  def decode(stream: ByteStream) -> str:
386
431
  wire = stream.read(1)[0]
387
- if wire == 242:
432
+ if wire in (0, 242):
388
433
  return ""
389
434
  else:
390
435
  # Should be wire 243
@@ -405,6 +450,13 @@ class _StringAdapter(AbstractPrimitiveAdapter[str]):
405
450
  STRING_ADAPTER: Final[TypeAdapter] = _StringAdapter()
406
451
 
407
452
 
453
+ def _bytes_from_json(json: str) -> bytes:
454
+ if json.startswith("hex:"):
455
+ return bytes.fromhex(json[4:])
456
+ else:
457
+ return base64.b64decode(json)
458
+
459
+
408
460
  class _BytesAdapter(AbstractPrimitiveAdapter[bytes]):
409
461
  def default_expr(self) -> ExprLike:
410
462
  return 'b""'
@@ -420,18 +472,25 @@ class _BytesAdapter(AbstractPrimitiveAdapter[bytes]):
420
472
  in_expr: ExprLike,
421
473
  readable: bool,
422
474
  ) -> Expr:
423
- return Expr.join(
424
- Expr.local("b64encode", base64.b64encode),
425
- "(",
426
- in_expr,
427
- ").decode('utf-8')",
428
- )
475
+ if readable:
476
+ return Expr.join(
477
+ "('hex:' + ",
478
+ in_expr,
479
+ ".hex())",
480
+ )
481
+ else:
482
+ return Expr.join(
483
+ Expr.local("b64encode", base64.b64encode),
484
+ "(",
485
+ in_expr,
486
+ ").decode('utf-8')",
487
+ )
429
488
 
430
489
  def from_json_expr(
431
490
  self, json_expr: ExprLike, keep_unrecognized_expr: ExprLike
432
491
  ) -> Expr:
433
492
  return Expr.join(
434
- Expr.local("b64decode", base64.b64decode), "(", json_expr, ' or "")'
493
+ Expr.local("bytes_from_json", _bytes_from_json), "(", json_expr, ' or "")'
435
494
  )
436
495
 
437
496
  @staticmethod
soia/_impl/structs.py CHANGED
@@ -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,
soia/reflection.py CHANGED
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soia-client
3
- Version: 1.1.8
3
+ Version: 1.1.20
4
4
  Author-email: Tyler Fibonacci <gepheum@gmail.com>
5
5
  License: MIT License
6
6
 
@@ -1,28 +1,28 @@
1
1
  soia/__init__.py,sha256=WPhdlu7zKBSWd4DVFWXQKQoptD0gU7xGFm4tbQHrVc8,787
2
2
  soia/_module_initializer.py,sha256=JHZMcLqpYuWoC3cN4wBFFCHlHR60-LNvrjo_EMCFkAE,4220
3
3
  soia/_spec.py,sha256=Y5EHHQa6qNeJc29aaqGrFPnPFXxlL7TED9_AXUGBjf0,3663
4
- soia/reflection.py,sha256=SEFHNlzmWZEOQwoVUTIxzjjnbkiKSwo2rbpSU-qXhC4,9375
4
+ soia/reflection.py,sha256=rBwoA6iqT6ELXpuZyJg3Gjj4XadlT4U7Veu-JgcEZUg,9375
5
5
  soia/_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- soia/_impl/arrays.py,sha256=xX9xBvdk_-DcI9PiylRzszkf25uXk0SJOi8rRLcxYCw,7252
6
+ soia/_impl/arrays.py,sha256=_4aayjMJkoCh_Nz28QXOUr5h7YWKBkoeBdLAEbjagNY,7260
7
7
  soia/_impl/binary.py,sha256=JK8W_xjVBHUmJoGrmMZX1EKWXXFpfnTbCmQGid4t5z8,8986
8
- soia/_impl/enums.py,sha256=qZCFQTOWuzNidkxCEXY71lJ1rT5-HHgzYxZIPD6_6LY,24968
8
+ soia/_impl/enums.py,sha256=RcHAHQUNynngiJWbQMwnzpx-Sc_f12xZwFXg1GFqroY,25073
9
9
  soia/_impl/function_maker.py,sha256=MvCDv1WwzKGJzZbNCnJ_8-MP3m1xTIabumXA-9Ydd9M,5639
10
10
  soia/_impl/keep.py,sha256=GDeMKKUcvUFXWJVzBPB9CuLkcQb93sWKvo0PcyKUBzg,370
11
11
  soia/_impl/keyed_items.py,sha256=EoPrdeLJ8i7zCH-oW-7qOcyadyrzykB6lkrf3xRVmyk,337
12
12
  soia/_impl/method.py,sha256=C6ygh-Li4zADxFR_gfeBTuPUzLjZ1XHCp0ZI4-uiRYs,455
13
13
  soia/_impl/never.py,sha256=T7PHtIipuXlici4wa0yuJKrn9JgcT-ODC3QVCwsPprY,46
14
14
  soia/_impl/optionals.py,sha256=nYEQcR_kGzVGSaIhatQmZyusdDfmgmB7a7cgL2OVeJA,3661
15
- soia/_impl/primitives.py,sha256=hjUxMmd584je6DANjWlZ9shHO5PX6vrK5zJAAfdrA-4,13436
15
+ soia/_impl/primitives.py,sha256=N5Z9VWYSihqPKZ32WR7OAjNsHJp-OUvpJKiEuDcD9-Q,14864
16
16
  soia/_impl/repr.py,sha256=Z4sZKFrujdTD49aqB7q3bjXAb1f31I7uuChDBy5XvFg,1418
17
17
  soia/_impl/serializer.py,sha256=UrOb5_VaPnRb0t-Nop7mu7j_yaK4fiRQzwMdKOUkmTQ,4627
18
18
  soia/_impl/serializers.py,sha256=IL9jHHMo11pgrL1-crarOEElvTyV5YM6FTcgumjW6IU,2564
19
19
  soia/_impl/service.py,sha256=4FZ7yY4EJTw4xFmfg3Ya9IfbI0s8qN97aIuqa8TifjM,15535
20
20
  soia/_impl/service_client.py,sha256=FWfbFswbhMBw1snR9JLEpSJagY2ntZbFaVxTUGEDA5s,5303
21
- soia/_impl/structs.py,sha256=7hHula-mJnKbYyl6crYvv1U5uxj5lcvLeyD1fCbJIrc,35945
21
+ soia/_impl/structs.py,sha256=cddVUo1wzXccl5WtxpMSpjup6Wej6fc3OiKLtXEG_Vg,35877
22
22
  soia/_impl/timestamp.py,sha256=uiDQOVDC1ygA-15Yl_b7-pT_tsbHe1YrtB0kA5FFebY,5637
23
23
  soia/_impl/type_adapter.py,sha256=OSZdXbeXANSEkKBb_rAgljB_2qG3HJUk6jK3nPjzRRY,2909
24
- soia_client-1.1.8.dist-info/licenses/LICENSE,sha256=SaAftKkX6hfSOiPdENQPS70tifH3PDHgazq8eK2Pwfw,1064
25
- soia_client-1.1.8.dist-info/METADATA,sha256=gGzPD_379bwWLs0YBwu7ljW-gPzxYkaBAMPZNptH6QE,2121
26
- soia_client-1.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- soia_client-1.1.8.dist-info/top_level.txt,sha256=lsYG9JrvauFe1oIV5zvnwsS9hsx3ztwfK_937op9mxc,5
28
- soia_client-1.1.8.dist-info/RECORD,,
24
+ soia_client-1.1.20.dist-info/licenses/LICENSE,sha256=SaAftKkX6hfSOiPdENQPS70tifH3PDHgazq8eK2Pwfw,1064
25
+ soia_client-1.1.20.dist-info/METADATA,sha256=rPdH_a2Fn_wCoRk3SxVBs3L4P8AADh6A-74G9kgxMqA,2122
26
+ soia_client-1.1.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ soia_client-1.1.20.dist-info/top_level.txt,sha256=lsYG9JrvauFe1oIV5zvnwsS9hsx3ztwfK_937op9mxc,5
28
+ soia_client-1.1.20.dist-info/RECORD,,