From bf4b03e878cdecbca08f2e7ad1983961a227801b Mon Sep 17 00:00:00 2001 From: Kevin Eger Date: Wed, 21 Jan 2026 18:15:59 +0000 Subject: [PATCH 1/5] Set the 'colab' renderer only for Colab web notebooks The current implementation detects if the `google.colab` module is available. This has a couple problems: 1. Anyone can install that library, outside of Colab. 2. The recently launched [Colab VS Code extension](https://marketplace.visualstudio.com/items?itemName=Google.colab) does not work with that web-based renderer. Snapping to the conventions used for the other notebooks/renderers (e.g. Kaggle, Azure), this change now looks for the presence of the `COLAB_NOTEBOOK_ID` environment variable. I'm an engineer on Colab and have verified that we set this on kernel init for all notebooks accessed through our web app (https://colab.research.google.com/). More context in https://github.com/plotly/plotly.py/issues/5471. --- plotly/io/_renderers.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plotly/io/_renderers.py b/plotly/io/_renderers.py index 4c21760bb0a..8eea1fe8bf8 100644 --- a/plotly/io/_renderers.py +++ b/plotly/io/_renderers.py @@ -488,13 +488,10 @@ def show(fig, renderer=None, validate=True, **kwargs): elif ipython and ipython.get_ipython(): # Try to detect environment so that we can enable a useful # default renderer - if not default_renderer: - try: - import google.colab # noqa: F401 - default_renderer = "colab" - except ImportError: - pass + # Check if we're running in a Colab web notebook + if not default_renderer and "COLAB_NOTEBOOK_ID" in os.environ: + default_renderer = "colab" # Check if we're running in a Kaggle notebook if not default_renderer and os.path.exists("/kaggle/input"): From 63188317c3f4b7a4b8d3d097cf062f935e8c7a0f Mon Sep 17 00:00:00 2001 From: Kevin Eger Date: Tue, 21 Apr 2026 17:07:31 +0000 Subject: [PATCH 2/5] test and changelog entry --- CHANGELOG.md | 1 + tests/test_io/test_renderers.py | 76 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 126ff280b49..954a41e8acc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Fixed +- Fix Colab renderer detection to use `COLAB_NOTEBOOK_ID` env var instead of importing `google.colab`, so the `colab` renderer is only set for Colab web notebooks and not for other environments like the Colab VS Code extension [[#5473](https://github.com/plotly/plotly.py/pull/5473)] - Fix issue where user-specified `color_continuous_scale` was ignored when template had `autocolorscale=True` [[#5439](https://github.com/plotly/plotly.py/pull/5439)], with thanks to @antonymilne for the contribution! - Update tests to be compatible with numpy 2.4 [[#5522](https://github.com/plotly/plotly.py/pull/5522)], with thanks to @thunze for the contribution! diff --git a/tests/test_io/test_renderers.py b/tests/test_io/test_renderers.py index ac204d5d9eb..51abac6f4d0 100644 --- a/tests/test_io/test_renderers.py +++ b/tests/test_io/test_renderers.py @@ -1,4 +1,5 @@ import json +import os import threading import time @@ -418,3 +419,78 @@ def test_missing_webbrowser_methods(fig1): finally: # restore everything after this test webbrowser.get = removed_webbrowser_get_method + + +def test_colab_renderer_when_env_var_is_set(): + """ + When COLAB_NOTEBOOK_ID is present the default renderer should be 'colab'. + """ + import importlib + import plotly.io._renderers as _renderers_mod + from plotly import optional_imports + + fake_ipython = MagicMock() + original_get_module = optional_imports.get_module + + def patched_get_module(name, *args, **kwargs): + if name in ("IPython", "IPython.display"): + return fake_ipython + return original_get_module(name, *args, **kwargs) + + original_default = pio.renderers.default + try: + with mock.patch.dict(os.environ, {"COLAB_NOTEBOOK_ID": "fake-id"}, clear=True): + with mock.patch.object( + optional_imports, "get_module", side_effect=patched_get_module + ): + importlib.reload(_renderers_mod) + assert _renderers_mod.renderers.default == "colab" + finally: + importlib.reload(_renderers_mod) + pio.renderers.default = original_default + + +def test_colab_renderer_when_env_var_is_absent(): + """ + Without COLAB_NOTEBOOK_ID the default renderer must not be 'colab', + even when ``google.colab`` is importable. The old detection used + ``import google.colab`` which wrongly activated the colab renderer + in environments that merely had the package installed (e.g. the + Colab VS Code extension). + + Regression test for https://github.com/plotly/plotly.py/pull/5473. + """ + import sys + import types + import importlib + import plotly.io._renderers as _renderers_mod + from plotly import optional_imports + + fake_ipython = MagicMock() + original_get_module = optional_imports.get_module + + def patched_get_module(name, *args, **kwargs): + if name in ("IPython", "IPython.display"): + return fake_ipython + return original_get_module(name, *args, **kwargs) + + # Make google.colab importable so the old ``import google.colab`` + # approach would have chosen the colab renderer here. + fake_google = types.ModuleType("google") + fake_google_colab = types.ModuleType("google.colab") + + original_default = pio.renderers.default + try: + with mock.patch.dict(os.environ, {}, clear=True): + with mock.patch.dict( + sys.modules, + {"google": fake_google, "google.colab": fake_google_colab}, + ): + with mock.patch.object( + optional_imports, "get_module", side_effect=patched_get_module + ): + importlib.reload(_renderers_mod) + assert _renderers_mod.renderers.default != "colab" + finally: + importlib.reload(_renderers_mod) + pio.renderers.default = original_default From 5cf19147d8c048ae3a799ec51b6ac8c56d6b47d2 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Tue, 21 Apr 2026 16:29:42 -0600 Subject: [PATCH 3/5] Trim some text from the test description --- tests/test_io/test_renderers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_io/test_renderers.py b/tests/test_io/test_renderers.py index 51abac6f4d0..73ce23bd78a 100644 --- a/tests/test_io/test_renderers.py +++ b/tests/test_io/test_renderers.py @@ -453,10 +453,7 @@ def patched_get_module(name, *args, **kwargs): def test_colab_renderer_when_env_var_is_absent(): """ Without COLAB_NOTEBOOK_ID the default renderer must not be 'colab', - even when ``google.colab`` is importable. The old detection used - ``import google.colab`` which wrongly activated the colab renderer - in environments that merely had the package installed (e.g. the - Colab VS Code extension). + even when ``google.colab`` is importable. Regression test for https://github.com/plotly/plotly.py/pull/5473. """ From 3890d22aeae347e86e258d9843fb40a99163a8ea Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Tue, 21 Apr 2026 16:29:57 -0600 Subject: [PATCH 4/5] Rewrite changelog message and add attribution --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 954a41e8acc..d47e78122c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Fixed -- Fix Colab renderer detection to use `COLAB_NOTEBOOK_ID` env var instead of importing `google.colab`, so the `colab` renderer is only set for Colab web notebooks and not for other environments like the Colab VS Code extension [[#5473](https://github.com/plotly/plotly.py/pull/5473)] +- Use presence of `COLAB_NOTEBOOK_ID` env var to enable Colab renderer instead of testing import of `google.colab` [[#5473](https://github.com/plotly/plotly.py/pull/5473)], with thanks to @kevineger for the contribution! - Fix issue where user-specified `color_continuous_scale` was ignored when template had `autocolorscale=True` [[#5439](https://github.com/plotly/plotly.py/pull/5439)], with thanks to @antonymilne for the contribution! - Update tests to be compatible with numpy 2.4 [[#5522](https://github.com/plotly/plotly.py/pull/5522)], with thanks to @thunze for the contribution! From b0e46d3b6f5cc02bcfd703f4b3110c57c8b76cf6 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Tue, 21 Apr 2026 16:31:23 -0600 Subject: [PATCH 5/5] Fix order of changelog entries --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d47e78122c4..23b6b561af3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Fixed -- Use presence of `COLAB_NOTEBOOK_ID` env var to enable Colab renderer instead of testing import of `google.colab` [[#5473](https://github.com/plotly/plotly.py/pull/5473)], with thanks to @kevineger for the contribution! - Fix issue where user-specified `color_continuous_scale` was ignored when template had `autocolorscale=True` [[#5439](https://github.com/plotly/plotly.py/pull/5439)], with thanks to @antonymilne for the contribution! +- Use presence of `COLAB_NOTEBOOK_ID` env var to enable Colab renderer instead of testing import of `google.colab` [[#5473](https://github.com/plotly/plotly.py/pull/5473)], with thanks to @kevineger for the contribution! - Update tests to be compatible with numpy 2.4 [[#5522](https://github.com/plotly/plotly.py/pull/5522)], with thanks to @thunze for the contribution! ### Updated