Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test on Pyodide #2388

Merged
merged 9 commits into from
Jan 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 34 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
matrix:
name-prefix: ['']
os: [ubuntu-latest]
python: [3.7, 3.8, 3.9, '3.10', 3.11, pypy-3.9]
python: [3.7, 3.8, 3.9, '3.10', 3.11, pypy-3.9, pyodide]
include:
# To keep the overall number of runs low, we test Windows
# only on the latest CPython.
Expand All @@ -21,6 +21,7 @@ jobs:
name: ${{ format('{0}{1}', matrix.name-prefix, matrix.python) }}
runs-on: ${{ matrix.os }}
env:
EMSCRIPTEN_VERSION: 3.1.27
TERM: xterm-256color
# This is needed to avoid a terminfo-related crash when
# testing PyPy.
Expand All @@ -29,11 +30,37 @@ jobs:
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- if: ${{ matrix.python != 'pyodide' }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- run: pip install . && rm -r hy
# We want to be sure we're testing the installed version,
# instead of running from the source tree.
- run: pip install pytest
- run: pytest
- if: ${{ matrix.python == 'pyodide' }}
uses: actions/setup-node@v3
- if: ${{ matrix.python == 'pyodide' }}
uses: mymindstorm/setup-emsdk@v11
with:
version: ${{ env.EMSCRIPTEN_VERSION }}
actions-cache-folder: emsdk-cache
- name: Install
shell: bash
run: |
if [[ ${{ matrix.python }} = pyodide ]] ; then
npm install pyodide
pip install 'pip >= 22.3.1'
# Older pips may fail to install `pyodide-build`.
pip install pyodide-build
pyodide venv .venv-pyodide
source .venv-pyodide/bin/activate
fi
pip install .
rm -r hy
# We want to be sure we're testing the installed version,
# instead of running from the source tree.
pip install pytest
- name: Test
shell: bash
run: |
if [[ ${{ matrix.python }} = pyodide ]] ; then
source .venv-pyodide/bin/activate
fi
python -m pytest tests
1 change: 1 addition & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Bug Fixes

New Features
------------------------------
* Pyodide is now officially supported.
* `.`, `..`, etc. are now usable as ordinary symbols (with the
remaining special rule that `...` compiles to `Ellipsis`)
* On Pythons ≥ 3.7, Hy modules can now be imported from ZIP
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ To install the latest release of Hy, just use the command `pip3 install
--user hy`. Then you can start an interactive read-eval-print loop (REPL) with
the command `hy`, or run a Hy program with `hy myprogram.hy`.

Hy is tested on all released and currently maintained versions of CPython (on
Linux and Windows), and on recent versions of PyPy and Pyodide.

* [Try Hy with a web console](https://hylang.github.io/hy-interpreter)
* [Why Hy?](http://docs.hylang.org/en/stable/whyhy.html)
* [Tutorial](http://docs.hylang.org/en/stable/tutorial.html)
Expand Down
3 changes: 3 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ To install the latest release of Hy, just use the command ``pip3 install
--user hy``. Then you can start an interactive read-eval-print loop (REPL) with
the command ``hy``, or run a Hy program with ``hy myprogram.hy``.

Hy is tested on all released and currently maintained versions of CPython (on
Linux and Windows), and on recent versions of PyPy and Pyodide.

.. toctree::
:maxdepth: 3

Expand Down
1 change: 1 addition & 0 deletions hy/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
PY3_10 = sys.version_info >= (3, 10)
PY3_11 = sys.version_info >= (3, 11)
PYPY = platform.python_implementation() == "PyPy"
PYODIDE = platform.system() == "Emscripten"


if not PY3_9:
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def run(self):
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: Implementation :: PyPy",
"Environment :: WebAssembly :: Emscripten",
"Topic :: Software Development :: Code Generators",
"Topic :: Software Development :: Compilers",
"Topic :: Software Development :: Libraries",
Expand Down
7 changes: 4 additions & 3 deletions tests/native_tests/comprehensions.hy
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(import
types
asyncio
pytest)
pytest
tests.resources [async-test])


(defn test-comprehension-types []
Expand Down Expand Up @@ -385,7 +386,7 @@
(assert (= x 3)))


(defn test-for-async []
(defn [async-test] test-for-async []
(defn/a numbers []
(for [i [1 2]]
(yield i)))
Expand All @@ -398,7 +399,7 @@
(assert (= x 3))))))


(defn test-for-async-else []
(defn [async-test] test-for-async-else []
(defn/a numbers []
(for [i [1 2]]
(yield i)))
Expand Down
5 changes: 3 additions & 2 deletions tests/native_tests/decorators.hy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
(import
asyncio)
asyncio
tests.resources [async-test])


(defn test-decorated-1line-function []
Expand Down Expand Up @@ -52,7 +53,7 @@
(assert (= l ["dec" "arg" "foo" "foo fn" "bar body" 1])))


(defn test-decorated-defn/a []
(defn [async-test] test-decorated-defn/a []
(defn decorator [func] (fn/a [] (/ (await (func)) 2)))

(defn/a [decorator] coro-test []
Expand Down
7 changes: 4 additions & 3 deletions tests/native_tests/functions.hy
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
(import
asyncio
typing [List]
pytest)
pytest
tests.resources [async-test])


(defn test-fn []
Expand All @@ -24,7 +25,7 @@
(assert (= (fn-test) None)))


(defn test-fn/a []
(defn [async-test] test-fn/a []
(assert (= (asyncio.run ((fn/a [] (await (asyncio.sleep 0)) [1 2 3])))
[1 2 3])))

Expand Down Expand Up @@ -132,7 +133,7 @@
(setv x [#* spam] y 1)))


(defn test-defn/a []
(defn [async-test] test-defn/a []
(defn/a coro-test []
(await (asyncio.sleep 0))
[1 2 3])
Expand Down
6 changes: 4 additions & 2 deletions tests/native_tests/import.hy
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
os.path [exists isdir isfile]
sys :as systest
sys
pytest)
pytest
hy._compat [PYODIDE])


(defn test-imported-bits []
Expand Down Expand Up @@ -202,7 +203,8 @@ in expansions."

;; Now that bytecode is present, reload the module, clear the `require`d
;; macros and tags, and rerun the tests.
(assert (os.path.isfile pyc-file))
(when (not PYODIDE)
(assert (os.path.isfile pyc-file)))

;; Reload the module and clear the local macro context.
(.clear sys.path_importer_cache)
Expand Down
1 change: 0 additions & 1 deletion tests/native_tests/model_patterns.hy
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,4 @@
for n from 1 to 3
for p in [k n (* 10 n)]
do (.append l p) (-= k 1))
(print l)
(assert (= l [2 1 10 -1 2 20 -4 3 30])))
2 changes: 1 addition & 1 deletion tests/native_tests/setv.hy
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
(an (setv x (for [i (range 3)] i (+ i 1))))
(an (setv x (assert True)))

(an (setv x (with [(open "README.md" "r")] 3)))
(an (setv x (with [(open "tests/resources/text.txt" "r")] 3)))
(assert (= x 3))
(an (setv x (try (/ 1 2) (except [ZeroDivisionError] "E1"))))
(assert (= x .5))
Expand Down
18 changes: 9 additions & 9 deletions tests/native_tests/with.hy
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
(import
asyncio
pytest
tests.resources [AsyncWithTest])
tests.resources [async-test AsyncWithTest])

(defn test-context []
(with [fd (open "README.md" "r")] (assert fd))
(with [(open "README.md" "r")] (do)))
(with [fd (open "tests/resources/text.txt" "r")] (assert fd))
(with [(open "tests/resources/text.txt" "r")] (do)))

(defn test-with-return []
(defn read-file [filename]
(with [fd (open filename "r")] (.read fd)))
(assert (!= 0 (len (read-file "README.md")))))
(with [fd (open filename "r" :encoding "UTF-8")] (.read fd)))
(assert (= (read-file "tests/resources/text.txt") "TAARGÜS TAARGÜS\n")))

(defclass WithTest [object]
(defn __init__ [self val]
Expand Down Expand Up @@ -50,21 +50,21 @@
(assert (= t2 2))
(assert (= t3 3))))

(defn test-single-with/a []
(defn [async-test] test-single-with/a []
(asyncio.run
((fn/a []
(with/a [t (AsyncWithTest 1)]
(assert (= t 1)))))))

(defn test-two-with/a []
(defn [async-test] test-two-with/a []
(asyncio.run
((fn/a []
(with/a [t1 (AsyncWithTest 1)
t2 (AsyncWithTest 2)]
(assert (= t1 1))
(assert (= t2 2)))))))

(defn test-thrice-with/a []
(defn [async-test] test-thrice-with/a []
(asyncio.run
((fn/a []
(with/a [t1 (AsyncWithTest 1)
Expand All @@ -74,7 +74,7 @@
(assert (= t2 2))
(assert (= t3 3)))))))

(defn test-quince-with/a []
(defn [async-test] test-quince-with/a []
(asyncio.run
((fn/a []
(with/a [t1 (AsyncWithTest 1)
Expand Down
10 changes: 10 additions & 0 deletions tests/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import pytest

from hy._compat import PYODIDE

in_init = "chippy"


Expand All @@ -9,6 +13,12 @@ def function_with_a_dash():
pass


can_test_async = not PYODIDE
async_test = pytest.mark.skipif(
not can_test_async, reason="`asyncio.run` not implemented"
)


class AsyncWithTest:
def __init__(self, val):
self.val = val
Expand Down
1 change: 1 addition & 0 deletions tests/resources/text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TAARGÜS TAARGÜS
7 changes: 6 additions & 1 deletion tests/test_bin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

import pytest

from hy._compat import PY3_9, PYPY
from hy._compat import PY3_9, PYODIDE, PYPY

if PYODIDE:
pytest.skip(
'`subprocess.Popen` not implemented on Pyodide',
allow_module_level = True)


def pyr(s=""):
Expand Down
9 changes: 8 additions & 1 deletion tests/test_hy2py.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
import itertools
import math
import os
import platform

import pytest

import hy.importer
from hy import mangle
from hy._compat import PYODIDE
from tests.resources import can_test_async


def test_direct_import():
Expand All @@ -13,6 +18,7 @@ def test_direct_import():
assert_stuff(tests.resources.pydemo)


@pytest.mark.skipif(PYODIDE, reason="subprocess.check_call not implemented on Pyodide")
def test_hy2py_import():
import contextlib
import os
Expand Down Expand Up @@ -148,7 +154,8 @@ class C:
assert m.pys_accum == [0, 1, 2, 3, 4]
assert m.py_accum == "01234"

assert asyncio.run(m.coro()) == list("abcdef")
if can_test_async:
assert asyncio.run(m.coro()) == list("abcdef")

assert m.cheese == [1, 1]
assert m.mac_results == ["x", "x"]
Expand Down