From baf16ee9d22d39712905af70a922af6cdb6e287d Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 4 Jun 2022 23:37:31 -0700 Subject: [PATCH 1/4] ci: test on emscripten target This adds CI to build libpython3.11 for wasm32-emscripten and running tests against it. We need to patch instant to work around the emscripten_get_now: https://github.com/sebcrozet/instant/pull/47 We also have to patch emscripten to work aroung the "undefined symbol gxx_personality_v0" error: https://github.com/emscripten-core/emscripten/issues/17128 I set up a nox file to download and install emscripten, download and build cpython, set appropriate environment variables then run cargo test. The workflow just installs python, rust, node, and nox and runs the nox session. I xfailed all the test failures. There are problems with datetime. iter_dict_nosegv and test_filenotfounderror should probably be fixable. The tests that involve threads or asyncio probably can't be fixed. --- .github/workflows/ci.yml | 32 ++++++++ Cargo.toml | 5 ++ emscripten/Makefile | 81 +++++++++++++++++++ ...xx_personality_v0-stub-to-library.js.patch | 28 +++++++ emscripten/env.sh | 10 +++ emscripten/runner.py | 8 ++ noxfile.py | 65 +++++++++++++++ src/ffi/tests.rs | 4 + src/gil.rs | 2 + src/marker.rs | 1 + src/types/datetime.rs | 2 + tests/test_class_basics.rs | 3 + tests/test_compile_error.rs | 3 + tests/test_dict_iter.rs | 1 + tests/test_exceptions.rs | 1 + tests/test_proto_methods.rs | 2 + 16 files changed, 248 insertions(+) create mode 100644 emscripten/Makefile create mode 100644 emscripten/emscripten_patches/0001-Add-_gxx_personality_v0-stub-to-library.js.patch create mode 100644 emscripten/env.sh create mode 100755 emscripten/runner.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96ac286e974..7da18f2b314 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -339,3 +339,35 @@ jobs: with: file: coverage.lcov name: ${{ matrix.os }} + + emscripten: + name: emscripten + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.11.0-beta.1 + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-emscripten + - uses: actions/setup-node@v3 + with: + node-version: 14 + - run: pip install nox + - uses: actions/cache@v3 + id: cache + with: + path: | + .nox/emscripten + key: ${{ hashFiles('emscripten/*') }} - ${{ hashFiles('noxfile.py') }} + - uses: Swatinem/rust-cache@v1 + with: + key: cargo-emscripten-wasm32 + - name: Build + if: steps.cache.outputs.cache-hit != 'true' + run: nox -s build_emscripten + - name: Test + run: nox -s test_emscripten diff --git a/Cargo.toml b/Cargo.toml index 99f6a96c0bc..d24acd192e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,3 +168,8 @@ members = [ no-default-features = true features = ["macros", "num-bigint", "num-complex", "hashbrown", "serde", "multiple-pymethods", "indexmap", "eyre"] rustdoc-args = ["--cfg", "docsrs"] + +[patch.crates-io] +# Instant misspells emscripten_get_now by including a leading underscore. +# https://github.com/sebcrozet/instant/pull/47 +instant = { git = 'https://github.com/hoodmane/instant/', branch= 'emscripten-no-leading-underscore' } diff --git a/emscripten/Makefile b/emscripten/Makefile new file mode 100644 index 00000000000..8256d1b27dd --- /dev/null +++ b/emscripten/Makefile @@ -0,0 +1,81 @@ +CURDIR=$(abspath .) + +BUILDROOT ?= $(CURDIR)/builddir +export EMSDKDIR = $(BUILDROOT)/emsdk + +PLATFORM=wasm32_emscripten +SYSCONFIGDATA_NAME=_sysconfigdata__$(PLATFORM) + +# BASH_ENV tells bash to run pyodide_env.sh on startup, which sets various +# environment variables. The next line instructs make to use bash to run each +# command. +export BASH_ENV := $(CURDIR)/env.sh +SHELL := /bin/bash + +EMSCRIPTEN_VERSION=3.1.13 + +PYMAJORMINORMICRO ?= 3.11.0 +PYPRERELEASE ?= b1 + +version_tuple := $(subst ., ,$(PYMAJORMINORMICRO:v%=%)) +export PYMAJOR=$(word 1,$(version_tuple)) +export PYMINOR=$(word 2,$(version_tuple)) +export PYMICRO=$(word 3,$(version_tuple)) +PYVERSION=$(PYMAJORMINORMICRO)$(PYPRERELEASE) +PYMAJORMINOR=$(PYMAJOR).$(PYMINOR) + + +PYTHONURL=https://www.python.org/ftp/python/$(PYMAJORMINORMICRO)/Python-$(PYVERSION).tgz +PYTHONTARBALL=$(BUILDROOT)/downloads/Python-$(PYVERSION).tgz +PYTHONBUILD=$(BUILDROOT)/build/Python-$(PYVERSION) + +export PYTHONLIBDIR=$(BUILDROOT)/install/Python-$(PYVERSION)/lib + +all: $(PYTHONLIBDIR)/libpython$(PYMAJORMINOR).a + +$(BUILDROOT)/.exists: + mkdir -p $(BUILDROOT) + touch $@ + + +$(EMSDKDIR): $(CURDIR)/emscripten_patches/* $(BUILDROOT)/.exists + git clone https://github.com/emscripten-core/emsdk.git --depth 1 --branch $(EMSCRIPTEN_VERSION) $(EMSDKDIR) + $(EMSDKDIR)/emsdk install $(EMSCRIPTEN_VERSION) + cd $(EMSDKDIR)/upstream/emscripten && cat $(CURDIR)/emscripten_patches/* | patch -p1 + $(EMSDKDIR)/emsdk activate $(EMSCRIPTEN_VERSION) + + +$(PYTHONTARBALL): + [ -d $(BUILDROOT)/downloads ] || mkdir -p $(BUILDROOT)/downloads + wget -q -O $@ $(PYTHONURL) + +$(PYTHONBUILD)/.patched: $(PYTHONTARBALL) + [ -d $(PYTHONBUILD) ] || ( \ + mkdir -p $(dir $(PYTHONBUILD));\ + tar -C $(dir $(PYTHONBUILD)) -xf $(PYTHONTARBALL) \ + ) + touch $@ + +$(PYTHONBUILD)/Makefile: $(PYTHONBUILD)/.patched $(BUILDROOT)/emsdk + cd $(PYTHONBUILD) && \ + CONFIG_SITE=Tools/wasm/config.site-wasm32-emscripten \ + emconfigure ./configure -C \ + --host=wasm32-unknown-emscripten \ + --build=$(shell $(PYTHONBUILD)/config.guess) \ + --with-emscripten-target=browser \ + --enable-wasm-dynamic-linking \ + --with-build-python=python3.11 + +$(PYTHONLIBDIR)/libpython$(PYMAJORMINOR).a : $(PYTHONBUILD)/Makefile + cd $(PYTHONBUILD) && \ + emmake make -j3 libpython$(PYMAJORMINOR).a + + _PYTHON_SYSCONFIGDATA_NAME=$(SYSCONFIGDATA_NAME) _PYTHON_PROJECT_BASE=$(PYTHONBUILD) python3.11 -m sysconfig --generate-posix-vars + cp `cat pybuilddir.txt`/$(SYSCONFIGDATA_NAME).py $(PYTHONBUILD)/Lib + + mkdir -p $(PYTHONLIBDIR) + find $(PYTHONBUILD) -name '*.a' -exec cp {} $(PYTHONLIBDIR) \; + cp -r $(PYTHONBUILD)/Lib $(PYTHONLIBDIR)/python$(PYMAJORMINOR) + +clean: + rm -rf $(BUILDROOT) diff --git a/emscripten/emscripten_patches/0001-Add-_gxx_personality_v0-stub-to-library.js.patch b/emscripten/emscripten_patches/0001-Add-_gxx_personality_v0-stub-to-library.js.patch new file mode 100644 index 00000000000..bd0af28a03f --- /dev/null +++ b/emscripten/emscripten_patches/0001-Add-_gxx_personality_v0-stub-to-library.js.patch @@ -0,0 +1,28 @@ +From 4b56f37c3dc9185a235a8314086c4d7a6239b2f8 Mon Sep 17 00:00:00 2001 +From: Hood Chatham +Date: Sat, 4 Jun 2022 19:19:47 -0700 +Subject: [PATCH] Add _gxx_personality_v0 stub to library.js + +Mitigation for an incompatibility between Rust and Emscripten: +https://github.com/rust-lang/rust/issues/85821 +https://github.com/emscripten-core/emscripten/issues/17128 +--- + src/library.js | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/library.js b/src/library.js +index e7bb4c38e..7d01744df 100644 +--- a/src/library.js ++++ b/src/library.js +@@ -403,6 +403,8 @@ mergeInto(LibraryManager.library, { + abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']); + }, + ++ __gxx_personality_v0: function() {}, ++ + // ========================================================================== + // time.h + // ========================================================================== +-- +2.25.1 + diff --git a/emscripten/env.sh b/emscripten/env.sh new file mode 100644 index 00000000000..814992dd11f --- /dev/null +++ b/emscripten/env.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +# emsdk_env.sh is fairly noisy, and suppress error message if the file doesn't +# exist yet (i.e. before building emsdk) +# shellcheck source=/dev/null +source "$EMSDKDIR/emsdk_env.sh" 2> /dev/null || true +EMCC_PATH=$(which emcc.py || echo ".") +EM_DIR=$(dirname "$EMCC_PATH") +export EM_DIR diff --git a/emscripten/runner.py b/emscripten/runner.py new file mode 100755 index 00000000000..95eaa8d4f36 --- /dev/null +++ b/emscripten/runner.py @@ -0,0 +1,8 @@ +#!/usr/local/bin/python +import pathlib +import sys +import subprocess + +p = pathlib.Path(sys.argv[1]) + +sys.exit(subprocess.call(["node", p.name], cwd=p.parent)) diff --git a/noxfile.py b/noxfile.py index e399a79cf9c..52c8b40ce64 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,5 +1,7 @@ import time from glob import glob +from pathlib import Path +import re import nox @@ -128,3 +130,66 @@ def contributors(session: nox.Session) -> None: for author in authors: print(f"@{author}") + + +class EmscriptenInfo: + def __init__(self): + rootdir = Path(__file__).parent + self.emscripten_dir = rootdir / "emscripten" + self.builddir = rootdir / ".nox/emscripten" + self.builddir.mkdir(exist_ok=True, parents=True) + + self.pyversion = "3.11.0b1" + self.pymajor, self.pyminor, self.pymicro = self.pyversion.split(".") + self.pymicro, self.pydev = re.match( + "([0-9]*)([^0-9].*)?", self.pymicro + ).groups() + if self.pydev is None: + self.pydev = "" + + self.pymajorminor = f"{self.pymajor}.{self.pyminor}" + self.pymajorminormicro = f"{self.pymajorminor}.{self.pymicro}" + + +@nox.session(venv_backend="none") +def build_emscripten(session: nox.Session): + info = EmscriptenInfo() + session.run( + "make", + "-C", + str(info.emscripten_dir), + f"BUILDROOT={info.builddir}", + f"PYMAJORMINORMICRO={info.pymajorminormicro}", + f"PYPRERELEASE={info.pydev}", + external=True, + ) + + +@nox.session(venv_backend="none") +def test_emscripten(session: nox.Session): + info = EmscriptenInfo() + + libdir = info.builddir / f"install/Python-{info.pyversion}/lib" + pythonlibdir = libdir / f"python{info.pymajorminor}" + + target = "wasm32-unknown-emscripten" + + session.env["CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER"] = "python " + str( + info.emscripten_dir / "runner.py" + ) + session.env["RUSTFLAGS"] = " ".join( + [ + f"-L native={libdir}", + "-C link-arg=--preload-file", + f"-C link-arg={pythonlibdir}@/lib/python{info.pymajorminor}", + f"-C link-arg=-lpython{info.pymajorminor}", + "-C link-arg=-lexpat", + "-C link-arg=-lmpdec", + ] + ) + session.env["CARGO_BUILD_TARGET"] = target + session.env["PYO3_CROSS_LIB_DIR"] = pythonlibdir + session.run("rustup", "target", "add", target, "--toolchain", "stable") + session.run( + "bash", "-c", f"source {info.builddir/'emsdk/emsdk_env.sh'} && cargo test" + ) diff --git a/src/ffi/tests.rs b/src/ffi/tests.rs index 8508e6df338..5dfd593cac2 100644 --- a/src/ffi/tests.rs +++ b/src/ffi/tests.rs @@ -6,6 +6,7 @@ use crate::types::PyString; #[cfg(target_endian = "little")] use libc::wchar_t; +#[cfg_attr(target_arch = "wasm32", ignore)] #[test] fn test_datetime_fromtimestamp() { Python::with_gil(|py| { @@ -23,6 +24,7 @@ fn test_datetime_fromtimestamp() { }) } +#[cfg_attr(target_arch = "wasm32", ignore)] #[test] fn test_date_fromtimestamp() { Python::with_gil(|py| { @@ -40,6 +42,7 @@ fn test_date_fromtimestamp() { }) } +#[cfg_attr(target_arch = "wasm32", ignore)] #[test] fn test_utc_timezone() { Python::with_gil(|py| { @@ -183,6 +186,7 @@ fn ucs4() { } #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] #[cfg(not(PyPy))] fn test_get_tzinfo() { crate::Python::with_gil(|py| { diff --git a/src/gil.rs b/src/gil.rs index d5258ed60fc..77f0390df90 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -729,6 +729,7 @@ mod tests { } #[test] + #[cfg_attr(target_arch = "wasm32", ignore)] fn test_clone_without_gil() { use crate::{Py, PyAny}; use std::{sync::Arc, thread}; @@ -799,6 +800,7 @@ mod tests { } #[test] + #[cfg_attr(target_arch = "wasm32", ignore)] fn test_clone_in_other_thread() { use crate::Py; use std::{sync::Arc, thread}; diff --git a/src/marker.rs b/src/marker.rs index 6c27833bee5..3d10f20bb66 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -942,6 +942,7 @@ mod tests { } #[test] + #[cfg_attr(target_arch = "wasm32", ignore)] fn test_allow_threads_releases_and_acquires_gil() { Python::with_gil(|py| { let b = std::sync::Arc::new(std::sync::Barrier::new(2)); diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 2d55caca9b8..d54c72b448a 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -546,6 +546,7 @@ fn opt_to_pyobj(py: Python<'_>, opt: Option<&PyObject>) -> *mut ffi::PyObject { #[cfg(test)] mod tests { #[test] + #[cfg_attr(target_arch = "wasm32", ignore)] fn test_new_with_fold() { crate::Python::with_gil(|py| { use crate::types::{PyDateTime, PyTimeAccess}; @@ -560,6 +561,7 @@ mod tests { #[cfg(not(PyPy))] #[test] + #[cfg_attr(target_arch = "wasm32", ignore)] fn test_get_tzinfo() { crate::Python::with_gil(|py| { use crate::conversion::ToPyObject; diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs index ad8c8c07d8d..fcb35973088 100644 --- a/tests/test_class_basics.rs +++ b/tests/test_class_basics.rs @@ -229,6 +229,7 @@ impl UnsendableChild { } } +#[cfg_attr(target_arch = "wasm32", ignore)] fn test_unsendable() -> PyResult<()> { let obj = std::thread::spawn(|| -> PyResult<_> { Python::with_gil(|py| { @@ -259,6 +260,7 @@ fn test_unsendable() -> PyResult<()> { /// If a class is marked as `unsendable`, it panics when accessed by another thread. #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] #[should_panic( expected = "test_class_basics::UnsendableBase is unsendable, but sent to another thread!" )] @@ -267,6 +269,7 @@ fn panic_unsendable_base() { } #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] #[should_panic( expected = "test_class_basics::UnsendableBase is unsendable, but sent to another thread!" )] diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index f85c925a673..abffaa0fa60 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -1,6 +1,7 @@ #![cfg(feature = "macros")] #[rustversion::stable] +#[cfg_attr(target_arch = "wasm32", ignore)] #[test] fn test_compile_errors() { // stable - require all tests to pass @@ -8,6 +9,7 @@ fn test_compile_errors() { } #[cfg(not(feature = "nightly"))] +#[cfg_attr(target_arch = "wasm32", ignore)] #[rustversion::nightly] #[test] fn test_compile_errors() { @@ -17,6 +19,7 @@ fn test_compile_errors() { } #[cfg(feature = "nightly")] +#[cfg_attr(target_arch = "wasm32", ignore)] #[rustversion::nightly] #[test] fn test_compile_errors() { diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rs index 1a79ca92f81..28f6c0d8d70 100644 --- a/tests/test_dict_iter.rs +++ b/tests/test_dict_iter.rs @@ -2,6 +2,7 @@ use pyo3::prelude::*; use pyo3::types::IntoPyDict; #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] fn iter_dict_nosegv() { let gil = Python::acquire_gil(); let py = gil.python(); diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rs index da42f1b50a0..ed436fe468b 100644 --- a/tests/test_exceptions.rs +++ b/tests/test_exceptions.rs @@ -17,6 +17,7 @@ fn fail_to_open_file() -> PyResult<()> { } #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] #[cfg(not(target_os = "windows"))] fn test_filenotfounderror() { let gil = Python::acquire_gil(); diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index 68881d6fb89..fb641c31f3d 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -698,6 +698,7 @@ impl OnceFuture { } #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] fn test_await() { let gil = Python::acquire_gil(); let py = gil.python(); @@ -747,6 +748,7 @@ impl AsyncIterator { } #[test] +#[cfg_attr(target_arch = "wasm32", ignore)] fn test_anext_aiter() { let gil = Python::acquire_gil(); let py = gil.python(); From eb01df9d738a31b7364fbf56c811ffa5b600ad9a Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 7 Jun 2022 12:40:22 -0700 Subject: [PATCH 2/4] Some cleanup --- emscripten/Makefile | 29 ++++++++++++++++++----------- emscripten/env.sh | 10 +++------- emscripten/pybuilddir.txt | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 emscripten/pybuilddir.txt diff --git a/emscripten/Makefile b/emscripten/Makefile index 8256d1b27dd..eec64876298 100644 --- a/emscripten/Makefile +++ b/emscripten/Makefile @@ -1,26 +1,28 @@ CURDIR=$(abspath .) +# These three are passed in from nox. BUILDROOT ?= $(CURDIR)/builddir +PYMAJORMINORMICRO ?= 3.11.0 +PYPRERELEASE ?= b1 # I'm not sure how to split 3.11.0b1 in Make. + +EMSCRIPTEN_VERSION=3.1.13 + export EMSDKDIR = $(BUILDROOT)/emsdk PLATFORM=wasm32_emscripten SYSCONFIGDATA_NAME=_sysconfigdata__$(PLATFORM) -# BASH_ENV tells bash to run pyodide_env.sh on startup, which sets various -# environment variables. The next line instructs make to use bash to run each -# command. +# BASH_ENV tells bash to source emsdk_env.sh on startup. export BASH_ENV := $(CURDIR)/env.sh +# Use bash to run each command so that env.sh will be used. SHELL := /bin/bash -EMSCRIPTEN_VERSION=3.1.13 - -PYMAJORMINORMICRO ?= 3.11.0 -PYPRERELEASE ?= b1 +# Set version variables. version_tuple := $(subst ., ,$(PYMAJORMINORMICRO:v%=%)) -export PYMAJOR=$(word 1,$(version_tuple)) -export PYMINOR=$(word 2,$(version_tuple)) -export PYMICRO=$(word 3,$(version_tuple)) +PYMAJOR=$(word 1,$(version_tuple)) +PYMINOR=$(word 2,$(version_tuple)) +PYMICRO=$(word 3,$(version_tuple)) PYVERSION=$(PYMAJORMINORMICRO)$(PYPRERELEASE) PYMAJORMINOR=$(PYMAJOR).$(PYMINOR) @@ -29,7 +31,7 @@ PYTHONURL=https://www.python.org/ftp/python/$(PYMAJORMINORMICRO)/Python-$(PYVERS PYTHONTARBALL=$(BUILDROOT)/downloads/Python-$(PYVERSION).tgz PYTHONBUILD=$(BUILDROOT)/build/Python-$(PYVERSION) -export PYTHONLIBDIR=$(BUILDROOT)/install/Python-$(PYVERSION)/lib +PYTHONLIBDIR=$(BUILDROOT)/install/Python-$(PYVERSION)/lib all: $(PYTHONLIBDIR)/libpython$(PYMAJORMINOR).a @@ -38,6 +40,7 @@ $(BUILDROOT)/.exists: touch $@ +# Install emscripten $(EMSDKDIR): $(CURDIR)/emscripten_patches/* $(BUILDROOT)/.exists git clone https://github.com/emscripten-core/emsdk.git --depth 1 --branch $(EMSCRIPTEN_VERSION) $(EMSDKDIR) $(EMSDKDIR)/emsdk install $(EMSCRIPTEN_VERSION) @@ -70,11 +73,15 @@ $(PYTHONLIBDIR)/libpython$(PYMAJORMINOR).a : $(PYTHONBUILD)/Makefile cd $(PYTHONBUILD) && \ emmake make -j3 libpython$(PYMAJORMINOR).a + # Generate sysconfigdata _PYTHON_SYSCONFIGDATA_NAME=$(SYSCONFIGDATA_NAME) _PYTHON_PROJECT_BASE=$(PYTHONBUILD) python3.11 -m sysconfig --generate-posix-vars cp `cat pybuilddir.txt`/$(SYSCONFIGDATA_NAME).py $(PYTHONBUILD)/Lib mkdir -p $(PYTHONLIBDIR) + # Copy libexpat.a, libmpdec.a, and libpython3.11.a + # In noxfile, we explicitly link libexpat and libmpdec via RUSTFLAGS find $(PYTHONBUILD) -name '*.a' -exec cp {} $(PYTHONLIBDIR) \; + # Install Python stdlib cp -r $(PYTHONBUILD)/Lib $(PYTHONLIBDIR)/python$(PYMAJORMINOR) clean: diff --git a/emscripten/env.sh b/emscripten/env.sh index 814992dd11f..87b7b55138e 100644 --- a/emscripten/env.sh +++ b/emscripten/env.sh @@ -1,10 +1,6 @@ #!/bin/bash - -# emsdk_env.sh is fairly noisy, and suppress error message if the file doesn't -# exist yet (i.e. before building emsdk) -# shellcheck source=/dev/null +# Activate emsdk environment. emsdk_env.sh writes a lot to stderr so we suppress +# the output. This also prevents it from complaining when emscripten isn't yet +# installed. source "$EMSDKDIR/emsdk_env.sh" 2> /dev/null || true -EMCC_PATH=$(which emcc.py || echo ".") -EM_DIR=$(dirname "$EMCC_PATH") -export EM_DIR diff --git a/emscripten/pybuilddir.txt b/emscripten/pybuilddir.txt new file mode 100644 index 00000000000..59f2a4a7546 --- /dev/null +++ b/emscripten/pybuilddir.txt @@ -0,0 +1 @@ +build/lib.linux-x86_64-3.11 \ No newline at end of file From 449152667c66fef554828a1671403f8923fc5d2f Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 7 Jun 2022 12:40:29 -0700 Subject: [PATCH 3/4] Remove instant patch --- Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d24acd192e4..99f6a96c0bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,8 +168,3 @@ members = [ no-default-features = true features = ["macros", "num-bigint", "num-complex", "hashbrown", "serde", "multiple-pymethods", "indexmap", "eyre"] rustdoc-args = ["--cfg", "docsrs"] - -[patch.crates-io] -# Instant misspells emscripten_get_now by including a leading underscore. -# https://github.com/sebcrozet/instant/pull/47 -instant = { git = 'https://github.com/hoodmane/instant/', branch= 'emscripten-no-leading-underscore' } From 58f4747c2f372ec0fd7dec22e3408e5dc2d86a87 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 7 Jun 2022 13:13:51 -0700 Subject: [PATCH 4/4] Add explanations for xfails --- src/ffi/tests.rs | 8 ++++---- src/gil.rs | 4 ++-- src/marker.rs | 2 +- src/types/datetime.rs | 4 ++-- tests/test_class_basics.rs | 1 - tests/test_compile_error.rs | 6 +++--- tests/test_dict_iter.rs | 2 +- tests/test_exceptions.rs | 2 +- tests/test_proto_methods.rs | 4 ++-- 9 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/ffi/tests.rs b/src/ffi/tests.rs index 5dfd593cac2..e6867901b9e 100644 --- a/src/ffi/tests.rs +++ b/src/ffi/tests.rs @@ -6,7 +6,7 @@ use crate::types::PyString; #[cfg(target_endian = "little")] use libc::wchar_t; -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons #[test] fn test_datetime_fromtimestamp() { Python::with_gil(|py| { @@ -24,7 +24,7 @@ fn test_datetime_fromtimestamp() { }) } -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons #[test] fn test_date_fromtimestamp() { Python::with_gil(|py| { @@ -42,7 +42,7 @@ fn test_date_fromtimestamp() { }) } -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons #[test] fn test_utc_timezone() { Python::with_gil(|py| { @@ -186,7 +186,7 @@ fn ucs4() { } #[test] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons #[cfg(not(PyPy))] fn test_get_tzinfo() { crate::Python::with_gil(|py| { diff --git a/src/gil.rs b/src/gil.rs index 77f0390df90..37e0ed2495d 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -729,7 +729,7 @@ mod tests { } #[test] - #[cfg_attr(target_arch = "wasm32", ignore)] + #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled fn test_clone_without_gil() { use crate::{Py, PyAny}; use std::{sync::Arc, thread}; @@ -800,7 +800,7 @@ mod tests { } #[test] - #[cfg_attr(target_arch = "wasm32", ignore)] + #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled fn test_clone_in_other_thread() { use crate::Py; use std::{sync::Arc, thread}; diff --git a/src/marker.rs b/src/marker.rs index 3d10f20bb66..e3d48051f8b 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -942,7 +942,7 @@ mod tests { } #[test] - #[cfg_attr(target_arch = "wasm32", ignore)] + #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled fn test_allow_threads_releases_and_acquires_gil() { Python::with_gil(|py| { let b = std::sync::Arc::new(std::sync::Barrier::new(2)); diff --git a/src/types/datetime.rs b/src/types/datetime.rs index d54c72b448a..810f19a4821 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -546,7 +546,7 @@ fn opt_to_pyobj(py: Python<'_>, opt: Option<&PyObject>) -> *mut ffi::PyObject { #[cfg(test)] mod tests { #[test] - #[cfg_attr(target_arch = "wasm32", ignore)] + #[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons fn test_new_with_fold() { crate::Python::with_gil(|py| { use crate::types::{PyDateTime, PyTimeAccess}; @@ -561,7 +561,7 @@ mod tests { #[cfg(not(PyPy))] #[test] - #[cfg_attr(target_arch = "wasm32", ignore)] + #[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons fn test_get_tzinfo() { crate::Python::with_gil(|py| { use crate::conversion::ToPyObject; diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs index fcb35973088..b3ebc5df4d0 100644 --- a/tests/test_class_basics.rs +++ b/tests/test_class_basics.rs @@ -229,7 +229,6 @@ impl UnsendableChild { } } -#[cfg_attr(target_arch = "wasm32", ignore)] fn test_unsendable() -> PyResult<()> { let obj = std::thread::spawn(|| -> PyResult<_> { Python::with_gil(|py| { diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index abffaa0fa60..26d9f66685c 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] #[rustversion::stable] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm #[test] fn test_compile_errors() { // stable - require all tests to pass @@ -9,7 +9,7 @@ fn test_compile_errors() { } #[cfg(not(feature = "nightly"))] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled #[rustversion::nightly] #[test] fn test_compile_errors() { @@ -19,7 +19,7 @@ fn test_compile_errors() { } #[cfg(feature = "nightly")] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm #[rustversion::nightly] #[test] fn test_compile_errors() { diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rs index 28f6c0d8d70..51f54167aec 100644 --- a/tests/test_dict_iter.rs +++ b/tests/test_dict_iter.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; use pyo3::types::IntoPyDict; #[test] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // Not sure why this fails. fn iter_dict_nosegv() { let gil = Python::acquire_gil(); let py = gil.python(); diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rs index ed436fe468b..9483f6ae6d5 100644 --- a/tests/test_exceptions.rs +++ b/tests/test_exceptions.rs @@ -17,7 +17,7 @@ fn fail_to_open_file() -> PyResult<()> { } #[test] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg_attr(target_arch = "wasm32", ignore)] // Not sure why this fails. #[cfg(not(target_os = "windows"))] fn test_filenotfounderror() { let gil = Python::acquire_gil(); diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index fb641c31f3d..635412ca41a 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -698,7 +698,7 @@ impl OnceFuture { } #[test] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop) fn test_await() { let gil = Python::acquire_gil(); let py = gil.python(); @@ -748,7 +748,7 @@ impl AsyncIterator { } #[test] -#[cfg_attr(target_arch = "wasm32", ignore)] +#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop) fn test_anext_aiter() { let gil = Python::acquire_gil(); let py = gil.python();