From c555d57590719338835231d9fc7a9b937107fd6c Mon Sep 17 00:00:00 2001 From: Emily Kellison-Linn <4672118+emilykl@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:13:03 -0400 Subject: [PATCH 1/4] suppress DeprecationWarnings when updating template.data --- plotly/graph_objs/layout/_template.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plotly/graph_objs/layout/_template.py b/plotly/graph_objs/layout/_template.py index cc93069a078..3dbd6fa2fcd 100644 --- a/plotly/graph_objs/layout/_template.py +++ b/plotly/graph_objs/layout/_template.py @@ -1,6 +1,7 @@ -from plotly.basedatatypes import BaseLayoutHierarchyType as _BaseLayoutHierarchyType import copy as _copy +import warnings +from plotly.basedatatypes import BaseLayoutHierarchyType as _BaseLayoutHierarchyType class Template(_BaseLayoutHierarchyType): @@ -324,7 +325,12 @@ def __init__(self, arg=None, data=None, layout=None, **kwargs): _v = arg.pop("data", None) _v = data if data is not None else _v if _v is not None: - self["data"] = _v + # Template.data contains key for deprecated scattermapbox trace + # In order to prevent false deprecation warnings from surfacing, + # we suppress deprecation warnings for this line only + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + self["data"] = _v _v = arg.pop("layout", None) _v = layout if layout is not None else _v if _v is not None: From cf3e9012faec7e2a4f45fe8faa2bc394ef0f1ee7 Mon Sep 17 00:00:00 2001 From: Emily Kellison-Linn <4672118+emilykl@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:24:09 -0400 Subject: [PATCH 2/4] edit comment --- plotly/graph_objs/layout/_template.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plotly/graph_objs/layout/_template.py b/plotly/graph_objs/layout/_template.py index 3dbd6fa2fcd..ae33de77da2 100644 --- a/plotly/graph_objs/layout/_template.py +++ b/plotly/graph_objs/layout/_template.py @@ -325,9 +325,10 @@ def __init__(self, arg=None, data=None, layout=None, **kwargs): _v = arg.pop("data", None) _v = data if data is not None else _v if _v is not None: - # Template.data contains key for deprecated scattermapbox trace + # Template.data contains a 'scattermapbox' key, which causes a + # go.Scattermapbox trace object to be created during validation. # In order to prevent false deprecation warnings from surfacing, - # we suppress deprecation warnings for this line only + # we suppress deprecation warnings for this line only. with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self["data"] = _v From 9243f6d7760ad94a988c58bd3c0dee0531b1e5ef Mon Sep 17 00:00:00 2001 From: Emily Kellison-Linn <4672118+emilykl@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:26:20 -0400 Subject: [PATCH 3/4] add tests for mapbox deprecation warnings --- .../test_graph_objs/test_graph_objs.py | 27 +++++++++++ tests/test_optional/test_px/test_px.py | 48 ++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/tests/test_core/test_graph_objs/test_graph_objs.py b/tests/test_core/test_graph_objs/test_graph_objs.py index 8c5f62c7534..a137f4f5304 100644 --- a/tests/test_core/test_graph_objs/test_graph_objs.py +++ b/tests/test_core/test_graph_objs/test_graph_objs.py @@ -1,5 +1,7 @@ from unittest import TestCase +import warnings +import pytest import plotly.graph_objs as go @@ -154,3 +156,28 @@ def test_pop_invalid_prop_key_error(self): def test_pop_invalid_prop_with_default(self): self.assertEqual(self.layout.pop("bogus", 42), 42) + +class TestDeprecationWarnings(TestCase): + def test_warn_on_deprecated_mapbox_traces(self): + # This test will fail if any of the following traces + # fails to emit a DeprecationWarning + for trace_constructor in [ + go.Scattermapbox, + go.Densitymapbox, + go.Choroplethmapbox, + ]: + with pytest.warns(DeprecationWarning): + _ = go.Figure([trace_constructor()]) + + def test_no_warn_on_non_deprecated_traces(self): + # This test will fail if any of the following traces emits a DeprecationWarning + for trace_constructor in [ + go.Scatter, + go.Bar, + go.Scattermap, + go.Densitymap, + go.Choroplethmap, + ]: + with warnings.catch_warnings(): + warnings.simplefilter("error") + _ = go.Figure([trace_constructor()]) diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index 185dcf5afca..c2b7ce0b3b2 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -1,9 +1,11 @@ +from itertools import permutations +import warnings + import plotly.express as px import plotly.io as pio import narwhals.stable.v1 as nw import numpy as np import pytest -from itertools import permutations def test_scatter(backend): @@ -394,3 +396,47 @@ def test_load_px_data(return_type): else: df = getattr(px.data, fname)(return_type=return_type) assert len(df) > 0 + + +def test_warn_on_deprecated_mapbox_px_constructors(): + # This test will fail if any of the following px constructors + # fails to emit a DeprecationWarning + for fig_constructor in [ + px.line_mapbox, + px.scatter_mapbox, + px.density_mapbox, + px.choropleth_mapbox, + ]: + # Look for warnings with the string "_mapbox" in them + # to make sure the warning is coming from px rather than go + with pytest.warns(DeprecationWarning, match="_mapbox"): + if fig_constructor == px.choropleth_mapbox: + fig_constructor(locations=["CA", "TX", "NY"]) + else: + fig_constructor(lat=[10, 20, 30], lon=[10, 20, 30]) + +def test_no_warn_on_non_deprecated_px_constructors(): + # This test will fail if any of the following px constructors + # emits a DeprecationWarning + for fig_constructor in [ + px.scatter, + px.line, + px.scatter_map, + px.density_map, + px.choropleth_map, + ]: + with warnings.catch_warnings(): + warnings.simplefilter("error") + if fig_constructor == px.choropleth_map: + fig_constructor(locations=["CA", "TX", "NY"]) + elif fig_constructor in {px.scatter_map, px.density_map}: + fig_constructor(lat=[10, 20, 30], lon=[10, 20, 30]) + else: + fig_constructor(x=[1, 2, 3], y=[1, 2, 3]) + +def test_no_warn_on_update_template(): + # This test will fail if update_layout(template=...) emits a DeprecationWarning + fig = px.line(x=[1, 2, 3], y=[1, 2, 3]) + with warnings.catch_warnings(): + warnings.simplefilter("error") + fig.update_layout(template="plotly_white") From 2a0241d653d6080950e19295baeb551cc0c7e623 Mon Sep 17 00:00:00 2001 From: Emily Kellison-Linn <4672118+emilykl@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:38:30 -0400 Subject: [PATCH 4/4] format --- plotly/graph_objs/layout/_template.py | 2 +- tests/test_core/test_graph_objs/test_graph_objs.py | 2 +- tests/test_optional/test_px/test_px.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plotly/graph_objs/layout/_template.py b/plotly/graph_objs/layout/_template.py index ae33de77da2..69f6cf38ec5 100644 --- a/plotly/graph_objs/layout/_template.py +++ b/plotly/graph_objs/layout/_template.py @@ -3,8 +3,8 @@ from plotly.basedatatypes import BaseLayoutHierarchyType as _BaseLayoutHierarchyType -class Template(_BaseLayoutHierarchyType): +class Template(_BaseLayoutHierarchyType): # class properties # -------------------- _parent_path_str = "layout" diff --git a/tests/test_core/test_graph_objs/test_graph_objs.py b/tests/test_core/test_graph_objs/test_graph_objs.py index a137f4f5304..5b0e3dbbdf7 100644 --- a/tests/test_core/test_graph_objs/test_graph_objs.py +++ b/tests/test_core/test_graph_objs/test_graph_objs.py @@ -48,7 +48,6 @@ class TestBackwardsCompat(TestCase): def test_old_class_names(self): - # these were all defined at one point, we want to maintain backwards # compat, so we basically just create a checkpoint with this test. @@ -157,6 +156,7 @@ def test_pop_invalid_prop_key_error(self): def test_pop_invalid_prop_with_default(self): self.assertEqual(self.layout.pop("bogus", 42), 42) + class TestDeprecationWarnings(TestCase): def test_warn_on_deprecated_mapbox_traces(self): # This test will fail if any of the following traces diff --git a/tests/test_optional/test_px/test_px.py b/tests/test_optional/test_px/test_px.py index c2b7ce0b3b2..3a8ddabcd0a 100644 --- a/tests/test_optional/test_px/test_px.py +++ b/tests/test_optional/test_px/test_px.py @@ -415,6 +415,7 @@ def test_warn_on_deprecated_mapbox_px_constructors(): else: fig_constructor(lat=[10, 20, 30], lon=[10, 20, 30]) + def test_no_warn_on_non_deprecated_px_constructors(): # This test will fail if any of the following px constructors # emits a DeprecationWarning @@ -434,6 +435,7 @@ def test_no_warn_on_non_deprecated_px_constructors(): else: fig_constructor(x=[1, 2, 3], y=[1, 2, 3]) + def test_no_warn_on_update_template(): # This test will fail if update_layout(template=...) emits a DeprecationWarning fig = px.line(x=[1, 2, 3], y=[1, 2, 3])