Skip to content

Commit 8c38313

Browse files
ionmincuclaude
andauthored
fix: handle unserializable objects in serialize_defaults (#1527)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b31d876 commit 8c38313

6 files changed

Lines changed: 36 additions & 6 deletions

File tree

packages/uipath-core/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-core"
3-
version = "0.5.9"
3+
version = "0.5.10"
44
description = "UiPath Core abstractions"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

packages/uipath-core/src/uipath/core/serialization/json.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ def serialize_defaults(
6767
>>> serialize_json(user)
6868
'{"name": "Alice", "created_at": "2024-01-01T12:00:00"}'
6969
"""
70+
try:
71+
return _serialize_defaults_inner(obj)
72+
except Exception:
73+
return str(obj)
74+
75+
76+
def _serialize_defaults_inner(
77+
obj: Any,
78+
) -> dict[str, Any] | list[Any] | str | int | float | bool | None:
7079
# Handle Pydantic BaseModel instances
7180
if hasattr(obj, "model_dump") and not isinstance(obj, type):
7281
return obj.model_dump(exclude_none=True, mode="json")
@@ -97,7 +106,7 @@ def serialize_defaults(
97106

98107
# Handle enums - recursively serialize the value
99108
if isinstance(obj, Enum):
100-
return serialize_defaults(obj.value)
109+
return _serialize_defaults_inner(obj.value)
101110

102111
# Handle sets and tuples
103112
if isinstance(obj, (set, tuple)):

packages/uipath-core/tests/serialization/test_json.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,24 @@ def __str__(self) -> str:
636636

637637
# Seventh sublist: Booleans and None
638638
assert parsed[6] == [True, False, None]
639+
640+
def test_dataclass_with_unpicklable_field_falls_back_to_str(self) -> None:
641+
"""Test dataclass containing unpicklable objects (e.g. SimpleQueue) falls back to str().
642+
643+
dataclasses.asdict() uses copy.deepcopy internally, which fails on objects
644+
that cannot be pickled (like _queue.SimpleQueue found in httpx clients).
645+
The serializer should gracefully fall back to str() instead of raising.
646+
"""
647+
import queue
648+
649+
@dataclass
650+
class DataclassWithQueue:
651+
name: str
652+
internal: Any
653+
654+
obj = DataclassWithQueue(name="test", internal=queue.SimpleQueue())
655+
data = {"obj": obj}
656+
result = serialize_json(data)
657+
parsed = json.loads(result)
658+
assert isinstance(parsed["obj"], str)
659+
assert "DataclassWithQueue" in parsed["obj"]

packages/uipath-core/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/uipath-platform/uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/uipath/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)