cocoindex 0.1.63__cp313-cp313-manylinux_2_28_x86_64.whl → 0.1.64__cp313-cp313-manylinux_2_28_x86_64.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.
cocoindex/convert.py CHANGED
@@ -18,6 +18,7 @@ from .typing import (
18
18
  encode_enriched_type,
19
19
  extract_ndarray_scalar_dtype,
20
20
  is_namedtuple_type,
21
+ is_struct_type,
21
22
  )
22
23
 
23
24
 
@@ -37,9 +38,15 @@ def encode_engine_value(value: Any) -> Any:
37
38
  if isinstance(value, (list, tuple)):
38
39
  return [encode_engine_value(v) for v in value]
39
40
  if isinstance(value, dict):
40
- return [
41
- [encode_engine_value(k)] + encode_engine_value(v) for k, v in value.items()
42
- ]
41
+ if not value:
42
+ return {}
43
+
44
+ first_val = next(iter(value.values()))
45
+ if is_struct_type(type(first_val)): # KTable
46
+ return [
47
+ [encode_engine_value(k)] + encode_engine_value(v)
48
+ for k, v in value.items()
49
+ ]
43
50
  return value
44
51
 
45
52
 
cocoindex/flow.py CHANGED
@@ -198,18 +198,42 @@ class DataSlice(Generic[T]):
198
198
  raise KeyError(field_name)
199
199
  return DataSlice(_DataSliceState(self._state.flow_builder_state, field_slice))
200
200
 
201
- def row(self) -> DataScope:
201
+ def row(
202
+ self,
203
+ /,
204
+ *,
205
+ max_inflight_rows: int | None = None,
206
+ max_inflight_bytes: int | None = None,
207
+ ) -> DataScope:
202
208
  """
203
209
  Return a scope representing each row of the table.
204
210
  """
205
- row_scope = self._state.engine_data_slice.table_row_scope()
211
+ row_scope = self._state.flow_builder_state.engine_flow_builder.for_each(
212
+ self._state.engine_data_slice,
213
+ execution_options=dump_engine_object(
214
+ _ExecutionOptions(
215
+ max_inflight_rows=max_inflight_rows,
216
+ max_inflight_bytes=max_inflight_bytes,
217
+ ),
218
+ ),
219
+ )
206
220
  return DataScope(self._state.flow_builder_state, row_scope)
207
221
 
208
- def for_each(self, f: Callable[[DataScope], None]) -> None:
222
+ def for_each(
223
+ self,
224
+ f: Callable[[DataScope], None],
225
+ /,
226
+ *,
227
+ max_inflight_rows: int | None = None,
228
+ max_inflight_bytes: int | None = None,
229
+ ) -> None:
209
230
  """
210
231
  Apply a function to each row of the collection.
211
232
  """
212
- with self.row() as scope:
233
+ with self.row(
234
+ max_inflight_rows=max_inflight_rows,
235
+ max_inflight_bytes=max_inflight_bytes,
236
+ ) as scope:
213
237
  f(scope)
214
238
 
215
239
  def transform(
@@ -418,7 +442,8 @@ class _SourceRefreshOptions:
418
442
 
419
443
  @dataclass
420
444
  class _ExecutionOptions:
421
- max_inflight_count: int | None = None
445
+ max_inflight_rows: int | None = None
446
+ max_inflight_bytes: int | None = None
422
447
 
423
448
 
424
449
  class FlowBuilder:
@@ -444,7 +469,8 @@ class FlowBuilder:
444
469
  *,
445
470
  name: str | None = None,
446
471
  refresh_interval: datetime.timedelta | None = None,
447
- max_inflight_count: int | None = None,
472
+ max_inflight_rows: int | None = None,
473
+ max_inflight_bytes: int | None = None,
448
474
  ) -> DataSlice[T]:
