Skip to content

Commit 8668fa3

Browse files
committed
fix: avoid relying on runtime values when building table encoders
1 parent 7ee84de commit 8668fa3

File tree

1 file changed

+20
-34
lines changed

1 file changed

+20
-34
lines changed

python/cocoindex/convert.py

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
encode_enriched_type,
2929
is_namedtuple_type,
3030
is_numpy_number_type,
31-
is_struct_type,
3231
)
3332

3433

@@ -88,38 +87,25 @@ def encode_struct_list(value: Any) -> Any:
8887

8988
return encode_struct_list
9089

91-
if isinstance(variant, AnalyzedDictType):
92-
if not variant.value_type:
93-
return lambda value: value
90+
# Otherwise it's a vector, falling into basic type in the engine.
9491

92+
if isinstance(variant, AnalyzedDictType):
9593
value_type_info = analyze_type_info(variant.value_type)
96-
if isinstance(value_type_info.variant, AnalyzedStructType):
97-
98-
def encode_struct_dict(value: Any) -> Any:
99-
if not isinstance(value, dict):
100-
return value
101-
if not value:
102-
return []
103-
104-
sample_key, sample_val = next(iter(value.items()))
105-
key_type, val_type = type(sample_key), type(sample_val)
106-
107-
# Handle KTable case
108-
if value and is_struct_type(val_type):
109-
key_encoder = (
110-
make_engine_value_encoder(analyze_type_info(key_type))
111-
if is_struct_type(key_type)
112-
else make_engine_value_encoder(ANY_TYPE_INFO)
113-
)
114-
value_encoder = make_engine_value_encoder(
115-
analyze_type_info(val_type)
116-
)
117-
return [
118-
[key_encoder(k)] + value_encoder(v) for k, v in value.items()
119-
]
120-
return {key_encoder(k): value_encoder(v) for k, v in value.items()}
94+
if not isinstance(value_type_info.variant, AnalyzedStructType):
95+
raise ValueError(
96+
f"Value type for dict is required to be a struct (e.g. dataclass or NamedTuple), got {variant.value_type}. "
97+
f"If you want a free-formed dict, use `cocoindex.Json` instead."
98+
)
12199

122-
return encode_struct_dict
100+
key_encoder = make_engine_value_encoder(analyze_type_info(variant.key_type))
101+
value_encoder = make_engine_value_encoder(analyze_type_info(variant.value_type))
102+
103+
def encode_struct_dict(value: Any) -> Any:
104+
if not value:
105+
return []
106+
return [[key_encoder(k)] + value_encoder(v) for k, v in value.items()]
107+
108+
return encode_struct_dict
123109

124110
if isinstance(variant, AnalyzedStructType):
125111
struct_type = variant.struct_type
@@ -132,8 +118,8 @@ def encode_struct_dict(value: Any) -> Any:
132118
field_names = [f.name for f in fields]
133119

134120
def encode_dataclass(value: Any) -> Any:
135-
if not dataclasses.is_dataclass(value):
136-
return value
121+
if value is None:
122+
return None
137123
return [
138124
encoder(getattr(value, name))
139125
for encoder, name in zip(field_encoders, field_names)
@@ -154,8 +140,8 @@ def encode_dataclass(value: Any) -> Any:
154140
]
155141

156142
def encode_namedtuple(value: Any) -> Any:
157-
if not is_namedtuple_type(type(value)):
158-
return value
143+
if value is None:
144+
return None
159145
return [
160146
encoder(getattr(value, name))
161147
for encoder, name in zip(field_encoders, field_names)

0 commit comments

Comments
 (0)