File: tests.yml

package info (click to toggle)
matplotlib 3.10.7%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 72,820 kB
  • sloc: python: 147,545; cpp: 62,988; objc: 1,679; ansic: 1,426; javascript: 788; makefile: 92; sh: 53
file content (434 lines) | stat: -rw-r--r-- 18,213 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
---
name: Tests
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
  cancel-in-progress: true

on:
  push:
    branches-ignore:
      - auto-backport-of-pr-[0-9]+
      - v[0-9]+.[0-9]+.[0-9x]+-doc
      - dependabot/**
  pull_request:
    branches-ignore:
      - v[0-9]+.[0-9]+.[0-9x]+-doc
    paths-ignore:
      # Skip running tests if changes are only in documentation directories
      - 'doc/**'
      - 'galleries/**'
  schedule:
    # 5:47 UTC on Saturdays
    - cron: "47 5 * * 6"
  workflow_dispatch:

env:
  NO_AT_BRIDGE: 1  # Necessary for GTK3 interactive test.
  OPENBLAS_NUM_THREADS: 1
  PYTHONFAULTHANDLER: 1

jobs:
  test:
    if: >-
      github.event_name == 'workflow_dispatch' ||
      (
        github.repository == 'matplotlib/matplotlib' &&
        !contains(github.event.head_commit.message, '[ci skip]') &&
        !contains(github.event.head_commit.message, '[skip ci]') &&
        !contains(github.event.head_commit.message, '[skip github]') &&
        !contains(github.event.head_commit.message, '[ci doc]')
      )
    permissions:
      contents: read
    name: "Python ${{ matrix.python-version }} on ${{ matrix.os }} ${{ matrix.name-suffix }}"
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        include:
          - name-suffix: "(Minimum Versions)"
            os: ubuntu-22.04
            python-version: '3.10'
            extra-requirements: '-c requirements/testing/minver.txt'
            delete-font-cache: true
            # Oldest versions with Py3.10 wheels.
            pyqt5-ver: '==5.15.5 sip==6.3.0'
            pyqt6-ver: '==6.2.0 PyQt6-Qt6==6.2.0'
            pyside2-ver: '==5.15.2.1'
            pyside6-ver: '==6.2.0'
          - os: ubuntu-22.04
            python-version: '3.11'
            CFLAGS: "-fno-lto"  # Ensure that disabling LTO works.
            # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html
            pyqt6-ver: '!=6.6.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
            extra-requirements: '-r requirements/testing/extra.txt'
          - os: ubuntu-22.04
            python-version: '3.12'
            # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html
            pyqt6-ver: '!=6.6.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
          - os: ubuntu-22.04
            python-version: '3.13'
            # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html
            pyqt6-ver: '!=6.6.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
          - name-suffix: "Free-threaded"
            os: ubuntu-22.04
            python-version: '3.13t'
            # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html
            pyqt6-ver: '!=6.6.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
          - os: macos-14  # This runner is on M1 (arm64) chips.
            python-version: '3.10'
            # https://github.com/matplotlib/matplotlib/issues/29732
            pygobject-ver: '<3.52.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
          - os: macos-14  # This runner is on M1 (arm64) chips.
            python-version: '3.12'
            # https://github.com/matplotlib/matplotlib/issues/29732
            pygobject-ver: '<3.52.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'
          - os: macos-15  # This runner is on M1 (arm64) chips.
            python-version: '3.13'
            # https://github.com/matplotlib/matplotlib/issues/29732
            pygobject-ver: '<3.52.0'
            # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346
            pyside6-ver: '!=6.5.1'

    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b  # v5.3.0
        if: matrix.python-version != '3.13t'
        with:
          python-version: ${{ matrix.python-version }}
          allow-prereleases: true

      - name: Set up Python ${{ matrix.python-version }}
        uses: Quansight-Labs/setup-python@b9ab292c751a42bcd2bb465b7fa202ea2c3f5796  # v5.3.1
        if: matrix.python-version == '3.13t'
        with:
          python-version: ${{ matrix.python-version }}
          allow-prereleases: true

      - name: Install OS dependencies
        run: |
          case "${{ runner.os }}" in
          Linux)
            echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries
            sudo apt-get update -yy
            sudo apt-get install -yy --no-install-recommends \
              ccache \
              cm-super \
              dvipng \
              ffmpeg \
              fonts-freefont-otf \
              fonts-noto-cjk \
              fonts-wqy-zenhei \
              gdb \
              gir1.2-gtk-3.0 \
              graphviz \
              inkscape \
              language-pack-de \
              lcov \
              libcairo2 \
              libcairo2-dev \
              libffi-dev \
              libgeos-dev \
              libgirepository1.0-dev \
              libnotify4 \
              libsdl2-2.0-0 \
              libxkbcommon-x11-0 \
              libxcb-cursor0 \
              libxcb-icccm4 \
              libxcb-image0 \
              libxcb-keysyms1 \
              libxcb-randr0 \
              libxcb-render-util0 \
              libxcb-xinerama0 \
              lmodern \
              ninja-build \
              pkg-config \
              qtbase5-dev \
              texlive-fonts-recommended \
              texlive-latex-base \
              texlive-latex-extra \
              texlive-latex-recommended \
              texlive-luatex \
              texlive-pictures \
              texlive-xetex
            sudo apt-get install -yy --no-install-recommends gir1.2-gtk-4.0
            ;;
          macOS)
            brew update
            # Periodically, Homebrew updates Python and fails to overwrite the
            # existing not-managed-by-Homebrew copy without explicitly being told
            # to do so. GitHub/Azure continues to avoid fixing their runner images:
            # https://github.com/actions/runner-images/issues/9966
            # so force an overwrite even if there are no Python updates.
            # We don't even care about Homebrew's Python because we use the one
            # from actions/setup-python.
            for python_package in $(brew list | grep python@); do
              brew unlink ${python_package}
              brew link --overwrite ${python_package}
            done
            # Workaround for https://github.com/actions/runner-images/issues/10984
            brew uninstall --ignore-dependencies --force pkg-config@0.29.2
            brew install ccache ghostscript gobject-introspection gtk4 ninja
            brew install --cask font-noto-sans-cjk inkscape
            ;;
          esac

      - name: Cache pip
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        if: startsWith(runner.os, 'Linux')
        with:
          path: ~/.cache/pip
          key: ${{ matrix.os }}-py${{ matrix.python-version }}-pip-${{ hashFiles('requirements/*/*.txt') }}
          restore-keys: |
            ${{ matrix.os }}-py${{ matrix.python-version }}-pip-
      - name: Cache pip
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        if: startsWith(runner.os, 'macOS')
        with:
          path: ~/Library/Caches/pip
          key: ${{ matrix.os }}-py${{ matrix.python-version }}-pip-${{ hashFiles('requirements/*/*.txt') }}
          restore-keys: |
            ${{ matrix.os }}-py${{ matrix.python-version }}-pip-
      - name: Cache ccache
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        with:
          path: |
            ~/.ccache
          key: ${{ matrix.os }}-py${{ matrix.python-version }}-ccache-${{ hashFiles('src/*') }}
          restore-keys: |
            ${{ matrix.os }}-py${{ matrix.python-version }}-ccache-
      - name: Cache Matplotlib
        uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57  # v4.2.0
        with:
          path: |
            ~/.cache/matplotlib
            !~/.cache/matplotlib/tex.cache
            !~/.cache/matplotlib/test_cache
          key: 4-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}-${{ github.sha }}
          restore-keys: |
            4-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}-
            4-${{ runner.os }}-py${{ matrix.python-version }}-mpl-

      - name: Install Python dependencies
        run: |
          # Upgrade pip and setuptools and wheel to get as clean an install as
          # possible.
          python -m pip install --upgrade pip setuptools wheel

          # Install pre-release versions during our weekly upcoming dependency tests.
          if [[ "${{ github.event_name }}" == 'schedule'
                && "${{ matrix.name-suffix }}" != '(Minimum Versions)' ]]; then
            PRE="--pre"
          fi

          # Install dependencies from PyPI.
          # Preinstall build requirements to enable no-build-isolation builds.
          python -m pip install --upgrade $PRE \
            'contourpy>=1.0.1' cycler fonttools kiwisolver importlib_resources \
            packaging pillow 'pyparsing!=3.1.0' python-dateutil setuptools-scm \
            'meson-python>=0.13.1' 'pybind11>=2.13.2' \
            -r requirements/testing/all.txt \
            ${{ matrix.extra-requirements }}

          # Install optional dependencies from PyPI.
          # Sphinx is needed to run sphinxext tests
          python -m pip install --upgrade sphinx!=6.1.2

          if [[ "${{ matrix.python-version }}" != '3.13t' ]]; then
          # GUI toolkits are pip-installable only for some versions of Python
          # so don't fail if we can't install them.  Make it easier to check
          # whether the install was successful by trying to import the toolkit
          # (sometimes, the install appears to be successful but shared
          # libraries cannot be loaded at runtime, so an actual import is a
          # better check).
          python -m pip install --upgrade pycairo 'cairocffi>=0.8' 'PyGObject${{ matrix.pygobject-ver }}' &&
            (
              python -c 'import gi; gi.require_version("Gtk", "4.0"); from gi.repository import Gtk' &&
              echo 'PyGObject 4 is available' || echo 'PyGObject 4 is not available'
            ) && (
              python -c 'import gi; gi.require_version("Gtk", "3.0"); from gi.repository import Gtk' &&
              echo 'PyGObject 3 is available' || echo 'PyGObject 3 is not available'
            )

          python -mpip install --upgrade pyqt5${{ matrix.pyqt5-ver }} &&
            python -c 'import PyQt5.QtCore' &&
            echo 'PyQt5 is available' ||
            echo 'PyQt5 is not available'
          # Even though PySide2 wheels can be installed on Python 3.12+, they are broken and since PySide2 is
          # deprecated, they are unlikely to be fixed. For the same deprecation reason, there are no wheels
          # on M1 macOS, so don't bother there either.
          if [[ "${{ matrix.os }}" != 'macos-14'
                && "${{ matrix.python-version }}" != '3.12' && "${{ matrix.python-version }}" != '3.13' ]]; then
            python -mpip install --upgrade pyside2${{ matrix.pyside2-ver }} &&
              python -c 'import PySide2.QtCore' &&
              echo 'PySide2 is available' ||
              echo 'PySide2 is not available'
          fi
          python -mpip install --upgrade pyqt6${{ matrix.pyqt6-ver }} &&
            python -c 'import PyQt6.QtCore' &&
            echo 'PyQt6 is available' ||
            echo 'PyQt6 is not available'
          python -mpip install --upgrade pyside6${{ matrix.pyside6-ver }} &&
            python -c 'import PySide6.QtCore' &&
            echo 'PySide6 is available' ||
            echo 'PySide6 is not available'

          python -mpip install --upgrade \
            -f "https://extras.wxpython.org/wxPython4/extras/linux/gtk3/${{ matrix.os }}" \
            wxPython &&
            python -c 'import wx' &&
            echo 'wxPython is available' ||
            echo 'wxPython is not available'

          fi  # Skip backends on Python 3.13t.

      - name: Install the nightly dependencies
        # Only install the nightly dependencies during the scheduled event
        if: github.event_name == 'schedule' && matrix.name-suffix != '(Minimum Versions)'
        run: |
          python -m pip install pytz tzdata  # Must be installed for Pandas.
          python -m pip install \
            --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
            --upgrade --only-binary=:all: numpy pandas

      - name: Install Matplotlib
        run: |
          ccache -s
          git describe

          # Set flag in a delayed manner to avoid issues with installing other
          # packages
          if [[ "${{ runner.os }}" == 'macOS' ]]; then
            export CPPFLAGS='-fprofile-instr-generate=default.%m.profraw'
            export CPPFLAGS="$CPPFLAGS -fcoverage-mapping"
          else
            export CPPFLAGS='--coverage -fprofile-abs-path'
          fi

          python -m pip install --no-deps --no-build-isolation --verbose \
            --config-settings=setup-args="-DrcParams-backend=Agg" \
            --editable .[dev]

          if [[ "${{ runner.os }}" != 'macOS' ]]; then
            unset CPPFLAGS
          fi

      - name: Clear font cache
        run: |
          rm -rf ~/.cache/matplotlib
        if: matrix.delete-font-cache

      - name: Run pytest
        run: |
          if [[ "${{ matrix.python-version }}" == '3.13t' ]]; then
            export PYTHON_GIL=0
          fi
          pytest -rfEsXR -n auto \
            --maxfail=50 --timeout=300 --durations=25 \
            --cov-report=xml --cov=lib --log-level=DEBUG --color=yes

      - name: Cleanup non-failed image files
        if: failure()
        run: |
          function remove_files() {
              local extension=$1
              find ./result_images -type f -name "*-expected*.$extension" | while read file; do
                  if [[ $file == *"-expected_pdf"* ]]; then
                      base=${file%-expected_pdf.$extension}_pdf
                  elif [[ $file == *"-expected_eps"* ]]; then
                      base=${file%-expected_eps.$extension}_eps
                  elif [[ $file == *"-expected_svg"* ]]; then
                      base=${file%-expected_svg.$extension}_svg
                  else
                      base=${file%-expected.$extension}
                  fi
                  if [[ ! -e "${base}-failed-diff.$extension" ]]; then
                      if [[ -e "$file" ]]; then
                          rm "$file"
                          echo "Removed $file"
                      fi
                      if [[ -e "${base}.$extension" ]]; then
                          rm "${base}.$extension"
                          echo " Removed ${base}.$extension"
                      fi
                  fi
              done
          }

          remove_files "png"; remove_files "svg"; remove_files "pdf"; remove_files "eps";

          if [ "$(find ./result_images -mindepth 1 -type d)" ]; then
              find ./result_images/* -type d -empty -delete
          fi

      - name: Filter C coverage
        if: ${{ !cancelled() && github.event_name != 'schedule' }}
        run: |
          if [[ "${{ runner.os }}" != 'macOS' ]]; then
            lcov --rc lcov_branch_coverage=1 --capture --directory . \
              --output-file coverage.info
            lcov --rc lcov_branch_coverage=1 --output-file coverage.info \
              --extract coverage.info $PWD/src/'*' $PWD/lib/'*'
            lcov --rc lcov_branch_coverage=1 --list coverage.info
            find . -name '*.gc*' -delete
          else
            xcrun llvm-profdata merge -sparse default.*.profraw \
              -o default.profdata
            xcrun llvm-cov export -format="lcov" build/*/src/*.so \
              -instr-profile default.profdata > info.lcov
          fi
      - name: Upload code coverage
        if: ${{ !cancelled() && github.event_name != 'schedule' }}
        uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e  # v5.1.1
        with:
          name: "${{ matrix.python-version }} ${{ matrix.os }} ${{ matrix.name-suffix }}"
          token: ${{ secrets.CODECOV_TOKEN }}

      - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882  # v4.4.3
        if: failure()
        with:
          name: "${{ matrix.python-version }} ${{ matrix.os }} ${{ matrix.name-suffix }} result images"
          path: ./result_images

  # Separate dependent job to only upload one issue from the matrix of jobs
  create-issue:
    if: ${{ failure() && github.event_name == 'schedule' }}
    needs: [test]
    permissions:
      issues: write
    runs-on: ubuntu-latest
    name: "Create issue on failure"

    steps:
      - name: Create issue on failure
        uses: imjohnbo/issue-bot@572eed14422c4d6ca37e870f97e7da209422f5bd  # v3.4.4
        with:
          title: "[TST] Upcoming dependency test failures"
          body: |
            The weekly build with nightly wheels from numpy and pandas
            has failed. Check the logs for any updates that need to be
            made in matplotlib.
            https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}

          pinned: false
          close-previous: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}