From 3f65a59ea01cc82b8fd0558e9fd09f48a032b7be Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 29 Oct 2020 16:01:09 -0400 Subject: [PATCH] MNT: make sure we do not mutate input in Text.update We take in a dictionary (called kwargs rather than collecting kwargs) which we mutate in the method. We pop bbox and fontproperties keys out of the user supplied dictionary (to make sure the precedence and default behaviors are correct) which is propagated back out to user code. This makes an internal copy of the dictionary before we mutate it. closes #18838 --- lib/matplotlib/tests/test_text.py | 12 ++++++++++++ lib/matplotlib/text.py | 2 ++ 2 files changed, 14 insertions(+) diff --git a/lib/matplotlib/tests/test_text.py b/lib/matplotlib/tests/test_text.py index c330421a8c00..1fbbf864e25c 100644 --- a/lib/matplotlib/tests/test_text.py +++ b/lib/matplotlib/tests/test_text.py @@ -8,10 +8,12 @@ import matplotlib as mpl from matplotlib.backend_bases import MouseEvent +from matplotlib.font_manager import FontProperties import matplotlib.patches as mpatches import matplotlib.pyplot as plt import matplotlib.transforms as mtransforms from matplotlib.testing.decorators import check_figures_equal, image_comparison +from matplotlib.text import Text needs_usetex = pytest.mark.skipif( @@ -697,3 +699,13 @@ def test_transform_rotates_text(): transform_rotates_text=True) result = text.get_rotation() assert_almost_equal(result, 30) + + +def test_update_mutate_input(): + inp = dict(fontproperties=FontProperties(weight="bold"), + bbox=None) + cache = dict(inp) + t = Text() + t.update(inp) + assert inp['fontproperties'] == cache['fontproperties'] + assert inp['bbox'] == cache['bbox'] diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index 6dc50b9f2dac..78a6ad8b104c 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -172,6 +172,8 @@ def __init__(self, def update(self, kwargs): # docstring inherited + # make a copy so we do not mutate user input! + kwargs = dict(kwargs) sentinel = object() # bbox can be None, so use another sentinel. # Update fontproperties first, as it has lowest priority. fontproperties = kwargs.pop("fontproperties", sentinel)