Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 25f1939

Browse files
authored
Merge pull request #29093 from QuLogic/wasm
Add wasm CI
2 parents c46efc9 + e05db65 commit 25f1939

22 files changed

Lines changed: 173 additions & 52 deletions

.github/labeler.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
---
22
"CI: Run cibuildwheel":
33
- changed-files:
4-
- any-glob-to-any-file: ['.github/workflows/cibuildwheel.yml']
4+
- any-glob-to-any-file:
5+
- '.github/workflows/cibuildwheel.yml'
6+
- '.github/workflows/wasm.yml'
57
"CI: Run cygwin":
68
- changed-files:
79
- any-glob-to-any-file: ['.github/workflows/cygwin.yml']

.github/workflows/nightlies.yml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,28 @@ jobs:
3232
run: |
3333
PROJECT_REPO="matplotlib/matplotlib"
3434
BRANCH="main"
35-
WORKFLOW_NAME="cibuildwheel.yml"
3635
ARTIFACT_PATTERN="cibw-wheels-*"
3736
38-
gh run --repo "${PROJECT_REPO}" \
39-
list --branch "${BRANCH}" \
40-
--workflow "${WORKFLOW_NAME}" \
41-
--json event,status,conclusion,databaseId > runs.json
42-
RUN_ID=$(
43-
jq --compact-output \
44-
'[
45-
.[] |
46-
# Filter on "push" events to main (merged PRs) ...
47-
select(.event == "push") |
48-
# that have completed successfully ...
49-
select(.status == "completed" and .conclusion == "success")
50-
] |
51-
# and get ID of latest build of wheels.
52-
sort_by(.databaseId) | reverse | .[0].databaseId' runs.json
53-
)
54-
gh run --repo "${PROJECT_REPO}" view "${RUN_ID}"
55-
gh run --repo "${PROJECT_REPO}" \
56-
download "${RUN_ID}" --pattern "${ARTIFACT_PATTERN}"
37+
for WORKFLOW_NAME in cibuildwheel.yml wasm.yml; do
38+
gh run --repo "${PROJECT_REPO}" \
39+
list --branch "${BRANCH}" \
40+
--workflow "${WORKFLOW_NAME}" \
41+
--json event,status,conclusion,databaseId > runs.json
42+
RUN_ID=$(
43+
jq --compact-output \
44+
'[
45+
.[] |
46+
# Filter on "push" events to main (merged PRs) ...
47+
select(.event == "push") |
48+
# that have completed successfully ...
49+
select(.status == "completed" and .conclusion == "success")
50+
] |
51+
# and get ID of latest build of wheels.
52+
sort_by(.databaseId) | reverse | .[0].databaseId' runs.json
53+
)
54+
gh run --repo "${PROJECT_REPO}" view "${RUN_ID}"
55+
gh run --repo "${PROJECT_REPO}" download "${RUN_ID}" --pattern "${ARTIFACT_PATTERN}"
56+
done
5757
5858
mkdir dist
5959
mv ${ARTIFACT_PATTERN}/*.whl dist/

.github/workflows/wasm.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
name: Build wasm wheels
3+
4+
on:
5+
# Save CI by only running this on release branches or tags.
6+
push:
7+
branches:
8+
- main
9+
- v[0-9]+.[0-9]+.x
10+
tags:
11+
- v*
12+
# Also allow running this action on PRs if requested by applying the
13+
# "Run cibuildwheel" label.
14+
pull_request:
15+
types:
16+
- opened
17+
- synchronize
18+
- reopened
19+
- labeled
20+
21+
permissions:
22+
contents: read
23+
24+
jobs:
25+
build_wasm:
26+
if: >-
27+
(
28+
github.event_name == 'push' ||
29+
github.event_name == 'pull_request' && (
30+
(
31+
github.event.action == 'labeled' &&
32+
github.event.label.name == 'CI: Run cibuildwheel'
33+
) ||
34+
contains(github.event.pull_request.labels.*.name,
35+
'CI: Run cibuildwheel')
36+
)
37+
)
38+
name: Build wasm
39+
runs-on: ubuntu-24.04
40+
41+
steps:
42+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
43+
with:
44+
fetch-depth: 0
45+
persist-credentials: false
46+
47+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
48+
name: Install Python
49+
with:
50+
python-version: '3.13'
51+
52+
- name: Build wheels for wasm
53+
uses: pypa/cibuildwheel@ee02a1537ce3071a004a6b08c41e72f0fdc42d9a # v3.4.0
54+
env:
55+
CIBW_BUILD: "cp312-*"
56+
CIBW_PLATFORM: "pyodide"
57+
58+
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
59+
with:
60+
name: cibw-wheels-wasm
61+
path: ./wheelhouse/*.whl
62+
if-no-files-found: error

lib/matplotlib/animation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ def bin_path(cls):
369369
@classmethod
370370
def isAvailable(cls):
371371
"""Return whether a MovieWriter subclass is actually available."""
372+
if sys.platform == 'emscripten':
373+
return False
372374
return shutil.which(cls.bin_path()) is not None
373375

374376

lib/matplotlib/dviread.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ def find_tex_file(filename):
12971297

12981298
try:
12991299
lk = _LuatexKpsewhich()
1300-
except FileNotFoundError:
1300+
except (FileNotFoundError, OSError):
13011301
lk = None # Fallback to directly calling kpsewhich, as below.
13021302

13031303
if lk:
@@ -1320,7 +1320,7 @@ def find_tex_file(filename):
13201320
path = cbook._check_and_log_subprocess(
13211321
['kpsewhich', '-mktex=pk', filename], _log, **kwargs,
13221322
).rstrip('\n')
1323-
except (FileNotFoundError, RuntimeError):
1323+
except (FileNotFoundError, OSError, RuntimeError):
13241324
path = None
13251325

13261326
if path:

lib/matplotlib/font_manager.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ def findSystemFonts(fontpaths=None, fontext='ttf'):
291291
if sys.platform == 'win32':
292292
installed_fonts = _get_win32_installed_fonts()
293293
fontpaths = []
294+
elif sys.platform == 'emscripten':
295+
installed_fonts = []
296+
fontpaths = []
294297
else:
295298
installed_fonts = _get_fontconfig_fonts()
296299
if sys.platform == 'darwin':
@@ -1090,9 +1093,12 @@ def __init__(self, size=None, weight='normal'):
10901093
self.ttflist = []
10911094

10921095
# Delay the warning by 5s.
1093-
timer = threading.Timer(5, lambda: _log.warning(
1094-
'Matplotlib is building the font cache; this may take a moment.'))
1095-
timer.start()
1096+
try:
1097+
timer = threading.Timer(5, lambda: _log.warning(
1098+
'Matplotlib is building the font cache; this may take a moment.'))
1099+
timer.start()
1100+
except RuntimeError:
1101+
timer = None
10961102
try:
10971103
for fontext in ["afm", "ttf"]:
10981104
for path in [*findSystemFonts(paths, fontext=fontext),
@@ -1105,7 +1111,8 @@ def __init__(self, size=None, weight='normal'):
11051111
_log.info("Failed to extract font properties from %s: "
11061112
"%s", path, exc)
11071113
finally:
1108-
timer.cancel()
1114+
if timer:
1115+
timer.cancel()
11091116

11101117
def addfont(self, path):
11111118
"""

lib/matplotlib/testing/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,14 @@ def subprocess_run_for_testing(command, env=None, timeout=60, stdout=None,
8787
8888
Raises
8989
------
90+
pytest.skip
91+
If running on emscripten, which does not support subprocesses.
9092
pytest.xfail
9193
If platform is Cygwin and subprocess reports a fork() failure.
9294
"""
95+
if sys.platform == 'emscripten':
96+
import pytest
97+
pytest.skip('emscripten does not support subprocesses')
9398
if capture_output:
9499
stdout = stderr = subprocess.PIPE
95100
# Add CREATE_NO_WINDOW flag on Windows to prevent console window overhead
@@ -208,7 +213,7 @@ def _has_tex_package(package):
208213
try:
209214
mpl.dviread.find_tex_file(f"{package}.sty")
210215
return True
211-
except FileNotFoundError:
216+
except (FileNotFoundError, OSError):
212217
return False
213218

214219

lib/matplotlib/testing/decorators.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ def copy_baseline(self, baseline, extension):
139139
try:
140140
if 'microsoft' in uname().release.lower():
141141
raise OSError # On WSL, symlink breaks silently
142+
if sys.platform == 'emscripten':
143+
raise OSError
142144
os.symlink(orig_expected_path, expected_fname)
143145
except OSError: # On Windows, symlink *may* be unavailable.
144146
shutil.copyfile(orig_expected_path, expected_fname)

lib/matplotlib/tests/test_animation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ def test_no_length_frames(anim):
271271
anim.save('unused.null', writer=NullMovieWriter())
272272

273273

274+
@pytest.mark.skipif(sys.platform == 'emscripten',
275+
reason='emscripten does not support subprocesses')
274276
def test_movie_writer_registry():
275277
assert len(animation.writers._registered) > 0
276278
mpl.rcParams['animation.ffmpeg_path'] = "not_available_ever_xxxx"
@@ -522,6 +524,8 @@ def test_disable_cache_warning(anim):
522524
def test_movie_writer_invalid_path(anim):
523525
if sys.platform == "win32":
524526
match_str = r"\[WinError 3] .*\\\\foo\\\\bar\\\\aardvark'"
527+
elif sys.platform == "emscripten":
528+
match_str = r"\[Errno 44] .*'/foo"
525529
else:
526530
match_str = r"\[Errno 2] .*'/foo"
527531
with pytest.raises(FileNotFoundError, match=match_str):

lib/matplotlib/tests/test_axes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8530,7 +8530,7 @@ def test_normal_axes():
85308530
]
85318531
for nn, b in enumerate(bbaxis):
85328532
targetbb = mtransforms.Bbox.from_bounds(*target[nn])
8533-
assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2)
8533+
assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=1)
85348534

85358535
target = [
85368536
[150.0, 119.999, 930.0, 11.111],
@@ -8548,7 +8548,7 @@ def test_normal_axes():
85488548

85498549
target = [85.5138, 75.88888, 1021.11, 1017.11]
85508550
targetbb = mtransforms.Bbox.from_bounds(*target)
8551-
assert_array_almost_equal(bbtb.bounds, targetbb.bounds, decimal=2)
8551+
assert_array_almost_equal(bbtb.bounds, targetbb.bounds, decimal=1)
85528552

85538553
# test that get_position roundtrips to get_window_extent
85548554
axbb = ax.get_position().transformed(fig.transFigure).bounds

0 commit comments

Comments
 (0)