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 ca521c4
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ mod test {
.expect_err("raising should have given us an error")
.instance(py);
write!(&mut out, "{}", err).expect("successful format");
assert_eq!(out, "Exception: banana");
assert_eq!(out, "builtins.Exception: banana");
}

#[test]
Expand All @@ -623,13 +623,13 @@ mod test {
.expect_err("raising should have given us an error")
.instance(py);
write!(&mut out, "{}", err).expect("successful format");
assert_eq!(out, "Exception: banana");
assert_eq!(out, "builtins.Exception: banana");
out.clear();
let convert_ref: &super::PyBaseException =
unsafe { &*(err.as_ptr() as *const _ as *const _) };
let source = convert_ref.source().expect("cause should exist");
write!(&mut out, "{}", source).expect("successful format");
assert_eq!(out, "TypeError: peach");
assert_eq!(out, "builtins.TypeError: peach");
let source_source = source.source();
assert!(source_source.is_none(), "source_source should be None");
}
Expand Down
21 changes: 19 additions & 2 deletions src/types/typeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ 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 @@ -40,7 +39,25 @@ 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() }
let type_name: String = self
.getattr("__name__")
.expect("Error accessing __name__")
.extract()
.expect("__name__ must be a string");
let full_name = match self.getattr("__module__") {
Ok(module_name) => {
let module_name: String =
module_name.extract().expect("__module__ must be a string");
format!("{}.{}", module_name, type_name)
}
Err(e) => {
if !e.is_instance::<crate::exceptions::PyAttributeError>(self.py()) {
panic!("__module__ raised an exception besides AttributeError");
}
type_name
}
};
Cow::Owned(full_name)
}

/// Checks whether `self` is subclass of type `T`.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_frompyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ fn test_err_rename() {
PyErrValue::ToObject(to) => {
let o = to.to_object(py);
let s = String::extract(o.as_ref(py)).expect("Err val is not a string");
assert_eq!(s, "Can't convert {} (dict) to Union[str, uint, int]")
assert_eq!(s, "Can't convert {} (builtins.dict) to Union[str, uint, int]")
}
_ => panic!("Expected PyErrValue::ToObject"),
},
Expand Down
2 changes: 1 addition & 1 deletion tests/test_inheritance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn mutation_fails() {
.unwrap_err();
assert_eq!(
&e.instance(py).to_string(),
"RuntimeError: Already borrowed"
"builtins.RuntimeError: Already borrowed"
)
}

Expand Down

0 comments on commit ca521c4

Please sign in to comment.