Skip to content

Commit ac79078

Browse files
Nova (SFK)claude
andcommitted
fix: handle types.UnionType in from_dict_deep, fix missed List reference
On Python 3.10-3.12, the `X | Y` syntax creates a `types.UnionType` which is distinct from `typing.Union`. The `from_dict_deep` method in `SerializableDataClass` only checked for `typing.Union` via `get_origin`, so it failed to deserialize union-typed fields when the annotation used pipe syntax (e.g. `PromptBlockData`). Also fixes a missed `cast(List, ...)` → `cast(list, ...)` in langchain test_callbacks.py that caused a pylint E0602. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 010af87 commit ac79078

2 files changed

Lines changed: 3 additions & 2 deletions

File tree

py/src/braintrust/integrations/langchain/test_callbacks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def test_parallel_execution(logger_memory_logger):
399399

400400
map_chain.invoke({"topic": "bear"}, config={"callbacks": [cast(BaseCallbackHandler, handler)]})
401401

402-
spans = cast(List, memory_logger.pop())
402+
spans = cast(list, memory_logger.pop())
403403

404404
# Find the LLM spans
405405
llm_spans = find_spans_by_attributes(spans, name="ChatOpenAI")

py/src/braintrust/serializable_data_class.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import dataclasses
22
import json
3+
import types
34
from typing import Union, get_origin
45

56

@@ -39,7 +40,7 @@ def from_dict_deep(cls, d: dict):
3940
and issubclass(fields[k].type, SerializableDataClass)
4041
):
4142
filtered[k] = fields[k].type.from_dict_deep(v)
42-
elif get_origin(fields[k].type) == Union:
43+
elif get_origin(fields[k].type) is Union or isinstance(fields[k].type, types.UnionType):
4344
for t in fields[k].type.__args__:
4445
if t == type(None) and v is None:
4546
filtered[k] = None

0 commit comments

Comments
 (0)