From 9fd9a42625e0aa3c223d5ecf0ccc15ff20efc107 Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Tue, 9 Jan 2024 17:59:38 -0600 Subject: [PATCH 1/4] Prepare for Pytest v8 The behavior of pytest.warns has changed, particularly with regards to handling of additional warnings --- lib/matplotlib/tests/test_backend_pdf.py | 4 ++++ lib/matplotlib/tests/test_colors.py | 3 +-- lib/matplotlib/tests/test_rcparams.py | 6 ++---- lib/matplotlib/tests/test_ticker.py | 4 ++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/tests/test_backend_pdf.py b/lib/matplotlib/tests/test_backend_pdf.py index ae17c7a4a4e3..e6cdc34d452d 100644 --- a/lib/matplotlib/tests/test_backend_pdf.py +++ b/lib/matplotlib/tests/test_backend_pdf.py @@ -3,6 +3,7 @@ import io import os from pathlib import Path +import warnings import numpy as np import pytest @@ -84,6 +85,9 @@ def test_multipage_keep_empty(tmp_path): os.chdir(tmp_path) # test empty pdf files + # Due to order of `with` block execution, a warning for unclosed file is raised + # but the pytest.warns must happen before the PdfPages is created + warnings.filterwarnings("ignore", category=ResourceWarning) # an empty pdf is left behind with keep_empty unset with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 139efbe17407..73afc1da8a37 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -147,8 +147,7 @@ def test_double_register_builtin_cmap(): with pytest.raises(ValueError, match='A colormap named "viridis"'): with pytest.warns(mpl.MatplotlibDeprecationWarning): cm.register_cmap(name, mpl.colormaps[name]) - with pytest.warns(UserWarning): - # TODO is warning more than once! + with pytest.warns(UserWarning), pytest.warns(mpl.MatplotlibDeprecationWarning): cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index e3e10145533d..782c390c9462 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -106,14 +106,12 @@ def test_rcparams_update(): rc = mpl.RcParams({'figure.figsize': (3.5, 42)}) bad_dict = {'figure.figsize': (3.5, 42, 1)} # make sure validation happens on input - with pytest.raises(ValueError), \ - pytest.warns(UserWarning, match="validate"): + with pytest.raises(ValueError): rc.update(bad_dict) def test_rcparams_init(): - with pytest.raises(ValueError), \ - pytest.warns(UserWarning, match="validate"): + with pytest.raises(ValueError): mpl.RcParams({'figure.figsize': (3.5, 42, 1)}) diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 12eafba9ea2b..1e15bade5d59 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -3,6 +3,7 @@ import locale import logging import re +import warnings import numpy as np from numpy.testing import assert_almost_equal, assert_array_equal @@ -914,6 +915,9 @@ def test_mathtext_ticks(self): 'axes.formatter.use_mathtext': False }) + # Glyph warning unrelated + warnings.filterwarnings("ignore", category=UserWarning, message="Glyph 8722") + with pytest.warns(UserWarning, match='cmr10 font should ideally'): fig, ax = plt.subplots() ax.set_xticks([-1, 0, 1]) From 1f53454fe290092be28e301ec651fd9dce87dd09 Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Thu, 11 Jan 2024 13:58:43 -0600 Subject: [PATCH 2/4] Use context manager to supress certain warnings --- lib/matplotlib/tests/test_backend_pdf.py | 71 ++++++++++++------------ lib/matplotlib/tests/test_colors.py | 8 ++- lib/matplotlib/tests/test_ticker.py | 13 +++-- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/lib/matplotlib/tests/test_backend_pdf.py b/lib/matplotlib/tests/test_backend_pdf.py index e6cdc34d452d..f6497bc01c78 100644 --- a/lib/matplotlib/tests/test_backend_pdf.py +++ b/lib/matplotlib/tests/test_backend_pdf.py @@ -87,41 +87,42 @@ def test_multipage_keep_empty(tmp_path): # test empty pdf files # Due to order of `with` block execution, a warning for unclosed file is raised # but the pytest.warns must happen before the PdfPages is created - warnings.filterwarnings("ignore", category=ResourceWarning) - - # an empty pdf is left behind with keep_empty unset - with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: - pass - assert os.path.exists("a.pdf") - - # an empty pdf is left behind with keep_empty=True - with pytest.warns(mpl.MatplotlibDeprecationWarning), \ - PdfPages("b.pdf", keep_empty=True) as pdf: - pass - assert os.path.exists("b.pdf") - - # an empty pdf deletes itself afterwards with keep_empty=False - with PdfPages("c.pdf", keep_empty=False) as pdf: - pass - assert not os.path.exists("c.pdf") - - # test pdf files with content, they should never be deleted - - # a non-empty pdf is left behind with keep_empty unset - with PdfPages("d.pdf") as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("d.pdf") - - # a non-empty pdf is left behind with keep_empty=True - with pytest.warns(mpl.MatplotlibDeprecationWarning), \ - PdfPages("e.pdf", keep_empty=True) as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("e.pdf") - - # a non-empty pdf is left behind with keep_empty=False - with PdfPages("f.pdf", keep_empty=False) as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("f.pdf") + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=ResourceWarning) + + # an empty pdf is left behind with keep_empty unset + with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: + pass + assert os.path.exists("a.pdf") + + # an empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("b.pdf", keep_empty=True) as pdf: + pass + assert os.path.exists("b.pdf") + + # an empty pdf deletes itself afterwards with keep_empty=False + with PdfPages("c.pdf", keep_empty=False) as pdf: + pass + assert not os.path.exists("c.pdf") + + # test pdf files with content, they should never be deleted + + # a non-empty pdf is left behind with keep_empty unset + with PdfPages("d.pdf") as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("d.pdf") + + # a non-empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("e.pdf", keep_empty=True) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("e.pdf") + + # a non-empty pdf is left behind with keep_empty=False + with PdfPages("f.pdf", keep_empty=False) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("f.pdf") def test_composite_image(): diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 73afc1da8a37..b8f381f91082 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -1,6 +1,7 @@ import copy import itertools import unittest.mock +import warnings from io import BytesIO import numpy as np @@ -147,8 +148,11 @@ def test_double_register_builtin_cmap(): with pytest.raises(ValueError, match='A colormap named "viridis"'): with pytest.warns(mpl.MatplotlibDeprecationWarning): cm.register_cmap(name, mpl.colormaps[name]) - with pytest.warns(UserWarning), pytest.warns(mpl.MatplotlibDeprecationWarning): - cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=mpl.MatplotlibDeprecationWarning) + with pytest.warns(UserWarning): + cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) def test_unregister_builtin_cmap(): diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 1e15bade5d59..67e3764f0d2c 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -916,12 +916,15 @@ def test_mathtext_ticks(self): }) # Glyph warning unrelated - warnings.filterwarnings("ignore", category=UserWarning, message="Glyph 8722") + with warnings.catch_warnings(): + warnings.filterwarnings( + "ignore", category=UserWarning, message="Glyph 8722" + ) - with pytest.warns(UserWarning, match='cmr10 font should ideally'): - fig, ax = plt.subplots() - ax.set_xticks([-1, 0, 1]) - fig.canvas.draw() + with pytest.warns(UserWarning, match='cmr10 font should ideally'): + fig, ax = plt.subplots() + ax.set_xticks([-1, 0, 1]) + fig.canvas.draw() def test_cmr10_substitutions(self, caplog): mpl.rcParams.update({ From bd3a6f17db490f54fd589af04ad0000d5768386d Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Thu, 11 Jan 2024 15:33:21 -0600 Subject: [PATCH 3/4] Version gate instead of ignoring, fix PDF to always properly close empty files --- lib/matplotlib/backends/backend_pdf.py | 3 +- lib/matplotlib/tests/test_backend_pdf.py | 73 +++++++++++------------- lib/matplotlib/tests/test_colors.py | 8 ++- lib/matplotlib/tests/test_ticker.py | 15 ++--- 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index d66e199b25b2..87f83af87061 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2708,6 +2708,7 @@ def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): + print(f"Closing file {self._filename}") self.close() def _ensure_file(self): @@ -2728,7 +2729,7 @@ def close(self): _api.warn_deprecated("3.8", message=( "Keeping empty pdf files is deprecated since %(since)s and support " "will be removed %(removal)s.")) - PdfFile(self._filename, metadata=self._metadata) # touch the file. + PdfFile(self._filename, metadata=self._metadata).close() # touch the file. def infodict(self): """ diff --git a/lib/matplotlib/tests/test_backend_pdf.py b/lib/matplotlib/tests/test_backend_pdf.py index f6497bc01c78..ae17c7a4a4e3 100644 --- a/lib/matplotlib/tests/test_backend_pdf.py +++ b/lib/matplotlib/tests/test_backend_pdf.py @@ -3,7 +3,6 @@ import io import os from pathlib import Path -import warnings import numpy as np import pytest @@ -85,44 +84,40 @@ def test_multipage_keep_empty(tmp_path): os.chdir(tmp_path) # test empty pdf files - # Due to order of `with` block execution, a warning for unclosed file is raised - # but the pytest.warns must happen before the PdfPages is created - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=ResourceWarning) - - # an empty pdf is left behind with keep_empty unset - with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: - pass - assert os.path.exists("a.pdf") - - # an empty pdf is left behind with keep_empty=True - with pytest.warns(mpl.MatplotlibDeprecationWarning), \ - PdfPages("b.pdf", keep_empty=True) as pdf: - pass - assert os.path.exists("b.pdf") - - # an empty pdf deletes itself afterwards with keep_empty=False - with PdfPages("c.pdf", keep_empty=False) as pdf: - pass - assert not os.path.exists("c.pdf") - - # test pdf files with content, they should never be deleted - - # a non-empty pdf is left behind with keep_empty unset - with PdfPages("d.pdf") as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("d.pdf") - - # a non-empty pdf is left behind with keep_empty=True - with pytest.warns(mpl.MatplotlibDeprecationWarning), \ - PdfPages("e.pdf", keep_empty=True) as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("e.pdf") - - # a non-empty pdf is left behind with keep_empty=False - with PdfPages("f.pdf", keep_empty=False) as pdf: - pdf.savefig(plt.figure()) - assert os.path.exists("f.pdf") + + # an empty pdf is left behind with keep_empty unset + with pytest.warns(mpl.MatplotlibDeprecationWarning), PdfPages("a.pdf") as pdf: + pass + assert os.path.exists("a.pdf") + + # an empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("b.pdf", keep_empty=True) as pdf: + pass + assert os.path.exists("b.pdf") + + # an empty pdf deletes itself afterwards with keep_empty=False + with PdfPages("c.pdf", keep_empty=False) as pdf: + pass + assert not os.path.exists("c.pdf") + + # test pdf files with content, they should never be deleted + + # a non-empty pdf is left behind with keep_empty unset + with PdfPages("d.pdf") as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("d.pdf") + + # a non-empty pdf is left behind with keep_empty=True + with pytest.warns(mpl.MatplotlibDeprecationWarning), \ + PdfPages("e.pdf", keep_empty=True) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("e.pdf") + + # a non-empty pdf is left behind with keep_empty=False + with PdfPages("f.pdf", keep_empty=False) as pdf: + pdf.savefig(plt.figure()) + assert os.path.exists("f.pdf") def test_composite_image(): diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index b8f381f91082..35030b6bea7a 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -1,7 +1,7 @@ import copy import itertools import unittest.mock -import warnings +from packaging.version import parse as parse_version from io import BytesIO import numpy as np @@ -149,10 +149,12 @@ def test_double_register_builtin_cmap(): with pytest.warns(mpl.MatplotlibDeprecationWarning): cm.register_cmap(name, mpl.colormaps[name]) - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=mpl.MatplotlibDeprecationWarning) + if parse_version(pytest.__version__).major < 8: with pytest.warns(UserWarning): cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) + else: + with pytest.warns(UserWarning), pytest.warns(mpl.MatplotlibDeprecationWarning): + cm.register_cmap(name, mpl.colormaps[name], override_builtin=True) def test_unregister_builtin_cmap(): diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 67e3764f0d2c..4b37d5c52206 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -3,7 +3,7 @@ import locale import logging import re -import warnings +from packaging.version import parse as parse_version import numpy as np from numpy.testing import assert_almost_equal, assert_array_equal @@ -915,16 +915,17 @@ def test_mathtext_ticks(self): 'axes.formatter.use_mathtext': False }) - # Glyph warning unrelated - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", category=UserWarning, message="Glyph 8722" - ) - + if parse_version(pytest.__version__).major < 8: with pytest.warns(UserWarning, match='cmr10 font should ideally'): fig, ax = plt.subplots() ax.set_xticks([-1, 0, 1]) fig.canvas.draw() + else: + with (pytest.warns(UserWarning, match="Glyph 8722"), + pytest.warns(UserWarning, match='cmr10 font should ideally')): + fig, ax = plt.subplots() + ax.set_xticks([-1, 0, 1]) + fig.canvas.draw() def test_cmr10_substitutions(self, caplog): mpl.rcParams.update({ From f0a15772d12989ea6aacc2117bd2dbe924877e1d Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Tue, 16 Jan 2024 13:18:54 -0600 Subject: [PATCH 4/4] remove debug print Co-authored-by: Thomas A Caswell --- lib/matplotlib/backends/backend_pdf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 87f83af87061..573b401c1950 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2708,7 +2708,6 @@ def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): - print(f"Closing file {self._filename}") self.close() def _ensure_file(self):