Skip to content

Commit

Permalink
stop panic on to_string, report using write_unraisable instead
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin authored and adamreichold committed May 9, 2023
1 parent c27a633 commit 52dca88
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
1 change: 1 addition & 0 deletions newsfragments/3060.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Stop panic on `fmt::Display`, instead return `"<unprintable object>"` string and report error via `sys.unraisablehook()`
8 changes: 8 additions & 0 deletions src/gil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,14 @@ pub(crate) fn ensure_gil_unchecked() -> EnsureGIL {
}
}

/// Yields access to the GIL only if it is already held
pub(crate) fn try_ensure_gil() -> Option<EnsureGIL> {
if gil_is_acquired() {
Some(EnsureGIL(None))
} else {
None
}
}
/// Struct used internally which avoids acquiring the GIL where it's not necessary.
pub(crate) struct EnsureGIL(Option<GILGuard>);

Expand Down
8 changes: 8 additions & 0 deletions src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,14 @@ impl Python<'_> {
{
f(gil::ensure_gil_unchecked().python())
}

/// Similar to [`Self::with_gil`] but only provides access to the GIL if it is already held.
pub fn try_with_gil<F, R>(f: F) -> Option<R>
where
F: for<'py> FnOnce(Python<'py>) -> R,
{
gil::try_ensure_gil().map(|gil| f(unsafe { gil.python() }))
}
}

impl<'py> Python<'py> {
Expand Down
11 changes: 9 additions & 2 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,15 @@ macro_rules! pyobject_native_type_base(
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error>
{
let s = self.str().or(::std::result::Result::Err(::std::fmt::Error))?;
f.write_str(&s.to_string_lossy())
match self.str() {
::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
::std::result::Result::Err(err) => err.write_unraisable(self.py(), ::std::option::Option::Some(self)),
}

match self.get_type().name() {
::std::result::Result::Ok(name) => ::std::write!(f, "<unprintable {} object>", name),
::std::result::Result::Err(_err) => f.write_str("<unprintable object>"),
}
}
}

Expand Down

0 comments on commit 52dca88

Please sign in to comment.