Add support for conversion to pyo3::PyErr (#47)

* Added convertion to pyo3::PyErr gated behind feature flag

* Added test_pyo3

* fix ci to not test unsupportable feature msrv

* fix rustfmt

Co-authored-by: Jane Lusby <jlusby@yaah.dev>
This commit is contained in:
Ryan Butler 2021-01-05 12:49:15 -05:00 committed by GitHub
parent 60218fff20
commit 1ea7c204e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 14 deletions

View File

@ -24,7 +24,7 @@ jobs:
with:
command: check
test-versions:
test-matrix:
name: Test Suite
runs-on: ubuntu-latest
strategy:
@ -33,10 +33,12 @@ jobs:
- stable
- beta
- nightly
- 1.39.0
features:
- --all-features
- # default
- --no-default-features
- --features track-caller
- --features pyo3
- --all-features
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
@ -48,6 +50,26 @@ jobs:
command: test
args: ${{ matrix.features }}
test-msrv:
name: Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
features:
- # default
- --no-default-features
- --features track-caller
# skip `--features pyo3` and `--all-features` because pyo3 doesn't support this msrv
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.39
override: true
- uses: actions-rs/cargo@v1
with:
command: test
test-os:
name: Test Suite
runs-on: ${{ matrix.os }}

View File

@ -25,6 +25,7 @@ anyhow = "1.0.28"
[dependencies]
indenter = "0.3.0"
once_cell = "1.4.0"
pyo3 = { version = "0.13", optional = true, default-features = false }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
@ -36,7 +37,7 @@ no-dev-version = true
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "Unreleased"
replace="{{version}}"
replace = "{{version}}"
[[package.metadata.release.pre-release-replacements]]
file = "src/lib.rs"
@ -47,22 +48,22 @@ exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "\\.\\.\\.HEAD"
replace="...{{tag_name}}"
replace = "...{{tag_name}}"
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "ReleaseDate"
replace="{{date}}"
replace = "{{date}}"
[[package.metadata.release.pre-release-replacements]]
file="CHANGELOG.md"
search="<!-- next-header -->"
replace="<!-- next-header -->\n\n## [Unreleased] - ReleaseDate"
exactly=1
file = "CHANGELOG.md"
search = "<!-- next-header -->"
replace = "<!-- next-header -->\n\n## [Unreleased] - ReleaseDate"
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file="CHANGELOG.md"
search="<!-- next-url -->"
replace="<!-- next-url -->\n[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD"
exactly=1
file = "CHANGELOG.md"
search = "<!-- next-url -->"
replace = "<!-- next-url -->\n[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD"
exactly = 1

View File

@ -8,6 +8,9 @@ use core::ptr::{self, NonNull};
use core::ops::{Deref, DerefMut};
#[cfg(feature = "pyo3")]
mod pyo3_compat;
impl Report {
/// Create a new error object from any error type.
///

7
src/error/pyo3_compat.rs Normal file
View File

@ -0,0 +1,7 @@
use crate::Report;
impl From<Report> for pyo3::PyErr {
fn from(error: Report) -> Self {
pyo3::exceptions::PyRuntimeError::new_err(format!("{:?}", error))
}
}

33
tests/test_pyo3.rs Normal file
View File

@ -0,0 +1,33 @@
#![cfg(feature = "pyo3")]
use pyo3::prelude::*;
use eyre::{bail, Result, WrapErr};
fn f() -> Result<()> {
use std::io;
bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!"));
}
fn g() -> Result<()> {
f().wrap_err("f failed")
}
fn h() -> Result<()> {
g().wrap_err("g failed")
}
#[test]
fn test_pyo3_exception_contents() {
use pyo3::types::IntoPyDict;
let err = h().unwrap_err();
let expected_contents = format!("{:?}", err);
let pyerr = PyErr::from(err);
Python::with_gil(|py| {
let locals = [("err", pyerr)].into_py_dict(py);
let pyerr = py.run("raise err", None, Some(locals)).unwrap_err();
assert_eq!(pyerr.pvalue(py).to_string(), expected_contents);
})
}