Skip to content

Commit

Permalink
Make PyType::name abi3 compatible
Browse files Browse the repository at this point in the history
The implementation is more complex, because there's no equivalent to tp_name in the limited API
  • Loading branch information
alex committed Sep 8, 2020
1 parent e8936be commit 117f60b
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 18 deletions.
8 changes: 4 additions & 4 deletions guide/src/trait_bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ impl Model for UserModel {
.call_method("get_results", (), None)
.unwrap();

if py_result.get_type().name() != "list" {
panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name());
if py_result.get_type().name().unwrap() != "list" {
panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name().unwrap());
}
py_result.extract()
})
Expand Down Expand Up @@ -536,8 +536,8 @@ impl Model for UserModel {
.call_method("get_results", (), None)
.unwrap();

if py_result.get_type().name() != "list" {
panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name());
if py_result.get_type().name().unwrap() != "list" {
panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name().unwrap());
}
py_result.extract()
})
Expand Down
2 changes: 1 addition & 1 deletion pyo3-derive-backend/src/from_pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl<'a> Enum<'a> {
};
quote!(
#(#var_extracts)*
let type_name = obj.get_type().name();
let type_name = obj.get_type().name()?;
let from = obj
.repr()
.map(|s| format!("{} ({})", s.to_string_lossy(), type_name))
Expand Down
11 changes: 7 additions & 4 deletions src/err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,13 @@ impl<'a> std::fmt::Display for PyDowncastError<'a> {
write!(
f,
"Can't convert {} to {}",
self.from
.repr()
.map(|s| s.to_string_lossy())
.unwrap_or_else(|_| self.from.get_type().name()),
self.from.repr().map(|s| s.to_string_lossy()).or_else(|_| {
self.from
.get_type()
.name()
.map_err(|_| std::fmt::Error)
.map(|s| s.into())
})?,
self.to
)
}
Expand Down
6 changes: 3 additions & 3 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ macro_rules! impl_exception_boilerplate {

impl std::fmt::Debug for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let type_name = self.get_type().name();
f.debug_struct(&*type_name)
let type_name = self.get_type().name().map_err(|_| std::fmt::Error)?;
f.debug_struct(type_name)
// TODO: print out actual fields!
.finish()
}
}

impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let type_name = self.get_type().name();
let type_name = self.get_type().name().map_err(|_| std::fmt::Error)?;
write!(f, "{}", type_name)?;
if let Ok(s) = self.str() {
write!(f, ": {}", &s.to_string_lossy())
Expand Down
6 changes: 2 additions & 4 deletions src/types/typeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use crate::err::{PyErr, PyResult};
use crate::instance::PyNativeType;
use crate::type_object::PyTypeObject;
use crate::{ffi, AsPyPointer, PyAny, Python};
use std::borrow::Cow;
use std::ffi::CStr;

/// Represents a reference to a Python `type object`.
#[repr(transparent)]
Expand Down Expand Up @@ -39,8 +37,8 @@ impl PyType {
}

/// Gets the name of the `PyType`.
pub fn name(&self) -> Cow<str> {
unsafe { CStr::from_ptr((*self.as_type_ptr()).tp_name).to_string_lossy() }
pub fn name(&self) -> PyResult<&str> {
self.getattr("__qualname__")?.extract()
}

/// Checks whether `self` is subclass of type `T`.
Expand Down
4 changes: 2 additions & 2 deletions tests/test_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl ClassMethod {
#[classmethod]
/// Test class method.
fn method(cls: &PyType) -> PyResult<String> {
Ok(format!("{}.method()!", cls.name()))
Ok(format!("{}.method()!", cls.name()?))
}
}

Expand Down Expand Up @@ -104,7 +104,7 @@ struct ClassMethodWithArgs {}
impl ClassMethodWithArgs {
#[classmethod]
fn method(cls: &PyType, input: &PyString) -> PyResult<String> {
Ok(format!("{}.method({})", cls.name(), input))
Ok(format!("{}.method({})", cls.name()?, input))
}
}

Expand Down

0 comments on commit 117f60b

Please sign in to comment.