Bug Description
Opening as a bug, but this might be considered a feature request
First - thank you for such a great library
We're using it to speedup some python in a web service running under gunicorn and hit a case where a SystemExit is swallowed and converted to a TypeError if it happened to be raised inside a field extractor in a struct
I believe this code is acting as a bare except: but IMO should be more like except Exception:
|
pub fn extract_struct_field<'a, 'py, T>( |
|
obj: &'a Bound<'py, PyAny>, |
|
struct_name: &str, |
|
field_name: &str, |
|
) -> PyResult<T> |
|
where |
|
T: FromPyObject<'a, 'py>, |
|
{ |
|
match obj.extract() { |
|
Ok(value) => Ok(value), |
|
Err(err) => Err(failed_to_extract_struct_field( |
|
obj.py(), |
|
err.into(), |
|
struct_name, |
|
field_name, |
|
)), |
|
} |
|
} |
This swallows exceptions deriving from BaseException like KeyboardInterrupt (user pressing Ctrl+C) and SystemExit (used by gunicorn to signal worker shutdown - https://github.com/benoitc/gunicorn/blob/a86ea1e4e6c271d1cd1823c7e14490123f9238fe/gunicorn/workers/base.py#L204
Steps to Reproduce
Seems to only happen with nested structs, see full repro here - https://github.com/vpoverennov/pyo3-exceptions-repro/blob/main/src/lib.rs
with a Nested class like this (simulating SystemExit being thrown into an otherwise innocuous getter function)
class Nested:
@property
def v(self):
raise SystemExit(1)
This works fine and SystemExit is raised when calling repro_w
#[derive(FromPyObject, Debug)]
struct Nested {
v: i32,
}
#[pyfunction]
fn repro_n(b: Nested) -> i32 {
println!("repro_n: {:?}", b);
b.v
}
But this converts SystemExit into a TypeError: argument 'a': failed to extract field Wrapper.n
#[derive(FromPyObject, Debug)]
struct Wrapper {
n: Nested,
}
#[derive(FromPyObject, Debug)]
struct Nested {
v: i32,
}
#[pyfunction]
fn repro_w(a: Wrapper) -> i32 {
println!("repro_w: {:?}", a);
a.n.v
}
Backtrace
Your operating system and version
Windows 10 / MacOS
Your Python version (python --version)
Python 3.10
Your Rust version (rustc --version)
rustc 1.90.0 (1159e78c4 2025-09-14)
Your PyO3 version
0.26.0
How did you install python? Did you use a virtualenv?
not relevant
Additional Info
No response
Bug Description
Opening as a bug, but this might be considered a feature request
First - thank you for such a great library
We're using it to speedup some python in a web service running under gunicorn and hit a case where a
SystemExitis swallowed and converted to a TypeError if it happened to be raised inside a field extractor in a structI believe this code is acting as a bare
except:but IMO should be more likeexcept Exception:pyo3/src/impl_/frompyobject.rs
Lines 45 to 62 in ae64e57
This swallows exceptions deriving from
BaseExceptionlikeKeyboardInterrupt(user pressing Ctrl+C) andSystemExit(used by gunicorn to signal worker shutdown - https://github.com/benoitc/gunicorn/blob/a86ea1e4e6c271d1cd1823c7e14490123f9238fe/gunicorn/workers/base.py#L204Steps to Reproduce
Seems to only happen with nested structs, see full repro here - https://github.com/vpoverennov/pyo3-exceptions-repro/blob/main/src/lib.rs
with a
Nestedclass like this (simulating SystemExit being thrown into an otherwise innocuous getter function)This works fine and
SystemExitis raised when callingrepro_wBut this converts
SystemExitinto aTypeError: argument 'a': failed to extract field Wrapper.nBacktrace
Your operating system and version
Windows 10 / MacOS
Your Python version (
python --version)Python 3.10
Your Rust version (
rustc --version)rustc 1.90.0 (1159e78c4 2025-09-14)
Your PyO3 version
0.26.0
How did you install python? Did you use a virtualenv?
not relevant
Additional Info
No response