diff --git a/lib/matplotlib/sphinxext/plot_directive.py b/lib/matplotlib/sphinxext/plot_directive.py index dbf5072e2c93..398469eec2e8 100644 --- a/lib/matplotlib/sphinxext/plot_directive.py +++ b/lib/matplotlib/sphinxext/plot_directive.py @@ -196,6 +196,7 @@ import sys import textwrap import traceback +import warnings from docutils.parsers.rst import directives, Directive from docutils.parsers.rst.directives.images import Image @@ -584,9 +585,10 @@ def _run_code(code, code_path, ns=None, function_name=None): dirname = os.path.abspath(os.path.dirname(code_path)) os.chdir(dirname) - with cbook._setattr_cm( + with (warnings.catch_warnings(record=True) as caught_warnings, + cbook._setattr_cm( sys, argv=[code_path], path=[os.getcwd(), *sys.path]), \ - contextlib.redirect_stdout(StringIO()): + contextlib.redirect_stdout(StringIO())): try: if ns is None: ns = {} @@ -609,6 +611,13 @@ def _run_code(code, code_path, ns=None, function_name=None): raise PlotError(traceback.format_exc()) from err finally: os.chdir(pwd) + + for warn in caught_warnings: + _log.warning( + "[plot] Python warning during plot execution: %s (%s)", + warn.message, + warn.category.__name__ + ) return ns diff --git a/lib/matplotlib/tests/test_sphinxext.py b/lib/matplotlib/tests/test_sphinxext.py index 9192cdfb906b..62b9d335c403 100644 --- a/lib/matplotlib/tests/test_sphinxext.py +++ b/lib/matplotlib/tests/test_sphinxext.py @@ -59,6 +59,24 @@ def test_plot_directive_exception_fails_build(tmp_path): assert "RuntimeError: plot directive failure" in proc.stderr +def test_plot_directive_warning_propagation(tmp_path): + shutil.copyfile(tinypages / 'conf.py', tmp_path / 'conf.py') + shutil.copytree(tinypages / '_static', tmp_path / '_static') + (tmp_path / 'index.rst').write_text(""" +.. plot:: + + import warnings + warnings.warn("A warning occurred") + +""") + + proc = build_sphinx_html( + tmp_path, tmp_path / 'doctrees', tmp_path / '_build' / 'html', + expected_returncode=1) + + assert "Python warning during plot execution: A warning occurred (UserWarning)" in proc.stderr + + def test_tinypages(tmp_path): shutil.copytree(tinypages, tmp_path, dirs_exist_ok=True, ignore=shutil.ignore_patterns('_build', 'doctrees',