Skip to content

Commit 2f709d7

Browse files
authored
Add CI job for Pyodide (#1143)
I figured it was worth testing the Pyodide support (#1099) a bit more comprehensively. The changes to the tests are just to skip the handful of cases that Pyodide doesn't support related to I/O and threading.
1 parent 5a84e37 commit 2f709d7

File tree

8 files changed

+100
-6
lines changed

8 files changed

+100
-6
lines changed

.github/workflows/pyodide.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copied from SymPy https://github.com/sympy/sympy/pull/27183
2+
3+
name: Mathics3 (Pyodide)
4+
5+
on:
6+
push:
7+
branches: [ master ]
8+
pull_request:
9+
branches: [ master ]
10+
11+
jobs:
12+
pyodide-test:
13+
runs-on: ubuntu-latest
14+
env:
15+
PYODIDE_VERSION: 0.27.0a2
16+
# PYTHON_VERSION and EMSCRIPTEN_VERSION are determined by PYODIDE_VERSION.
17+
# The appropriate versions can be found in the Pyodide repodata.json
18+
# "info" field, or in Makefile.envs:
19+
# https://github.com/pyodide/pyodide/blob/main/Makefile.envs#L2
20+
PYTHON_VERSION: 3.12.1
21+
EMSCRIPTEN_VERSION: 3.1.58
22+
NODE_VERSION: 20
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Python ${{ env.PYTHON_VERSION }}
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: ${{ env.PYTHON_VERSION }}
31+
32+
- name: Set up Emscripten toolchain
33+
uses: mymindstorm/setup-emsdk@v14
34+
with:
35+
version: ${{ env.EMSCRIPTEN_VERSION }}
36+
actions-cache-folder: emsdk-cache
37+
38+
- name: Install pyodide-build
39+
run: pip install pyodide-build
40+
41+
- name: Set up Node.js
42+
uses: actions/setup-node@v4
43+
with:
44+
node-version: ${{ env.NODE_VERSION }}
45+
46+
- name: Set up Pyodide virtual environment and run tests
47+
run: |
48+
# Set up Pyodide virtual environment
49+
pyodide xbuildenv install ${{ env.PYODIDE_VERSION }}
50+
pyodide venv .venv-pyodide
51+
52+
# Activate the virtual environment
53+
source .venv-pyodide/bin/activate
54+
55+
pip install "setuptools>=70.0.0" PyYAML click packaging pytest
56+
57+
git clone https://github.com/Mathics3/mathics-scanner.git
58+
cd mathics-scanner/
59+
pip install --no-build-isolation -e .
60+
cd ..
61+
62+
make mathics/data/op-tables.json mathics/data/operator-tables.json
63+
pip install --no-build-isolation -e .
64+
make -j3 check

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
/.cache
1717
/.gdbinit
1818
/.python-version
19+
/.pyodide-xbuildenv-*
1920
/Mathics.egg-info
2021
/Mathics3.egg-info
2122
ChangeLog

mathics/builtin/file_operations/file_properties.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,6 @@ class SetFileDate(Builtin):
241241
242242
>> SetFileDate[tmpfilename, {2002, 1, 1, 0, 0, 0.}, "Access"];
243243
244-
>> FileDate[tmpfilename, "Access"]
245-
= {2002, 1, 1, 0, 0, 0.}
246-
247244
#> DeleteFile[tmpfilename]
248245
"""
249246

mathics/builtin/files_io/files.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,6 @@ class OpenRead(_OpenAction):
461461
462462
The stream must be closed after using it to release the resource:
463463
>> Close[%];
464-
465-
S> Close[OpenRead["https://raw.githubusercontent.com/Mathics3/mathics-core/master/README.rst"]];
466464
"""
467465

468466
summary_text = "open a file for reading"

test/builtin/files_io/test_files.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ def test_close():
9999
), f"temporary filename {temp_filename} should not appear"
100100

101101

102+
@pytest.mark.skipif(
103+
sys.platform in ("emscripten",),
104+
reason="Pyodide has restricted filesystem access",
105+
)
102106
@pytest.mark.parametrize(
103107
("str_expr", "msgs", "str_expected", "fail_msg"),
104108
[
@@ -147,6 +151,12 @@ def test_close():
147151
"OpenRead[]",
148152
"",
149153
),
154+
(
155+
'Close[OpenRead["https://raw.githubusercontent.com/Mathics3/mathics-core/master/README.rst"]];',
156+
None,
157+
"Null",
158+
"",
159+
),
150160
(
151161
'fd=OpenRead["ExampleData/EinsteinSzilLetter.txt", BinaryFormat -> True, CharacterEncoding->"UTF8"]//Head',
152162
None,
@@ -314,6 +324,16 @@ def test_close():
314324
),
315325
("FilePrint[pathname]", None, "Null", ""),
316326
("DeleteFile[pathname];Clear[pathname];", None, "Null", ""),
327+
('tmpfilename = $TemporaryDirectory <> "/tmp0";', None, "Null", ""),
328+
("Close[OpenWrite[tmpfilename]];", None, "Null", ""),
329+
(
330+
'SetFileDate[tmpfilename, {2002, 1, 1, 0, 0, 0.}, "Access"];',
331+
None,
332+
"Null",
333+
"",
334+
),
335+
('FileDate[tmpfilename, "Access"]', None, "{2002, 1, 1, 0, 0, 0.}", ""),
336+
("DeleteFile[tmpfilename]", None, "Null", ""),
317337
],
318338
)
319339
def test_private_doctests_files(str_expr, msgs, str_expected, fail_msg):

test/builtin/test_datentime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
@pytest.mark.skipif(
14-
sys.platform in ("win32",) or hasattr(sys, "pyston_version_info"),
14+
sys.platform in ("win32", "emscripten") or hasattr(sys, "pyston_version_info"),
1515
reason="TimeConstrained needs to be rewritten",
1616
)
1717
def test_timeremaining():

test/test_main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22
import os.path as osp
33
import re
44
import subprocess
5+
import sys
6+
7+
import pytest
58

69

710
def get_testdir():
811
filename = osp.normcase(osp.dirname(osp.abspath(__file__)))
912
return osp.realpath(filename)
1013

1114

15+
@pytest.mark.skipif(
16+
sys.platform in ("emscripten",),
17+
reason="Pyodide does not support processes",
18+
)
1219
def test_cli():
1320
script_file = osp.join(get_testdir(), "data", "script.m")
1421

test/test_returncode.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
# -*- coding: utf-8 -*-
22
import os.path as osp
33
import subprocess
4+
import sys
5+
6+
import pytest
47

58

69
def get_testdir():
710
filename = osp.normcase(osp.dirname(osp.abspath(__file__)))
811
return osp.realpath(filename)
912

1013

14+
@pytest.mark.skipif(
15+
sys.platform in ("emscripten",),
16+
reason="Pyodide does not support processes",
17+
)
1118
def test_returncode():
1219
assert subprocess.run(["mathics", "-e", "Quit[5]"]).returncode == 5
1320
assert subprocess.run(["mathics", "-e", "1 + 2'"]).returncode == 0

0 commit comments

Comments
 (0)