Repository: altair-viz/altair
Pull request #800 (2018-05-01 16:14:58)

MAINT: fix handling of display metadata
I realized that mimebundle metadata should be passed with the same mimetype key as the main data. This PR fixes that.

It also cleans up the way that display functions are defined.


Patch:
diff --git a/altair/utils/display.py b/altair/utils/display.py
index 49d8f97b..3841b803 100644
--- a/altair/utils/display.py
+++ b/altair/utils/display.py
@@ -70,26 +70,27 @@ class Displayable(object):
             return {}
 
 
-def default_renderer(spec, mime_type, str_repr, **metadata):
-    """A default renderer for VegaLite 1/2 that works for modern frontends.
+def default_renderer_base(spec, mime_type, str_repr, **options):
+    """A default renderer for Vega or VegaLite that works for modern frontends.
 
     This renderer works with modern frontends (JupyterLab, nteract) that know
     how to render the custom VegaLite MIME type listed above.
     """
     assert isinstance(spec, dict)
     bundle = {}
-    bundle['text/plain'] = str_repr
+    metadata = {}
+
     bundle[mime_type] = spec
+    bundle['text/plain'] = str_repr
+    if options:
+        metadata[mime_type] = options
     return bundle, metadata
 
 
-def json_renderer(spec, str_repr, **metadata):
+def json_renderer_base(spec, str_repr, **options):
     """A renderer that returns a MIME type of application/json.
 
     In JupyterLab/nteract this is rendered as a nice JSON tree.
     """
-    assert isinstance(spec, dict)
-    bundle = {}
-    bundle['text/plain'] = str_repr
-    bundle['application/json'] = spec
-    return bundle, metadata
+    return default_renderer_base(spec, mime_type='application/json',
+                                 str_repr=str_repr, **options)
diff --git a/altair/vega/display.py b/altair/vega/display.py
index 80f5d654..2be6e0c4 100644
--- a/altair/vega/display.py
+++ b/altair/vega/display.py
@@ -1,11 +1,11 @@
-from ..utils.display import Displayable, default_renderer, json_renderer
+from ..utils.display import Displayable, default_renderer_base, json_renderer_base
 from ..utils.display import MimeBundleType, RendererType
 
 
 __all__ = (
     "Displayable",
-    "default_renderer",
-    "json_renderer",
+    "default_renderer_base",
+    "json_renderer_base",
     "MimeBundleType",
     "RendererType"
 )
diff --git a/altair/vega/v2/display.py b/altair/vega/v2/display.py
index eb667f13..a4a1584c 100644
--- a/altair/vega/v2/display.py
+++ b/altair/vega/v2/display.py
@@ -2,8 +2,8 @@ import os
 
 from ...utils import PluginRegistry
 from ..display import Displayable
-from ..display import default_renderer as default_renderer_base
-from ..display import json_renderer as json_renderer_base
+from ..display import default_renderer_base
+from ..display import json_renderer_base
 from ..display import RendererType
 
 
diff --git a/altair/vega/v3/display.py b/altair/vega/v3/display.py
index 0ae582ad..e3e65d73 100644
--- a/altair/vega/v3/display.py
+++ b/altair/vega/v3/display.py
@@ -2,8 +2,8 @@ import os
 
 from ...utils import PluginRegistry
 from ..display import Displayable
-from ..display import default_renderer as default_renderer_base
-from ..display import json_renderer as json_renderer_base
+from ..display import default_renderer_base
+from ..display import json_renderer_base
 from ..display import RendererType
 
 
diff --git a/altair/vegalite/display.py b/altair/vegalite/display.py
index 3c62ca7e..db0fe43c 100644
--- a/altair/vegalite/display.py
+++ b/altair/vegalite/display.py
@@ -1,10 +1,10 @@
-from ..utils.display import Displayable, default_renderer, json_renderer
+from ..utils.display import Displayable, default_renderer_base, json_renderer_base
 from ..utils.display import RendererRegistry
 
 
 __all__ = (
     "Displayable",
-    "default_renderer",
-    "json_renderer",
+    "default_renderer_base",
+    "json_renderer_base",
     "RendererRegistry"
 )
diff --git a/altair/vegalite/v1/display.py b/altair/vegalite/v1/display.py
index 15a49f0c..8d9b6a75 100644
--- a/altair/vegalite/v1/display.py
+++ b/altair/vegalite/v1/display.py
@@ -3,8 +3,8 @@ import os
 from ...utils.mimebundle import spec_to_mimebundle
 
 from ..display import Displayable
-from ..display import default_renderer as default_renderer_base
-from ..display import json_renderer as json_renderer_base
+from ..display import default_renderer_base
+from ..display import json_renderer_base
 from ..display import RendererRegistry
 
 from .schema import SCHEMA_VERSION
diff --git a/altair/vegalite/v2/display.py b/altair/vegalite/v2/display.py
index a1bb5d44..323c0322 100644
--- a/altair/vegalite/v2/display.py
+++ b/altair/vegalite/v2/display.py
@@ -2,8 +2,8 @@ import os
 
 from ...utils.mimebundle import spec_to_mimebundle
 from ..display import Displayable
-from ..display import default_renderer as default_renderer_base
-from ..display import json_renderer as json_renderer_base
+from ..display import default_renderer_base
+from ..display import json_renderer_base
 from ..display import RendererRegistry
 
 from .schema import SCHEMA_VERSION


Test patch:
diff --git a/altair/vegalite/v2/tests/test_renderers.py b/altair/vegalite/v2/tests/test_renderers.py
index 7cad241a..1d800ef4 100644
--- a/altair/vegalite/v2/tests/test_renderers.py
+++ b/altair/vegalite/v2/tests/test_renderers.py
@@ -25,15 +25,35 @@ def test_colab_renderer_embed_options(chart):
                 'embed_opt = {"mode": "vega-lite", "actions": true}' in html)
 
 
-# TODO: test notebook renderer here when it supports metadata
-@pytest.mark.parametrize('renderer', ['default'])
-def test_default_renderer_embed_options(chart, renderer):
+def test_default_renderer_embed_options(chart, renderer='default'):
     # check that metadata is passed appropriately
+    mimetype = alt.display.VEGALITE_MIME_TYPE
+    spec = chart.to_dict()
     with alt.renderers.enable(renderer, embed_options=dict(actions=False)):
         bundle, metadata = chart._repr_mimebundle_(None, None)
-        assert metadata == {'embed_options': {'actions': False}}
+        assert set(bundle.keys()) == {mimetype, 'text/plain'}
+        assert bundle[mimetype] == spec
+        assert metadata == {mimetype: {'embed_options': {'actions': False}}}
 
     # Sanity check: no metadata specified
     with alt.renderers.enable(renderer):
         bundle, metadata = chart._repr_mimebundle_(None, None)
+        assert bundle[mimetype] == spec
+        assert metadata == {}
+
+
+def test_json_renderer_embed_options(chart, renderer='json'):
+    """Test that embed_options in renderer metadata are correctly manifest in html"""
+    mimetype = 'application/json'
+    spec = chart.to_dict()
+    with alt.renderers.enable('json', option='foo'):
+        bundle, metadata = chart._repr_mimebundle_(None, None)
+        assert set(bundle.keys()) == {mimetype, 'text/plain'}
+        assert bundle[mimetype] == spec
+        assert metadata == {mimetype: {'option': 'foo'}}
+
+    # Sanity check: no options specified
+    with alt.renderers.enable(renderer):
+        bundle, metadata = chart._repr_mimebundle_(None, None)
+        assert bundle[mimetype] == spec
         assert metadata == {}