449
475
  """
450
476
  Import a source to the flow.
@@ -464,7 +490,10 @@ class FlowBuilder:
464
490
  _SourceRefreshOptions(refresh_interval=refresh_interval)
465
491
  ),
466
492
  execution_options=dump_engine_object(
467
- _ExecutionOptions(max_inflight_count=max_inflight_count)
493
+ _ExecutionOptions(
494
+ max_inflight_rows=max_inflight_rows,
495
+ max_inflight_bytes=max_inflight_bytes,
496
+ )
468
497
  ),
469
498
  ),
470
499
  name,
cocoindex/setting.py CHANGED
@@ -43,6 +43,15 @@ class DatabaseConnectionSpec:
43
43
  password: str | None = None
44
44
 
45
45
 
46
+ @dataclass
47
+ class DefaultExecutionOptions:
48
+ """Default execution options."""
49
+
50
+ # The maximum number of concurrent inflight requests.
51
+ source_max_inflight_rows: int | None = 256
52
+ source_max_inflight_bytes: int | None = 1024 * 1024 * 1024
53
+
54
+
46
55
  def _load_field(
47
56
  target: dict[str, Any],
48
57
  name: str,
@@ -55,7 +64,15 @@ def _load_field(
55
64
  if required:
56
65
  raise ValueError(f"{env_name} is not set")
57
66
  else:
58
- target[name] = value if parse is None else parse(value)
67
+ if parse is None:
68
+ target[name] = value
69
+ else:
70
+ try:
71
+ target[name] = parse(value)
72
+ except Exception as e:
73
+ raise ValueError(
74
+ f"failed to parse environment variable {env_name}: {value}"
75
+ ) from e
59
76
 
60
77
 
61
78
  @dataclass
@@ -64,6 +81,7 @@ class Settings:
64
81
 
65
82
  database: DatabaseConnectionSpec | None = None
66
83
  app_namespace: str = ""
84
+ default_execution_options: DefaultExecutionOptions | None = None
67
85
 
68
86
  @classmethod
69
87
  def from_env(cls) -> Self:
@@ -79,9 +97,28 @@ class Settings:
79
97
  else:
80
98
  database = None
81
99
 
100
+ exec_kwargs: dict[str, Any] = dict()
101
+ _load_field(
102
+ exec_kwargs,
103
+ "source_max_inflight_rows",
104
+ "COCOINDEX_SOURCE_MAX_INFLIGHT_ROWS",
105
+ parse=int,
106
+ )
107
+ _load_field(
108
+ exec_kwargs,
109
+ "source_max_inflight_bytes",
110
+ "COCOINDEX_SOURCE_MAX_INFLIGHT_BYTES",
111
+ parse=int,
112
+ )
113
+ default_execution_options = DefaultExecutionOptions(**exec_kwargs)
114
+
82
115
  app_namespace = os.getenv("COCOINDEX_APP_NAMESPACE", "")
83
116
 
84
- return cls(database=database, app_namespace=app_namespace)
117
+ return cls(
118
+ database=database,
119
+ app_namespace=app_namespace,
120
+ default_execution_options=default_execution_options,
121
+ )
85
122
 
86
123
 
87
124
  @dataclass
@@ -93,7 +93,7 @@ def validate_full_roundtrip_to(
93
93
  def eq(a: Any, b: Any) -> bool:
94
94
  if isinstance(a, np.ndarray) and isinstance(b, np.ndarray):
95
95
  return np.array_equal(a, b)
96
- return type(a) == type(b) and not not (a == b)
96
+ return type(a) is type(b) and not not (a == b)
97
97
 
98
98
  encoded_value = encode_engine_value(value)
99
99
  value_type = value_type or type(value)
@@ -229,6 +229,11 @@ def test_encode_engine_value_none() -> None:
229
229
 
230
230
 
231
231
  def test_roundtrip_basic_types() -> None:
232
+ validate_full_roundtrip(b"hello world", bytes, (b"hello world", None))
233
+ validate_full_roundtrip(b"\x00\x01\x02\xff\xfe", bytes)
234
+ validate_full_roundtrip("hello", str, ("hello", None))
235
+ validate_full_roundtrip(True, bool, (True, None))
236
+ validate_full_roundtrip(False, bool, (False, None))
232
237
  validate_full_roundtrip(
233
238
  42, cocoindex.Int64, (42, int), (np.int64(42), np.int64), (42, None)
234
239
  )
@@ -252,10 +257,29 @@ def test_roundtrip_basic_types() -> None:
252
257
  )
253
258
  validate_full_roundtrip(np.float32(3.25), np.float32, (3.25, Float32))
254
259
 
255
- validate_full_roundtrip("hello", str, ("hello", None))
256
- validate_full_roundtrip(True, bool, (True, None))
257
- validate_full_roundtrip(False, bool, (False, None))
258
- validate_full_roundtrip((1, 2), cocoindex.Range, ((1, 2), None))
260
+
261
+ def test_roundtrip_uuid() -> None:
262
+ uuid_value = uuid.uuid4()
263
+ validate_full_roundtrip(uuid_value, uuid.UUID, (uuid_value, None))
264
+
265
+
266
+ def test_roundtrip_range() -> None:
267
+ r1 = (0, 100)
268
+ validate_full_roundtrip(r1, cocoindex.Range, (r1, None))
269
+ r2 = (50, 50)
270
+ validate_full_roundtrip(r2, cocoindex.Range, (r2, None))
271
+ r3 = (0, 1_000_000_000)
272
+ validate_full_roundtrip(r3, cocoindex.Range, (r3, None))
273
+
274
+
275
+ def test_roundtrip_time() -> None:
276
+ t1 = datetime.time(10, 30, 50, 123456)
277
+ validate_full_roundtrip(t1, datetime.time, (t1, None))
278
+ t2 = datetime.time(23, 59, 59)
279
+ validate_full_roundtrip(t2, datetime.time, (t2, None))
280
+ t3 = datetime.time(0, 0, 0)
281
+ validate_full_roundtrip(t3, datetime.time, (t3, None))
282
+
259
283
  validate_full_roundtrip(
260
284
  datetime.date(2025, 1, 1), datetime.date, (datetime.date(2025, 1, 1), None)
261
285
  )
@@ -297,8 +321,38 @@ def test_roundtrip_basic_types() -> None:
297
321
  ),
298
322
  )
299
323
 
300
- uuid_value = uuid.uuid4()
301
- validate_full_roundtrip(uuid_value, uuid.UUID, (uuid_value, None))
324
+
325
+ def test_roundtrip_timedelta() -> None:
326
+ td1 = datetime.timedelta(
327
+ days=5, seconds=10, microseconds=123, milliseconds=456, minutes=30, hours=2
328
+ )
329
+ validate_full_roundtrip(td1, datetime.timedelta, (td1, None))
330
+ td2 = datetime.timedelta(days=-5, hours=-2)
331
+ validate_full_roundtrip(td2, datetime.timedelta, (td2, None))
332
+ td3 = datetime.timedelta(0)
333
+ validate_full_roundtrip(td3, datetime.timedelta, (td3, None))
334
+
335
+
336
+ def test_roundtrip_json() -> None:
337
+ simple_dict = {"key": "value", "number": 123, "bool": True, "float": 1.23}
338
+ validate_full_roundtrip(simple_dict, cocoindex.Json)
339
+
340
+ simple_list = [1, "string", False, None, 4.56]
341
+ validate_full_roundtrip(simple_list, cocoindex.Json)
342
+
343
+ nested_structure = {
344
+ "name": "Test Json",
345
+ "version": 1.0,
346
+ "items": [
347
+ {"id": 1, "value": "item1"},
348
+ {"id": 2, "value": None, "props": {"active": True}},
349
+ ],
350
+ "metadata": None,
351
+ }
352
+ validate_full_roundtrip(nested_structure, cocoindex.Json)
353
+
354
+ validate_full_roundtrip({}, cocoindex.Json)
355
+ validate_full_roundtrip([], cocoindex.Json)
302
356
 
303
357
 
304
358
  def test_decode_scalar_numpy_values() -> None:
@@ -675,6 +729,21 @@ def test_roundtrip_union_with_vector() -> None:
675
729
  validate_full_roundtrip(value, t, ([1.0, 2.0, 3.0], list[float] | str))
676
730
 
677
731
 
732
+ def test_roundtrip_union_with_misc_types() -> None:
733
+ t_bytes_union = int | bytes | str
734
+ validate_full_roundtrip(b"test_bytes", t_bytes_union)
735
+ validate_full_roundtrip(123, t_bytes_union)
736
+
737
+ t_range_union = cocoindex.Range | str | bool
738
+ validate_full_roundtrip((100, 200), t_range_union)
739
+ validate_full_roundtrip("test_string", t_range_union)
740
+
741
+ t_json_union = cocoindex.Json | int | bytes
742
+ json_dict = {"a": 1, "b": [2, 3]}
743
+ validate_full_roundtrip(json_dict, t_json_union)
744
+ validate_full_roundtrip(b"another_byte_string", t_json_union)
745
+
746
+
678
747
  def test_roundtrip_ltable() -> None:
679
748
  t = list[Order]
680
749
  value = [Order("O1", "item1", 10.0), Order("O2", "item2", 20.0)]
@@ -688,10 +757,26 @@ def test_roundtrip_ltable() -> None:
688
757
  validate_full_roundtrip(value_nt, t_nt)
689
758
 
690
759
 
691
- def test_roundtrip_ktable_str_key() -> None:
692
- t = dict[str, Order]
693
- value = {"K1": Order("O1", "item1", 10.0), "K2": Order("O2", "item2", 20.0)}
694
- validate_full_roundtrip(value, t)
760
+ def test_roundtrip_ktable_various_key_types() -> None:
761
+ @dataclass
762
+ class SimpleValue:
763
+ data: str
764
+
765
+ t_bytes_key = dict[bytes, SimpleValue]
766
+ value_bytes_key = {b"key1": SimpleValue("val1"), b"key2": SimpleValue("val2")}
767
+ validate_full_roundtrip(value_bytes_key, t_bytes_key)
768
+
769
+ t_int_key = dict[int, SimpleValue]
770
+ value_int_key = {1: SimpleValue("val1"), 2: SimpleValue("val2")}
771
+ validate_full_roundtrip(value_int_key, t_int_key)
772
+
773
+ t_bool_key = dict[bool, SimpleValue]
774
+ value_bool_key = {True: SimpleValue("val_true"), False: SimpleValue("val_false")}
775
+ validate_full_roundtrip(value_bool_key, t_bool_key)
776
+
777
+ t_str_key = dict[str, Order]
778
+ value_str_key = {"K1": Order("O1", "item1", 10.0), "K2": Order("O2", "item2", 20.0)}
779
+ validate_full_roundtrip(value_str_key, t_str_key)
695
780
 
696
781
  t_nt = dict[str, OrderNamedTuple]
697
782
  value_nt = {
@@ -700,6 +785,27 @@ def test_roundtrip_ktable_str_key() -> None:
700
785
  }
701
786
  validate_full_roundtrip(value_nt, t_nt)
702
787
 
788
+ t_range_key = dict[cocoindex.Range, SimpleValue]
789
+ value_range_key = {
790
+ (1, 10): SimpleValue("val_range1"),
791
+ (20, 30): SimpleValue("val_range2"),
792
+ }
793
+ validate_full_roundtrip(value_range_key, t_range_key)
794
+
795
+ t_date_key = dict[datetime.date, SimpleValue]
796
+ value_date_key = {
797
+ datetime.date(2023, 1, 1): SimpleValue("val_date1"),
798
+ datetime.date(2024, 2, 2): SimpleValue("val_date2"),
799
+ }
800
+ validate_full_roundtrip(value_date_key, t_date_key)
801
+
802
+ t_uuid_key = dict[uuid.UUID, SimpleValue]
803
+ value_uuid_key = {
804
+ uuid.uuid4(): SimpleValue("val_uuid1"),
805
+ uuid.uuid4(): SimpleValue("val_uuid2"),
806
+ }
807
+ validate_full_roundtrip(value_uuid_key, t_uuid_key)
808
+
703
809
 
704
810
  def test_roundtrip_ktable_struct_key() -> None:
705
811
  @dataclass(frozen=True)
@@ -990,6 +1096,24 @@ def test_full_roundtrip_vector_numeric_types() -> None:
990
1096
  validate_full_roundtrip(value_u64, Vector[np.uint64, Literal[3]])
991
1097
 
992
1098
 
1099
+ def test_full_roundtrip_vector_other_types() -> None:
1100
+ """Test full roundtrip for Vector with non-numeric basic types."""
1101
+ uuid_list = [uuid.uuid4(), uuid.uuid4()]
1102
+ validate_full_roundtrip(uuid_list, Vector[uuid.UUID], (uuid_list, list[uuid.UUID]))
1103
+
1104
+ date_list = [datetime.date(2023, 1, 1), datetime.date(2024, 10, 5)]
1105
+ validate_full_roundtrip(
1106
+ date_list, Vector[datetime.date], (date_list, list[datetime.date])
1107
+ )
1108
+
1109
+ bool_list = [True, False, True, False]
1110
+ validate_full_roundtrip(bool_list, Vector[bool], (bool_list, list[bool]))
1111
+
1112
+ validate_full_roundtrip([], Vector[uuid.UUID], ([], list[uuid.UUID]))
1113
+ validate_full_roundtrip([], Vector[datetime.date], ([], list[datetime.date]))
1114
+ validate_full_roundtrip([], Vector[bool], ([], list[bool]))
1115
+
1116
+
993
1117
  def test_roundtrip_vector_no_dimension() -> None:
994
1118
  """Test full roundtrip for vector types without dimension annotation."""
995
1119
  value_f64 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
cocoindex/typing.py CHANGED
@@ -108,7 +108,7 @@ def is_namedtuple_type(t: type) -> bool:
108
108
  return isinstance(t, type) and issubclass(t, tuple) and hasattr(t, "_fields")
109
109
 
110
110
 
111
- def _is_struct_type(t: ElementType | None) -> bool:
111
+ def is_struct_type(t: ElementType | None) -> bool:
112
112
  return isinstance(t, type) and (
113
113
  dataclasses.is_dataclass(t) or is_namedtuple_type(t)
114
114
  )
@@ -205,7 +205,7 @@ def analyze_type_info(t: Any) -> AnalyzedTypeInfo:
205
205
  union_variant_types: typing.List[ElementType] | None = None
206
206
  key_type: type | None = None
207
207
  np_number_type: type | None = None
208
- if _is_struct_type(t):
208
+ if is_struct_type(t):
209
209
  struct_type = t
210
210
 
211
211
  if kind is None:
@@ -220,7 +220,7 @@ def analyze_type_info(t: Any) -> AnalyzedTypeInfo:
220
220
  elem_type = args[0]
221
221
 
222
222
  if kind is None:
223
- if _is_struct_type(elem_type):
223
+ if is_struct_type(elem_type):
224
224
  kind = "LTable"
225
225
  if vector_info is not None:
226
226
  raise ValueError(
@@ -243,7 +243,7 @@ def analyze_type_info(t: Any) -> AnalyzedTypeInfo:
243
243
  args = typing.get_args(t)
244
244
  elem_type = (args[0], args[1])
245
245
  kind = "KTable"
246
- elif base_type is types.UnionType:
246
+ elif base_type in (types.UnionType, typing.Union):
247
247
  possible_types = typing.get_args(t)
248
248
  non_none_types = [
249
249
  arg for arg in possible_types if arg not in (None, types.NoneType)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cocoindex
3
- Version: 0.1.63
3
+ Version: 0.1.64
4
4
  Requires-Dist: click>=8.1.8
5
5
  Requires-Dist: rich>=14.0.0
6
6
  Requires-Dist: python-dotenv>=1.1.0
@@ -1,13 +1,13 @@
1
- cocoindex-0.1.63.dist-info/METADATA,sha256=5p9o6R9LBv3kIl3GdIo-V40NqnF7DEZHgRTzKxuWFEQ,10136
2
- cocoindex-0.1.63.dist-info/WHEEL,sha256=LA67brojLOZ0i0Pcaw_z7b5IlOGp1xIEPobtgkZ23mU,108
3
- cocoindex-0.1.63.dist-info/entry_points.txt,sha256=_NretjYVzBdNTn7dK-zgwr7YfG2afz1u1uSE-5bZXF8,46
4
- cocoindex-0.1.63.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1
+ cocoindex-0.1.64.dist-info/METADATA,sha256=ByEFBlXrGkbESv0twsq2eLycjhTdkQKnE_EzQVIpWgQ,10136
2
+ cocoindex-0.1.64.dist-info/WHEEL,sha256=s25ArxaEBsS5fVGGsO24U-sMTFw8T6jsDJcABX1aYfs,108
3
+ cocoindex-0.1.64.dist-info/entry_points.txt,sha256=_NretjYVzBdNTn7dK-zgwr7YfG2afz1u1uSE-5bZXF8,46
4
+ cocoindex-0.1.64.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
5
  cocoindex/__init__.py,sha256=hDjehCjxRabFCW0RTt00JxnSAJIn9HeVoK4OjFbETsk,1910
6
- cocoindex/_engine.cpython-313-x86_64-linux-gnu.so,sha256=rkhz9llA8Co75g_schDEwsGSVtET_WWPNJcB1k-bfm0,63213880
6
+ cocoindex/_engine.cpython-313-x86_64-linux-gnu.so,sha256=xfGHmMLqwY9chWftYgHWr52iZRYakIQ6Ac_1i7DyeZ0,63570272
7
7
  cocoindex/auth_registry.py,sha256=1XqO7ibjmBBd8i11XSJTvTgdz8p1ptW-ZpuSgo_5zzk,716
8
8
  cocoindex/cli.py,sha256=-gp639JSyQN6YjnhGqCakIzYoSSqXxQMbxbkcYGP0QY,22359
9
- cocoindex/convert.py,sha256=FsKb2Pfbm7e1VQDOs_AsoiW9PbIUuyHQuqUlrENXmUY,11199
10
- cocoindex/flow.py,sha256=x13SDZvFZ-MR-gGF1HPp14DMSn0vp37cfz0YFK9Pmy8,33334
9
+ cocoindex/convert.py,sha256=qE1Ut_tAwX4wA4WqaWxpyj80-1t6WZ8Oi5_L9Mw5g4k,11393
10
+ cocoindex/flow.py,sha256=Rb3ImrFa-TKYZXZnfcTj4ePUZXqKgJCzZR4OYHP6rlk,34207
11
11
  cocoindex/functions.py,sha256=IBwvdPpGR-S5mk53HvHpT2GVs15MI9wQznxgOdxA0ac,3202
12
12
  cocoindex/index.py,sha256=j93B9jEvvLXHtpzKWL88SY6wCGEoPgpsQhEGHlyYGFg,540
13
13
  cocoindex/lib.py,sha256=f--9dAYd84CZosbDZqNW0oGbBLsY3dXiUTR1VrfQ_QY,817
@@ -15,14 +15,14 @@ cocoindex/llm.py,sha256=0ri8ZRg9_Zf2gyC5xuQ1Kq6kdZUO8r-A5WLnxit5S_4,448
15
15
  cocoindex/op.py,sha256=r_Usx7Jqh49Cck3tsYLx2vLRNUZArkQP_g7bIID6LPU,11809
16
16
  cocoindex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  cocoindex/runtime.py,sha256=bAdHYaXFWiiUWyAgzmKTeaAaRR0D_AmaqVCIdPO-v00,1056
18
- cocoindex/setting.py,sha256=Zl8K86r8RVvG9c3pCsH0Ot8BHhDAQAQCjoBp7TnXMLQ,3590
18
+ cocoindex/setting.py,sha256=FMNjer3YVmVyxLuGt6_DJ6vA1QH1mIo7oH0R51OLnk4,4714
19
19
  cocoindex/setup.py,sha256=7uIHKN4FOCuoidPXcKyGTrkqpkl9luL49-6UcnMxYzw,3068
20
20
  cocoindex/sources.py,sha256=JCnOhv1w4o28e03i7yvo4ESicWYAhckkBg5bQlxNH4U,1330
21
21
  cocoindex/targets.py,sha256=Nfh_tpFd1goTnS_cxBjIs4j9zl3Z4Z1JomAQ1dl3Sic,2796
22
22
  cocoindex/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- cocoindex/tests/test_convert.py,sha256=WmgbaQTYPDnjBfMlIrZWBHipPW7SlrvHYsLLqb--KH0,38025
23
+ cocoindex/tests/test_convert.py,sha256=efwF-43SFJiu85sQ78Z9k9OaJphTz_es_1cm5BoPO2Y,42565
24
24
  cocoindex/tests/test_optional_database.py,sha256=snAmkNa6wtOSaxoZE1HgjvL5v_ylitt3Jt_9df4Cgdc,8506
25
25
  cocoindex/tests/test_typing.py,sha256=t6UCYShcfonTfjBlGRWPiFGMZ8DGFfABXo6idekPoJE,14757
26
- cocoindex/typing.py,sha256=s_Hk4Npi8pxJUM2h_7Km0VFrojA8wJU9VDtRqVSL6C0,12622
26
+ cocoindex/typing.py,sha256=qQ-nSdkHzu8pSxfuR5sGGfoE8nCKqCDb0D9jbmxVt4M,12635
27
27
  cocoindex/utils.py,sha256=hUhX-XV6XGCtJSEIpBOuDv6VvqImwPlgBxztBTw7u0U,598
28
- cocoindex-0.1.63.dist-info/RECORD,,
28
+ cocoindex-0.1.64.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.0)
2
+ Generator: maturin (1.9.1)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp313-cp313-manylinux_2_28_x86_64