Skip to content

Commit 958301d

Browse files
authored
Fix bug in reconstructing layered charts with from_json/from_dict (#3068)
* Fix for when subcharts do not have layer_props * Test the to_json and from_json methods using all examples in the gallery
1 parent e2e2a5b commit 958301d

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

altair/vegalite/v5/api.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,9 +3395,12 @@ def remove_prop(subchart, prop):
33953395
else:
33963396
raise ValueError(f"There are inconsistent values {values} for {prop}")
33973397
else:
3398-
# Top level has this prop; subchart props must be either
3399-
# Undefined or identical to proceed.
3400-
if all(c[prop] is Undefined or c[prop] == chart[prop] for c in subcharts):
3398+
# Top level has this prop; subchart must either not have the prop
3399+
# or it must be Undefined or identical to proceed.
3400+
if all(
3401+
getattr(c, prop, Undefined) is Undefined or c[prop] == chart[prop]
3402+
for c in subcharts
3403+
):
34013404
output_dict[prop] = chart[prop]
34023405
else:
34033406
raise ValueError(f"There are inconsistent values {values} for {prop}")

tests/test_examples.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import pytest
55

6+
import altair as alt
67
from altair.utils.execeval import eval_block
78
from tests import examples_arguments_syntax
89
from tests import examples_methods_syntax
@@ -48,6 +49,39 @@ def test_render_examples_to_chart(syntax_module):
4849
) from err
4950

5051

52+
@pytest.mark.parametrize(
53+
"syntax_module", [examples_arguments_syntax, examples_methods_syntax]
54+
)
55+
def test_from_and_to_json_roundtrip(syntax_module):
56+
"""Tests if the to_json and from_json (and by extension to_dict and from_dict)
57+
work for all examples in the Example Gallery.
58+
"""
59+
for filename in iter_examples_filenames(syntax_module):
60+
source = pkgutil.get_data(syntax_module.__name__, filename)
61+
chart = eval_block(source)
62+
63+
if chart is None:
64+
raise ValueError(
65+
f"Example file {filename} should define chart in its final "
66+
"statement."
67+
)
68+
69+
try:
70+
first_json = chart.to_json()
71+
reconstructed_chart = alt.Chart.from_json(first_json)
72+
# As the chart objects are not
73+
# necessarily the same - they could use different objects to encode the same
74+
# information - we do not test for equality of the chart objects, but rather
75+
# for equality of the json strings.
76+
second_json = reconstructed_chart.to_json()
77+
assert first_json == second_json
78+
except Exception as err:
79+
raise AssertionError(
80+
f"Example file {filename} raised an exception when "
81+
f"doing a json conversion roundtrip: {err}"
82+
) from err
83+
84+
5185
# We do not apply the save_engine mark to this test. This mark is used in
5286
# the build GitHub Action workflow to select the tests which should be rerun
5387
# with some of the saving engines uninstalled. This would not make sense for this test

0 commit comments

Comments
 (0)