Skip to content

Commit 645ee13

Browse files
committed
Fixed crash when serializing dict with mix of string and int keys
by not sorting keys (in either json engine) Add orjson OPT_NON_STR_KEYS and remove manual string conversion
1 parent 0a83329 commit 645ee13

File tree

3 files changed

+11
-6
lines changed

3 files changed

+11
-6
lines changed

packages/python/plotly/plotly/io/_json.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
112112
# Dump to a JSON string and return
113113
# --------------------------------
114114
if engine == "json":
115-
opts = {"sort_keys": True}
115+
opts = {}
116116
if pretty:
117117
opts["indent"] = 2
118118
else:
@@ -124,7 +124,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
124124
return json.dumps(plotly_object, cls=PlotlyJSONEncoder, **opts)
125125
elif engine == "orjson":
126126
JsonConfig.validate_orjson()
127-
opts = orjson.OPT_SORT_KEYS | orjson.OPT_SERIALIZE_NUMPY
127+
opts = orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY
128128

129129
if pretty:
130130
opts |= orjson.OPT_INDENT_2
@@ -462,7 +462,7 @@ def clean_to_json_compatible(obj, **kwargs):
462462
return obj
463463

464464
if isinstance(obj, dict):
465-
return {str(k): clean_to_json_compatible(v, **kwargs) for k, v in obj.items()}
465+
return {k: clean_to_json_compatible(v, **kwargs) for k, v in obj.items()}
466466
elif isinstance(obj, (list, tuple)):
467467
if obj:
468468
# Must process list recursively even though it may be slow

packages/python/plotly/plotly/tests/test_io/test_to_from_json.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ def fig1(request):
2929
opts = {
3030
"separators": (",", ":"),
3131
"cls": plotly.utils.PlotlyJSONEncoder,
32-
"sort_keys": True,
3332
}
34-
pretty_opts = {"indent": 2, "cls": plotly.utils.PlotlyJSONEncoder, "sort_keys": True}
33+
pretty_opts = {"indent": 2, "cls": plotly.utils.PlotlyJSONEncoder}
3534

3635

3736
# to_json

packages/python/plotly/plotly/tests/test_io/test_to_from_plotly_json.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def datetime_array(request, datetime_value):
135135
def test_graph_object_input(engine, pretty):
136136
scatter = go.Scatter(x=[1, 2, 3], y=np.array([4, 5, 6]))
137137
result = pio.to_json_plotly(scatter, engine=engine)
138-
expected = """{"type":"scatter","x":[1,2,3],"y":[4,5,6]}"""
138+
expected = """{"x":[1,2,3],"y":[4,5,6],"type":"scatter"}"""
139139
assert result == expected
140140
check_roundtrip(result, engine=engine, pretty=pretty)
141141

@@ -215,3 +215,9 @@ def test_nonstring_key(engine, pretty):
215215
value = build_test_dict({0: 1})
216216
result = pio.to_json_plotly(value, engine=engine)
217217
check_roundtrip(result, engine=engine, pretty=pretty)
218+
219+
220+
def test_mixed_string_nonstring_key(engine, pretty):
221+
value = build_test_dict({0: 1, "a": 2})
222+
result = pio.to_json_plotly(value, engine=engine)
223+
check_roundtrip(result, engine=engine, pretty=pretty)

0 commit comments

Comments
 (0)