diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7a197a9d4aa8..ea5e11e2e27b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -56,10 +56,11 @@ jobs: pygobject-ver: '<3.52.0' - os: ubuntu-22.04 python-version: '3.11' - CFLAGS: "-fno-lto" # Ensure that disabling LTO works. + lto: "--config-settings=setup-args=-Db_lto=false" # Ensure that disabling LTO works. extra-requirements: '-r requirements/testing/extra.txt' # https://github.com/matplotlib/matplotlib/issues/29844 pygobject-ver: '<3.52.0' + python-optimize: 'true' - os: ubuntu-22.04-arm python-version: '3.12' # https://github.com/matplotlib/matplotlib/issues/29844 @@ -317,7 +318,7 @@ jobs: fi python -m pip install --no-deps --no-build-isolation --verbose \ - --config-settings=setup-args="-DrcParams-backend=Agg" \ + --config-settings=setup-args="-DrcParams-backend=Agg" ${{ matrix.lto }} \ --editable .[dev] if [[ "${{ runner.os }}" != 'macOS' ]]; then @@ -334,7 +335,10 @@ jobs: if [[ "${{ matrix.python-version }}" == '3.13t' ]]; then export PYTHON_GIL=0 fi - pytest -rfEsXR -n auto \ + if [[ "${{ matrix.python-optimize }}" == 'true' ]]; then + export PYTHONOPTIMIZE=2 + fi + pytest -rfEsXR -n auto -sv \ --maxfail=50 --timeout=300 --durations=25 \ --cov-report=xml --cov=lib --log-level=DEBUG --color=yes diff --git a/lib/matplotlib/testing/__init__.py b/lib/matplotlib/testing/__init__.py index d6affb1b039f..0b7b309144b1 100644 --- a/lib/matplotlib/testing/__init__.py +++ b/lib/matplotlib/testing/__init__.py @@ -129,6 +129,8 @@ def subprocess_run_helper(func, *args, timeout, extra_env=None): [ sys.executable, "-c", + f"import pytest;" + f"pytest.register_assert_rewrite({module!r});" f"import importlib.util;" f"_spec = importlib.util.spec_from_file_location({module!r}, {file!r});" f"_module = importlib.util.module_from_spec(_spec);" diff --git a/lib/matplotlib/tests/test_artist.py b/lib/matplotlib/tests/test_artist.py index 5c8141e40741..e8f0c1269169 100644 --- a/lib/matplotlib/tests/test_artist.py +++ b/lib/matplotlib/tests/test_artist.py @@ -1,5 +1,6 @@ import io from itertools import chain +import sys import numpy as np @@ -256,7 +257,9 @@ def test_setp(): # Check *file* argument sio = io.StringIO() plt.setp(lines1, 'zorder', file=sio) - assert sio.getvalue() == ' zorder: float\n' + # With optimization, docstrings are stripped so the automated types don't work. + expected = 'unknown' if sys.flags.optimize >= 2 else 'float' + assert sio.getvalue() == f' zorder: {expected}\n' def test_None_zorder(): @@ -361,6 +364,8 @@ def set_myparam2(self, val): assert 'myparam2' in MyArtist2.set.__doc__ +@pytest.mark.skipif(sys.flags.optimize >= 2, + reason='Python optimization is enabled and docstrings are stripped') def test_set_is_overwritten(): """set() defined in Artist subclasses should not be overwritten.""" class MyArtist3(martist.Artist): diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index a27783fa4be1..4008e0a841e3 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -460,6 +460,8 @@ def qt5_and_qt6_pairs(): reason="$DISPLAY and $WAYLAND_DISPLAY are unset") @pytest.mark.parametrize('host, mpl', [*qt5_and_qt6_pairs()]) def test_cross_Qt_imports(host, mpl): + if sys.flags.optimize > 0 and 'PySide2' in {host, mpl}: + pytest.xfail('PySide2 does not work optimized') try: proc = _run_helper(_impl_test_cross_Qt_imports, host, mpl, timeout=_test_timeout) diff --git a/lib/matplotlib/tests/test_matplotlib.py b/lib/matplotlib/tests/test_matplotlib.py index 37b41fafdb78..500c343186e9 100644 --- a/lib/matplotlib/tests/test_matplotlib.py +++ b/lib/matplotlib/tests/test_matplotlib.py @@ -44,6 +44,8 @@ def test_importable_with_no_home(tmp_path): env={**os.environ, "MPLCONFIGDIR": str(tmp_path)}, check=True) +@pytest.mark.skipif(sys.flags.optimize >= 2, + reason='Python optimization is enabled and docstrings are stripped') def test_use_doc_standard_backends(): """ Test that the standard backends mentioned in the docstring of diff --git a/lib/matplotlib/tests/test_preprocess_data.py b/lib/matplotlib/tests/test_preprocess_data.py index c983d78786e1..f74c2a8f55a6 100644 --- a/lib/matplotlib/tests/test_preprocess_data.py +++ b/lib/matplotlib/tests/test_preprocess_data.py @@ -39,23 +39,25 @@ def func_no_ax_args(*args, **kwargs): pass # this has "enough" information to do all the replaces _preprocess_data(replace_names=["x", "y"])(func_args) - # no positional_parameter_names but needed due to replaces - with pytest.raises(AssertionError): - # z is unknown - _preprocess_data(replace_names=["x", "y", "z"])(func_args) - # no replacements at all -> all ok... _preprocess_data(replace_names=[], label_namer=None)(func) _preprocess_data(replace_names=[], label_namer=None)(func_args) _preprocess_data(replace_names=[], label_namer=None)(func_kwargs) _preprocess_data(replace_names=[], label_namer=None)(func_no_ax_args) - # label namer is unknown - with pytest.raises(AssertionError): - _preprocess_data(label_namer="z")(func) + # No asserts with optimizations. + if sys.flags.optimize < 1: + # no positional_parameter_names but needed due to replaces + with pytest.raises(AssertionError): + # z is unknown + _preprocess_data(replace_names=["x", "y", "z"])(func_args) + + # label namer is unknown + with pytest.raises(AssertionError): + _preprocess_data(label_namer="z")(func) - with pytest.raises(AssertionError): - _preprocess_data(label_namer="z")(func_args) + with pytest.raises(AssertionError): + _preprocess_data(label_namer="z")(func_args) @pytest.mark.parametrize('func', all_funcs, ids=all_func_ids) @@ -193,6 +195,8 @@ def func(ax, x, y, z=1): func(None, "a", "b", "z", "z", data=data) +@pytest.mark.skipif(sys.flags.optimize >= 2, + reason='Python optimization is enabled and docstrings are stripped') def test_docstring_addition(): @_preprocess_data() def funcy(ax, *args, **kwargs):