From 31e937ea2d9491879f712ed2beda54bfcaa8c510 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 5 Jun 2023 19:23:14 -0700 Subject: [PATCH] NFC Add test for pyo3 catching rust panics (#3905) This adds a test PyO3 module which intentionally panics and checks that it gets properly caught and converted to a Python exception. I think this test is failing on the wasm-exceptions branch, but in any case it is good to have explicit test coverage for this. --- packages/rust-panic-test/meta.yaml | 9 +++++++++ packages/rust-panic-test/src/Cargo.lock | 7 +++++++ packages/rust-panic-test/src/Cargo.toml | 19 +++++++++++++++++++ packages/rust-panic-test/src/pyproject.toml | 3 +++ packages/rust-panic-test/src/setup.py | 12 ++++++++++++ packages/rust-panic-test/src/src/lib.rs | 18 ++++++++++++++++++ packages/rust-panic-test/test_rust_panic.py | 12 ++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 packages/rust-panic-test/meta.yaml create mode 100644 packages/rust-panic-test/src/Cargo.lock create mode 100644 packages/rust-panic-test/src/Cargo.toml create mode 100644 packages/rust-panic-test/src/pyproject.toml create mode 100644 packages/rust-panic-test/src/setup.py create mode 100644 packages/rust-panic-test/src/src/lib.rs create mode 100644 packages/rust-panic-test/test_rust_panic.py diff --git a/packages/rust-panic-test/meta.yaml b/packages/rust-panic-test/meta.yaml new file mode 100644 index 000000000..18b6ffe8a --- /dev/null +++ b/packages/rust-panic-test/meta.yaml @@ -0,0 +1,9 @@ +package: + name: rust-panic-test + version: "1.0" +source: + path: src +build: + script: | + rustup toolchain install ${RUST_TOOLCHAIN} && rustup default ${RUST_TOOLCHAIN} + rustup target add wasm32-unknown-emscripten --toolchain ${RUST_TOOLCHAIN} diff --git a/packages/rust-panic-test/src/Cargo.lock b/packages/rust-panic-test/src/Cargo.lock new file mode 100644 index 000000000..e7cecae9f --- /dev/null +++ b/packages/rust-panic-test/src/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "hello-world" +version = "0.1.0" diff --git a/packages/rust-panic-test/src/Cargo.toml b/packages/rust-panic-test/src/Cargo.toml new file mode 100644 index 000000000..235085e5d --- /dev/null +++ b/packages/rust-panic-test/src/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rust-panic-test" +version = "0.1.0" +edition = "2018" +publish = false + +[dependencies] +pyo3 = { version = "0.15.2" } + +[features] +extension-module = ["pyo3/extension-module"] +default = ["extension-module"] + +[lib] +crate-type = ["cdylib"] + +[profile.release] +lto = "thin" +overflow-checks = true diff --git a/packages/rust-panic-test/src/pyproject.toml b/packages/rust-panic-test/src/pyproject.toml new file mode 100644 index 000000000..8619d8784 --- /dev/null +++ b/packages/rust-panic-test/src/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel", "setuptools-rust"] +build-backend = "setuptools.build_meta" diff --git a/packages/rust-panic-test/src/setup.py b/packages/rust-panic-test/src/setup.py new file mode 100644 index 000000000..21a44eec3 --- /dev/null +++ b/packages/rust-panic-test/src/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup +from setuptools_rust import Binding, RustExtension + +setup( + name="rust_panic_test", + version="1.0", + rust_extensions=[ + RustExtension("rust_panic_test", "Cargo.toml", binding=Binding.PyO3) + ], + # rust extensions are not zip safe, just like C-extensions. + zip_safe=False, +) diff --git a/packages/rust-panic-test/src/src/lib.rs b/packages/rust-panic-test/src/src/lib.rs new file mode 100644 index 000000000..26de2a73a --- /dev/null +++ b/packages/rust-panic-test/src/src/lib.rs @@ -0,0 +1,18 @@ + + +#[pyo3::prelude::pyfunction] +fn panic_test(data: &[u8]) -> bool { + if data[0] < 6 { + panic!("this is a {} {message:?}", "fancy", message = data); + } + data[0] < 20 +} + + + +#[pyo3::prelude::pymodule] +fn rust_panic_test(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> { + m.add_function(pyo3::wrap_pyfunction!(panic_test, m)?)?; + m.add("PanicException", py.get_type::())?; + Ok(()) +} diff --git a/packages/rust-panic-test/test_rust_panic.py b/packages/rust-panic-test/test_rust_panic.py new file mode 100644 index 000000000..dece19f87 --- /dev/null +++ b/packages/rust-panic-test/test_rust_panic.py @@ -0,0 +1,12 @@ +from pytest_pyodide import run_in_pyodide + + +@run_in_pyodide(packages=["rust-panic-test"]) +def test_rust_panic(selenium): + from pytest import raises + from rust_panic_test import PanicException, panic_test + + assert not panic_test(bytes([20])) + assert panic_test(bytes([10])) + with raises(PanicException): + panic_test(bytes([1]))