port `Python::get_type` to `Bound` API (#3846)

* port `Python::get_type` to `Bound` API

* fix `is_subclass_and_is_instance` FIXME
This commit is contained in:
Icxolu 2024-02-18 19:27:19 +01:00 committed by GitHub
parent f04ad56df4
commit 4ce9c35983
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 175 additions and 157 deletions

View File

@ -401,7 +401,7 @@ impl SubSubClass {
# pyo3::py_run!(py, subsub, "assert subsub.method3() == 3000"); # pyo3::py_run!(py, subsub, "assert subsub.method3() == 3000");
# let subsub = SubSubClass::factory_method(py, 2).unwrap(); # let subsub = SubSubClass::factory_method(py, 2).unwrap();
# let subsubsub = SubSubClass::factory_method(py, 3).unwrap(); # let subsubsub = SubSubClass::factory_method(py, 3).unwrap();
# let cls = py.get_type::<SubSubClass>(); # let cls = py.get_type_bound::<SubSubClass>();
# pyo3::py_run!(py, subsub cls, "assert not isinstance(subsub, cls)"); # pyo3::py_run!(py, subsub cls, "assert not isinstance(subsub, cls)");
# pyo3::py_run!(py, subsubsub cls, "assert isinstance(subsubsub, cls)"); # pyo3::py_run!(py, subsubsub cls, "assert isinstance(subsubsub, cls)");
# }); # });
@ -497,7 +497,7 @@ impl MyDict {
// some custom methods that use `private` here... // some custom methods that use `private` here...
} }
# Python::with_gil(|py| { # Python::with_gil(|py| {
# let cls = py.get_type::<MyDict>(); # let cls = py.get_type_bound::<MyDict>();
# pyo3::py_run!(py, cls, "cls(a=1, b=2)") # pyo3::py_run!(py, cls, "cls(a=1, b=2)")
# }); # });
# } # }
@ -767,7 +767,7 @@ impl MyClass {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let my_class = py.get_type::<MyClass>(); let my_class = py.get_type_bound::<MyClass>();
pyo3::py_run!(py, my_class, "assert my_class.my_attribute == 'hello'") pyo3::py_run!(py, my_class, "assert my_class.my_attribute == 'hello'")
}); });
``` ```
@ -1026,7 +1026,7 @@ enum MyEnum {
Python::with_gil(|py| { Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant).unwrap(); let x = Py::new(py, MyEnum::Variant).unwrap();
let y = Py::new(py, MyEnum::OtherVariant).unwrap(); let y = Py::new(py, MyEnum::OtherVariant).unwrap();
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
pyo3::py_run!(py, x y cls, r#" pyo3::py_run!(py, x y cls, r#"
assert x == cls.Variant assert x == cls.Variant
assert y == cls.OtherVariant assert y == cls.OtherVariant
@ -1046,7 +1046,7 @@ enum MyEnum {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
let x = MyEnum::Variant as i32; // The exact value is assigned by the compiler. let x = MyEnum::Variant as i32; // The exact value is assigned by the compiler.
pyo3::py_run!(py, cls x, r#" pyo3::py_run!(py, cls x, r#"
assert int(cls.Variant) == x assert int(cls.Variant) == x
@ -1068,7 +1068,7 @@ enum MyEnum{
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
let x = Py::new(py, MyEnum::Variant).unwrap(); let x = Py::new(py, MyEnum::Variant).unwrap();
pyo3::py_run!(py, cls x, r#" pyo3::py_run!(py, cls x, r#"
assert repr(x) == 'MyEnum.Variant' assert repr(x) == 'MyEnum.Variant'
@ -1094,7 +1094,7 @@ impl MyEnum {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
pyo3::py_run!(py, cls, "assert repr(cls.Answer) == '42'") pyo3::py_run!(py, cls, "assert repr(cls.Answer) == '42'")
}) })
``` ```
@ -1111,7 +1111,7 @@ enum MyEnum {
Python::with_gil(|py| { Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant).unwrap(); let x = Py::new(py, MyEnum::Variant).unwrap();
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
pyo3::py_run!(py, x cls, r#" pyo3::py_run!(py, x cls, r#"
assert repr(x) == 'RenamedEnum.UPPERCASE' assert repr(x) == 'RenamedEnum.UPPERCASE'
assert x == cls.UPPERCASE assert x == cls.UPPERCASE
@ -1165,7 +1165,7 @@ enum Shape {
Python::with_gil(|py| { Python::with_gil(|py| {
let circle = Shape::Circle { radius: 10.0 }.into_py(py); let circle = Shape::Circle { radius: 10.0 }.into_py(py);
let square = Shape::RegularPolygon { side_count: 4, radius: 10.0 }.into_py(py); let square = Shape::RegularPolygon { side_count: 4, radius: 10.0 }.into_py(py);
let cls = py.get_type::<Shape>(); let cls = py.get_type_bound::<Shape>();
pyo3::py_run!(py, circle square cls, r#" pyo3::py_run!(py, circle square cls, r#"
assert isinstance(circle, cls) assert isinstance(circle, cls)
assert isinstance(circle, cls.Circle) assert isinstance(circle, cls.Circle)
@ -1204,7 +1204,7 @@ enum MyEnum {
Python::with_gil(|py| { Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant { i: 42 }).unwrap(); let x = Py::new(py, MyEnum::Variant { i: 42 }).unwrap();
let cls = py.get_type::<MyEnum>(); let cls = py.get_type_bound::<MyEnum>();
pyo3::py_run!(py, x cls, r#" pyo3::py_run!(py, x cls, r#"
assert isinstance(x, cls) assert isinstance(x, cls)
assert not isinstance(x, cls.Variant) assert not isinstance(x, cls.Variant)
@ -1308,7 +1308,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass {
} }
# Python::with_gil(|py| { # Python::with_gil(|py| {
# let cls = py.get_type::<MyClass>(); # let cls = py.get_type_bound::<MyClass>();
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'") # pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
# }); # });
# } # }

View File

@ -24,7 +24,7 @@ use pyo3::exceptions::PyException;
create_exception!(mymodule, CustomError, PyException); create_exception!(mymodule, CustomError, PyException);
Python::with_gil(|py| { Python::with_gil(|py| {
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict_bound(py); let ctx = [("CustomError", py.get_type_bound::<CustomError>())].into_py_dict_bound(py);
pyo3::py_run!( pyo3::py_run!(
py, py,
*ctx, *ctx,
@ -46,7 +46,7 @@ pyo3::create_exception!(mymodule, CustomError, PyException);
#[pymodule] #[pymodule]
fn mymodule(py: Python<'_>, m: &PyModule) -> PyResult<()> { fn mymodule(py: Python<'_>, m: &PyModule) -> PyResult<()> {
// ... other elements added to module ... // ... other elements added to module ...
m.add("CustomError", py.get_type::<CustomError>())?; m.add("CustomError", py.get_type_bound::<CustomError>())?;
Ok(()) Ok(())
} }

View File

@ -1086,7 +1086,7 @@ pub fn gen_complex_enum_variant_attr(
let associated_method = quote! { let associated_method = quote! {
fn #wrapper_ident(py: _pyo3::Python<'_>) -> _pyo3::PyResult<_pyo3::PyObject> { fn #wrapper_ident(py: _pyo3::Python<'_>) -> _pyo3::PyResult<_pyo3::PyObject> {
#deprecations #deprecations
::std::result::Result::Ok(py.get_type::<#variant_cls>().into()) ::std::result::Result::Ok(py.get_type_bound::<#variant_cls>().into_any().unbind())
} }
}; };

View File

@ -52,9 +52,7 @@ use crate::types::{
}; };
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
use crate::{intern, DowncastError}; use crate::{intern, DowncastError};
use crate::{ use crate::{Bound, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject};
Bound, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python, ToPyObject,
};
use chrono::offset::{FixedOffset, Utc}; use chrono::offset::{FixedOffset, Utc};
use chrono::{ use chrono::{
DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike, DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike,
@ -461,7 +459,7 @@ fn warn_truncated_leap_second(obj: &Bound<'_, PyAny>) {
let py = obj.py(); let py = obj.py();
if let Err(e) = PyErr::warn_bound( if let Err(e) = PyErr::warn_bound(
py, py,
&py.get_type::<PyUserWarning>().as_borrowed(), &py.get_type_bound::<PyUserWarning>(),
"ignored leap-second, `datetime` does not support leap-seconds", "ignored leap-second, `datetime` does not support leap-seconds",
0, 0,
) { ) {

View File

@ -91,12 +91,8 @@ macro_rules! bigint_conversion {
} else { } else {
None None
}; };
py.get_type::<PyLong>() py.get_type_bound::<PyLong>()
.call_method( .call_method("from_bytes", (bytes_obj, "little"), kwargs.as_ref())
"from_bytes",
(bytes_obj, "little"),
kwargs.as_ref().map(crate::Bound::as_gil_ref),
)
.expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar .expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar
.into() .into()
} }

View File

@ -724,7 +724,7 @@ impl PyErr {
/// # use pyo3::prelude::*; /// # use pyo3::prelude::*;
/// # fn main() -> PyResult<()> { /// # fn main() -> PyResult<()> {
/// Python::with_gil(|py| { /// Python::with_gil(|py| {
/// let user_warning = py.get_type::<pyo3::exceptions::PyUserWarning>().as_borrowed(); /// let user_warning = py.get_type_bound::<pyo3::exceptions::PyUserWarning>();
/// PyErr::warn_bound(py, &user_warning, "I am warning you", 0)?; /// PyErr::warn_bound(py, &user_warning, "I am warning you", 0)?;
/// Ok(()) /// Ok(())
/// }) /// })
@ -1080,7 +1080,7 @@ impl_signed_integer!(isize);
mod tests { mod tests {
use super::PyErrState; use super::PyErrState;
use crate::exceptions::{self, PyTypeError, PyValueError}; use crate::exceptions::{self, PyTypeError, PyValueError};
use crate::{PyErr, PyNativeType, PyTypeInfo, Python}; use crate::{PyErr, PyTypeInfo, Python};
#[test] #[test]
fn no_error() { fn no_error() {
@ -1278,7 +1278,7 @@ mod tests {
// GIL locked should prevent effects to be visible to other testing // GIL locked should prevent effects to be visible to other testing
// threads. // threads.
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<exceptions::PyUserWarning>().as_borrowed(); let cls = py.get_type_bound::<exceptions::PyUserWarning>();
// Reset warning filter to default state // Reset warning filter to default state
let warnings = py.import_bound("warnings").unwrap(); let warnings = py.import_bound("warnings").unwrap();
@ -1293,14 +1293,14 @@ mod tests {
// Test with raising // Test with raising
warnings warnings
.call_method1("simplefilter", ("error", cls)) .call_method1("simplefilter", ("error", &cls))
.unwrap(); .unwrap();
PyErr::warn_bound(py, &cls, "I am warning you", 0).unwrap_err(); PyErr::warn_bound(py, &cls, "I am warning you", 0).unwrap_err();
// Test with error for an explicit module // Test with error for an explicit module
warnings.call_method0("resetwarnings").unwrap(); warnings.call_method0("resetwarnings").unwrap();
warnings warnings
.call_method1("filterwarnings", ("error", "", cls, "pyo3test")) .call_method1("filterwarnings", ("error", "", &cls, "pyo3test"))
.unwrap(); .unwrap();
// This has the wrong module and will not raise, just be emitted // This has the wrong module and will not raise, just be emitted

View File

@ -72,7 +72,7 @@ macro_rules! impl_exception_boilerplate {
/// import_exception!(socket, gaierror); /// import_exception!(socket, gaierror);
/// ///
/// Python::with_gil(|py| { /// Python::with_gil(|py| {
/// let ctx = [("gaierror", py.get_type::<gaierror>())].into_py_dict_bound(py); /// let ctx = [("gaierror", py.get_type_bound::<gaierror>())].into_py_dict_bound(py);
/// pyo3::py_run!(py, *ctx, "import socket; assert gaierror is socket.gaierror"); /// pyo3::py_run!(py, *ctx, "import socket; assert gaierror is socket.gaierror");
/// }); /// });
/// ///
@ -160,7 +160,7 @@ macro_rules! import_exception {
/// ///
/// #[pymodule] /// #[pymodule]
/// fn my_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { /// fn my_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
/// m.add("MyError", py.get_type::<MyError>())?; /// m.add("MyError", py.get_type_bound::<MyError>())?;
/// m.add_function(wrap_pyfunction!(raise_myerror, py)?)?; /// m.add_function(wrap_pyfunction!(raise_myerror, py)?)?;
/// Ok(()) /// Ok(())
/// } /// }
@ -168,7 +168,7 @@ macro_rules! import_exception {
/// # Python::with_gil(|py| -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> {
/// # let fun = wrap_pyfunction!(raise_myerror, py)?; /// # let fun = wrap_pyfunction!(raise_myerror, py)?;
/// # let locals = pyo3::types::PyDict::new_bound(py); /// # let locals = pyo3::types::PyDict::new_bound(py);
/// # locals.set_item("MyError", py.get_type::<MyError>())?; /// # locals.set_item("MyError", py.get_type_bound::<MyError>())?;
/// # locals.set_item("raise_myerror", fun)?; /// # locals.set_item("raise_myerror", fun)?;
/// # /// #
/// # py.run_bound( /// # py.run_bound(
@ -241,7 +241,6 @@ macro_rules! create_exception_type_object {
impl $name { impl $name {
fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject {
use $crate::sync::GILOnceCell; use $crate::sync::GILOnceCell;
use $crate::PyNativeType;
static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> =
GILOnceCell::new(); GILOnceCell::new();
@ -251,7 +250,7 @@ macro_rules! create_exception_type_object {
py, py,
concat!(stringify!($module), ".", stringify!($name)), concat!(stringify!($module), ".", stringify!($name)),
$doc, $doc,
::std::option::Option::Some(&py.get_type::<$base>().as_borrowed()), ::std::option::Option::Some(&py.get_type_bound::<$base>()),
::std::option::Option::None, ::std::option::Option::None,
).expect("Failed to initialize new exception type.") ).expect("Failed to initialize new exception type.")
).as_ptr() as *mut $crate::ffi::PyTypeObject ).as_ptr() as *mut $crate::ffi::PyTypeObject
@ -904,7 +903,7 @@ mod tests {
create_exception!(mymodule, CustomError, PyException); create_exception!(mymodule, CustomError, PyException);
Python::with_gil(|py| { Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>(); let error_type = py.get_type_bound::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let ctx = [("CustomError", error_type)].into_py_dict_bound(py);
let type_description: String = py let type_description: String = py
.eval_bound("str(CustomError)", None, Some(&ctx)) .eval_bound("str(CustomError)", None, Some(&ctx))
@ -927,7 +926,7 @@ mod tests {
fn custom_exception_dotted_module() { fn custom_exception_dotted_module() {
create_exception!(mymodule.exceptions, CustomError, PyException); create_exception!(mymodule.exceptions, CustomError, PyException);
Python::with_gil(|py| { Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>(); let error_type = py.get_type_bound::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let ctx = [("CustomError", error_type)].into_py_dict_bound(py);
let type_description: String = py let type_description: String = py
.eval_bound("str(CustomError)", None, Some(&ctx)) .eval_bound("str(CustomError)", None, Some(&ctx))
@ -946,7 +945,7 @@ mod tests {
create_exception!(mymodule, CustomError, PyException, "Some docs"); create_exception!(mymodule, CustomError, PyException, "Some docs");
Python::with_gil(|py| { Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>(); let error_type = py.get_type_bound::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let ctx = [("CustomError", error_type)].into_py_dict_bound(py);
let type_description: String = py let type_description: String = py
.eval_bound("str(CustomError)", None, Some(&ctx)) .eval_bound("str(CustomError)", None, Some(&ctx))
@ -979,7 +978,7 @@ mod tests {
); );
Python::with_gil(|py| { Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>(); let error_type = py.get_type_bound::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let ctx = [("CustomError", error_type)].into_py_dict_bound(py);
let type_description: String = py let type_description: String = py
.eval_bound("str(CustomError)", None, Some(&ctx)) .eval_bound("str(CustomError)", None, Some(&ctx))

View File

@ -166,7 +166,10 @@ pub fn from_py_with_with_default<'a, 'py, T>(
#[cold] #[cold]
pub fn argument_extraction_error(py: Python<'_>, arg_name: &str, error: PyErr) -> PyErr { pub fn argument_extraction_error(py: Python<'_>, arg_name: &str, error: PyErr) -> PyErr {
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
if error.get_type_bound(py).is(py.get_type::<PyTypeError>()) { if error
.get_type_bound(py)
.is(&py.get_type_bound::<PyTypeError>())
{
let remapped_error = PyTypeError::new_err(format!( let remapped_error = PyTypeError::new_err(format!(
"argument '{}': {}", "argument '{}': {}",
arg_name, arg_name,

View File

@ -73,7 +73,7 @@
/// } /// }
/// ///
/// Python::with_gil(|py| { /// Python::with_gil(|py| {
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict_bound(py); /// let locals = [("C", py.get_type_bound::<MyClass>())].into_py_dict_bound(py);
/// pyo3::py_run!(py, *locals, "c = C()"); /// pyo3::py_run!(py, *locals, "c = C()");
/// }); /// });
/// ``` /// ```

View File

@ -728,12 +728,28 @@ impl<'py> Python<'py> {
} }
/// Gets the Python type object for type `T`. /// Gets the Python type object for type `T`.
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "`Python::get_type` will be replaced by `Python::get_type_bound` in a future PyO3 version"
)
)]
#[inline] #[inline]
pub fn get_type<T>(self) -> &'py PyType pub fn get_type<T>(self) -> &'py PyType
where where
T: PyTypeInfo, T: PyTypeInfo,
{ {
T::type_object_bound(self).into_gil_ref() self.get_type_bound::<T>().into_gil_ref()
}
/// Gets the Python type object for type `T`.
#[inline]
pub fn get_type_bound<T>(self) -> Bound<'py, PyType>
where
T: PyTypeInfo,
{
T::type_object_bound(self)
} }
/// Deprecated form of [`Python::import_bound`] /// Deprecated form of [`Python::import_bound`]

View File

@ -122,7 +122,7 @@ impl<T: PyTypeInfo> PyObjectInit<T> for PyNativeTypeInitializer<T> {
/// } /// }
/// } /// }
/// Python::with_gil(|py| { /// Python::with_gil(|py| {
/// let typeobj = py.get_type::<SubSubClass>(); /// let typeobj = py.get_type_bound::<SubSubClass>();
/// let sub_sub_class = typeobj.call((), None).unwrap(); /// let sub_sub_class = typeobj.call((), None).unwrap();
/// py_run!( /// py_run!(
/// py, /// py,

View File

@ -42,7 +42,7 @@ mod inner {
($py:expr, *$dict:expr, $code:expr, $err:ident) => {{ ($py:expr, *$dict:expr, $code:expr, $err:ident) => {{
let res = $py.run_bound($code, None, Some(&$dict.as_borrowed())); let res = $py.run_bound($code, None, Some(&$dict.as_borrowed()));
let err = res.expect_err(&format!("Did not raise {}", stringify!($err))); let err = res.expect_err(&format!("Did not raise {}", stringify!($err)));
if !err.matches($py, $py.get_type::<pyo3::exceptions::$err>()) { if !err.matches($py, $py.get_type_bound::<pyo3::exceptions::$err>()) {
panic!("Expected {} but got {:?}", stringify!($err), err) panic!("Expected {} but got {:?}", stringify!($err), err)
} }
err err

View File

@ -217,22 +217,26 @@ impl<'a> Borrowed<'a, '_, PyType> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::types::typeobject::PyTypeMethods;
use crate::types::{PyBool, PyLong}; use crate::types::{PyBool, PyLong};
use crate::Python; use crate::Python;
#[test] #[test]
fn test_type_is_subclass() { fn test_type_is_subclass() {
Python::with_gil(|py| { Python::with_gil(|py| {
let bool_type = py.get_type::<PyBool>(); let bool_type = py.get_type_bound::<PyBool>();
let long_type = py.get_type::<PyLong>(); let long_type = py.get_type_bound::<PyLong>();
assert!(bool_type.is_subclass(long_type).unwrap()); assert!(bool_type.is_subclass(&long_type).unwrap());
}); });
} }
#[test] #[test]
fn test_type_is_subclass_of() { fn test_type_is_subclass_of() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert!(py.get_type::<PyBool>().is_subclass_of::<PyLong>().unwrap()); assert!(py
.get_type_bound::<PyBool>()
.is_subclass_of::<PyLong>()
.unwrap());
}); });
} }
} }

View File

@ -56,7 +56,7 @@ impl Foo {
#[test] #[test]
fn class_attributes() { fn class_attributes() {
Python::with_gil(|py| { Python::with_gil(|py| {
let foo_obj = py.get_type::<Foo>(); let foo_obj = py.get_type_bound::<Foo>();
py_assert!(py, foo_obj, "foo_obj.MY_CONST == 'foobar'"); py_assert!(py, foo_obj, "foo_obj.MY_CONST == 'foobar'");
py_assert!(py, foo_obj, "foo_obj.RENAMED_CONST == 'foobar_2'"); py_assert!(py, foo_obj, "foo_obj.RENAMED_CONST == 'foobar_2'");
py_assert!(py, foo_obj, "foo_obj.a == 5"); py_assert!(py, foo_obj, "foo_obj.a == 5");
@ -72,7 +72,7 @@ fn class_attributes() {
#[ignore] #[ignore]
fn class_attributes_are_immutable() { fn class_attributes_are_immutable() {
Python::with_gil(|py| { Python::with_gil(|py| {
let foo_obj = py.get_type::<Foo>(); let foo_obj = py.get_type_bound::<Foo>();
py_expect_exception!(py, foo_obj, "foo_obj.a = 6", PyTypeError); py_expect_exception!(py, foo_obj, "foo_obj.a = 6", PyTypeError);
}); });
} }
@ -88,8 +88,8 @@ impl Bar {
#[test] #[test]
fn recursive_class_attributes() { fn recursive_class_attributes() {
Python::with_gil(|py| { Python::with_gil(|py| {
let foo_obj = py.get_type::<Foo>(); let foo_obj = py.get_type_bound::<Foo>();
let bar_obj = py.get_type::<Bar>(); let bar_obj = py.get_type_bound::<Bar>();
py_assert!(py, foo_obj, "foo_obj.a_foo.x == 1"); py_assert!(py, foo_obj, "foo_obj.a_foo.x == 1");
py_assert!(py, foo_obj, "foo_obj.bar.x == 2"); py_assert!(py, foo_obj, "foo_obj.bar.x == 2");
py_assert!(py, bar_obj, "bar_obj.a_foo.x == 3"); py_assert!(py, bar_obj, "bar_obj.a_foo.x == 3");
@ -145,7 +145,7 @@ fn test_fallible_class_attribute() {
Python::with_gil(|py| { Python::with_gil(|py| {
let stderr = CaptureStdErr::new(py).unwrap(); let stderr = CaptureStdErr::new(py).unwrap();
assert!(std::panic::catch_unwind(|| py.get_type::<BrokenClass>()).is_err()); assert!(std::panic::catch_unwind(|| py.get_type_bound::<BrokenClass>()).is_err());
assert_eq!( assert_eq!(
stderr.reset().unwrap().trim(), stderr.reset().unwrap().trim(),
"\ "\
@ -187,7 +187,7 @@ fn test_renaming_all_struct_fields() {
use pyo3::types::PyBool; use pyo3::types::PyBool;
Python::with_gil(|py| { Python::with_gil(|py| {
let struct_class = py.get_type::<StructWithRenamedFields>(); let struct_class = py.get_type_bound::<StructWithRenamedFields>();
let struct_obj = struct_class.call0().unwrap(); let struct_obj = struct_class.call0().unwrap();
assert!(struct_obj assert!(struct_obj
.setattr("firstField", PyBool::new_bound(py, false)) .setattr("firstField", PyBool::new_bound(py, false))
@ -220,11 +220,11 @@ macro_rules! test_case {
//use pyo3::types::PyInt; //use pyo3::types::PyInt;
Python::with_gil(|py| { Python::with_gil(|py| {
let struct_class = py.get_type::<$struct_name>(); let struct_class = py.get_type_bound::<$struct_name>();
let struct_obj = struct_class.call0().unwrap(); let struct_obj = struct_class.call0().unwrap();
assert!(struct_obj.setattr($renamed_field_name, 2).is_ok()); assert!(struct_obj.setattr($renamed_field_name, 2).is_ok());
let attr = struct_obj.getattr($renamed_field_name).unwrap(); let attr = struct_obj.getattr($renamed_field_name).unwrap();
assert_eq!(2, PyAny::extract::<u8>(attr).unwrap()); assert_eq!(2, attr.extract().unwrap());
}); });
} }
}; };

View File

@ -13,7 +13,7 @@ struct EmptyClass {}
#[test] #[test]
fn empty_class() { fn empty_class() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<EmptyClass>(); let typeobj = py.get_type_bound::<EmptyClass>();
// By default, don't allow creating instances from python. // By default, don't allow creating instances from python.
assert!(typeobj.call((), None).is_err()); assert!(typeobj.call((), None).is_err());
@ -27,7 +27,7 @@ struct UnitClass;
#[test] #[test]
fn unit_class() { fn unit_class() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<UnitClass>(); let typeobj = py.get_type_bound::<UnitClass>();
// By default, don't allow creating instances from python. // By default, don't allow creating instances from python.
assert!(typeobj.call((), None).is_err()); assert!(typeobj.call((), None).is_err());
@ -58,7 +58,7 @@ struct ClassWithDocs {
#[test] #[test]
fn class_with_docstr() { fn class_with_docstr() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<ClassWithDocs>(); let typeobj = py.get_type_bound::<ClassWithDocs>();
py_run!( py_run!(
py, py,
typeobj, typeobj,
@ -104,7 +104,7 @@ impl EmptyClass2 {
#[test] #[test]
fn custom_names() { fn custom_names() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<EmptyClass2>(); let typeobj = py.get_type_bound::<EmptyClass2>();
py_assert!(py, typeobj, "typeobj.__name__ == 'CustomName'"); py_assert!(py, typeobj, "typeobj.__name__ == 'CustomName'");
py_assert!(py, typeobj, "typeobj.custom_fn.__name__ == 'custom_fn'"); py_assert!(py, typeobj, "typeobj.custom_fn.__name__ == 'custom_fn'");
py_assert!( py_assert!(
@ -137,7 +137,7 @@ impl RawIdents {
#[test] #[test]
fn test_raw_idents() { fn test_raw_idents() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<RawIdents>(); let typeobj = py.get_type_bound::<RawIdents>();
py_assert!(py, typeobj, "not hasattr(typeobj, 'r#fn')"); py_assert!(py, typeobj, "not hasattr(typeobj, 'r#fn')");
py_assert!(py, typeobj, "hasattr(typeobj, 'fn')"); py_assert!(py, typeobj, "hasattr(typeobj, 'fn')");
py_assert!(py, typeobj, "hasattr(typeobj, 'type')"); py_assert!(py, typeobj, "hasattr(typeobj, 'type')");
@ -191,7 +191,7 @@ impl ClassWithObjectField {
#[test] #[test]
fn class_with_object_field() { fn class_with_object_field() {
Python::with_gil(|py| { Python::with_gil(|py| {
let ty = py.get_type::<ClassWithObjectField>(); let ty = py.get_type_bound::<ClassWithObjectField>();
py_assert!(py, ty, "ty(5).value == 5"); py_assert!(py, ty, "ty(5).value == 5");
py_assert!(py, ty, "ty(None).value == None"); py_assert!(py, ty, "ty(None).value == None");
}); });
@ -346,7 +346,7 @@ struct TupleClass(#[pyo3(get, set, name = "value")] i32);
#[test] #[test]
fn test_tuple_struct_class() { fn test_tuple_struct_class() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<TupleClass>(); let typeobj = py.get_type_bound::<TupleClass>();
assert!(typeobj.call((), None).is_err()); assert!(typeobj.call((), None).is_err());
py_assert!(py, typeobj, "typeobj.__name__ == 'TupleClass'"); py_assert!(py, typeobj, "typeobj.__name__ == 'TupleClass'");

View File

@ -19,7 +19,7 @@ impl EmptyClassWithNew {
#[test] #[test]
fn empty_class_with_new() { fn empty_class_with_new() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<EmptyClassWithNew>(); let typeobj = py.get_type_bound::<EmptyClassWithNew>();
assert!(typeobj assert!(typeobj
.call((), None) .call((), None)
.unwrap() .unwrap()
@ -29,10 +29,7 @@ fn empty_class_with_new() {
// Calling with arbitrary args or kwargs is not ok // Calling with arbitrary args or kwargs is not ok
assert!(typeobj.call(("some", "args"), None).is_err()); assert!(typeobj.call(("some", "args"), None).is_err());
assert!(typeobj assert!(typeobj
.call( .call((), Some(&[("some", "kwarg")].into_py_dict_bound(py)))
(),
Some([("some", "kwarg")].into_py_dict_bound(py).as_gil_ref())
)
.is_err()); .is_err());
}); });
} }
@ -51,7 +48,7 @@ impl UnitClassWithNew {
#[test] #[test]
fn unit_class_with_new() { fn unit_class_with_new() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<UnitClassWithNew>(); let typeobj = py.get_type_bound::<UnitClassWithNew>();
assert!(typeobj assert!(typeobj
.call((), None) .call((), None)
.unwrap() .unwrap()
@ -74,9 +71,9 @@ impl TupleClassWithNew {
#[test] #[test]
fn tuple_class_with_new() { fn tuple_class_with_new() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<TupleClassWithNew>(); let typeobj = py.get_type_bound::<TupleClassWithNew>();
let wrp = typeobj.call((42,), None).unwrap(); let wrp = typeobj.call((42,), None).unwrap();
let obj = wrp.downcast::<PyCell<TupleClassWithNew>>().unwrap(); let obj = wrp.downcast::<TupleClassWithNew>().unwrap();
let obj_ref = obj.borrow(); let obj_ref = obj.borrow();
assert_eq!(obj_ref.0, 42); assert_eq!(obj_ref.0, 42);
}); });
@ -99,9 +96,9 @@ impl NewWithOneArg {
#[test] #[test]
fn new_with_one_arg() { fn new_with_one_arg() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<NewWithOneArg>(); let typeobj = py.get_type_bound::<NewWithOneArg>();
let wrp = typeobj.call((42,), None).unwrap(); let wrp = typeobj.call((42,), None).unwrap();
let obj = wrp.downcast::<PyCell<NewWithOneArg>>().unwrap(); let obj = wrp.downcast::<NewWithOneArg>().unwrap();
let obj_ref = obj.borrow(); let obj_ref = obj.borrow();
assert_eq!(obj_ref.data, 42); assert_eq!(obj_ref.data, 42);
}); });
@ -127,12 +124,12 @@ impl NewWithTwoArgs {
#[test] #[test]
fn new_with_two_args() { fn new_with_two_args() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<NewWithTwoArgs>(); let typeobj = py.get_type_bound::<NewWithTwoArgs>();
let wrp = typeobj let wrp = typeobj
.call((10, 20), None) .call((10, 20), None)
.map_err(|e| e.display(py)) .map_err(|e| e.display(py))
.unwrap(); .unwrap();
let obj = wrp.downcast::<PyCell<NewWithTwoArgs>>().unwrap(); let obj = wrp.downcast::<NewWithTwoArgs>().unwrap();
let obj_ref = obj.borrow(); let obj_ref = obj.borrow();
assert_eq!(obj_ref.data1, 10); assert_eq!(obj_ref.data1, 10);
assert_eq!(obj_ref.data2, 20); assert_eq!(obj_ref.data2, 20);
@ -158,7 +155,7 @@ impl SuperClass {
#[test] #[test]
fn subclass_new() { fn subclass_new() {
Python::with_gil(|py| { Python::with_gil(|py| {
let super_cls = py.get_type::<SuperClass>(); let super_cls = py.get_type_bound::<SuperClass>();
let source = pyo3::indoc::indoc!( let source = pyo3::indoc::indoc!(
r#" r#"
class Class(SuperClass): class Class(SuperClass):
@ -206,7 +203,7 @@ impl NewWithCustomError {
#[test] #[test]
fn new_with_custom_error() { fn new_with_custom_error() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<NewWithCustomError>(); let typeobj = py.get_type_bound::<NewWithCustomError>();
let err = typeobj.call0().unwrap_err(); let err = typeobj.call0().unwrap_err();
assert_eq!(err.to_string(), "ValueError: custom error"); assert_eq!(err.to_string(), "ValueError: custom error");
}); });
@ -247,7 +244,7 @@ impl NewExisting {
#[test] #[test]
fn test_new_existing() { fn test_new_existing() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<NewExisting>(); let typeobj = py.get_type_bound::<NewExisting>();
let obj1 = typeobj.call1((0,)).unwrap(); let obj1 = typeobj.call1((0,)).unwrap();
let obj2 = typeobj.call1((0,)).unwrap(); let obj2 = typeobj.call1((0,)).unwrap();
@ -263,10 +260,10 @@ fn test_new_existing() {
assert!(obj5.getattr("num").unwrap().extract::<u32>().unwrap() == 2); assert!(obj5.getattr("num").unwrap().extract::<u32>().unwrap() == 2);
assert!(obj6.getattr("num").unwrap().extract::<u32>().unwrap() == 2); assert!(obj6.getattr("num").unwrap().extract::<u32>().unwrap() == 2);
assert!(obj1.is(obj2)); assert!(obj1.is(&obj2));
assert!(obj3.is(obj4)); assert!(obj3.is(&obj4));
assert!(!obj1.is(obj3)); assert!(!obj1.is(&obj3));
assert!(!obj1.is(obj5)); assert!(!obj1.is(&obj5));
assert!(!obj5.is(obj6)); assert!(!obj5.is(&obj6));
}); });
} }

View File

@ -1,6 +1,6 @@
#![cfg(feature = "macros")] #![cfg(feature = "macros")]
#![cfg(not(target_arch = "wasm32"))] #![cfg(not(target_arch = "wasm32"))]
use std::{ops::Deref, task::Poll, thread, time::Duration}; use std::{task::Poll, thread, time::Duration};
use futures::{channel::oneshot, future::poll_fn, FutureExt}; use futures::{channel::oneshot, future::poll_fn, FutureExt};
use pyo3::{ use pyo3::{
@ -65,8 +65,11 @@ fn test_coroutine_qualname() {
assert coro.__name__ == name and coro.__qualname__ == qualname assert coro.__name__ == name and coro.__qualname__ == qualname
"#; "#;
let locals = [ let locals = [
("my_fn", wrap_pyfunction!(my_fn, gil).unwrap().deref()), (
("MyClass", gil.get_type::<MyClass>()), "my_fn",
wrap_pyfunction!(my_fn, gil).unwrap().as_borrowed().as_any(),
),
("MyClass", gil.get_type_bound::<MyClass>().as_any()),
] ]
.into_py_dict_bound(gil); .into_py_dict_bound(gil);
py_run!(gil, *locals, &handle_windows(test)); py_run!(gil, *locals, &handle_windows(test));
@ -286,7 +289,7 @@ fn test_async_method_receiver() {
assert False assert False
assert asyncio.run(coro3) == 1 assert asyncio.run(coro3) == 1
"#; "#;
let locals = [("Counter", gil.get_type::<Counter>())].into_py_dict_bound(gil); let locals = [("Counter", gil.get_type_bound::<Counter>())].into_py_dict_bound(gil);
py_run!(gil, *locals, test); py_run!(gil, *locals, test);
}) })
} }

View File

@ -16,7 +16,7 @@ pub enum MyEnum {
#[test] #[test]
fn test_enum_class_attr() { fn test_enum_class_attr() {
Python::with_gil(|py| { Python::with_gil(|py| {
let my_enum = py.get_type::<MyEnum>(); let my_enum = py.get_type_bound::<MyEnum>();
let var = Py::new(py, MyEnum::Variant).unwrap(); let var = Py::new(py, MyEnum::Variant).unwrap();
py_assert!(py, my_enum var, "my_enum.Variant == var"); py_assert!(py, my_enum var, "my_enum.Variant == var");
}) })
@ -31,7 +31,7 @@ fn return_enum() -> MyEnum {
fn test_return_enum() { fn test_return_enum() {
Python::with_gil(|py| { Python::with_gil(|py| {
let f = wrap_pyfunction!(return_enum)(py).unwrap(); let f = wrap_pyfunction!(return_enum)(py).unwrap();
let mynum = py.get_type::<MyEnum>(); let mynum = py.get_type_bound::<MyEnum>();
py_run!(py, f mynum, "assert f() == mynum.Variant") py_run!(py, f mynum, "assert f() == mynum.Variant")
}); });
@ -46,7 +46,7 @@ fn enum_arg(e: MyEnum) {
fn test_enum_arg() { fn test_enum_arg() {
Python::with_gil(|py| { Python::with_gil(|py| {
let f = wrap_pyfunction!(enum_arg)(py).unwrap(); let f = wrap_pyfunction!(enum_arg)(py).unwrap();
let mynum = py.get_type::<MyEnum>(); let mynum = py.get_type_bound::<MyEnum>();
py_run!(py, f mynum, "f(mynum.OtherVariant)") py_run!(py, f mynum, "f(mynum.OtherVariant)")
}) })
@ -83,7 +83,7 @@ enum CustomDiscriminant {
fn test_custom_discriminant() { fn test_custom_discriminant() {
Python::with_gil(|py| { Python::with_gil(|py| {
#[allow(non_snake_case)] #[allow(non_snake_case)]
let CustomDiscriminant = py.get_type::<CustomDiscriminant>(); let CustomDiscriminant = py.get_type_bound::<CustomDiscriminant>();
let one = Py::new(py, CustomDiscriminant::One).unwrap(); let one = Py::new(py, CustomDiscriminant::One).unwrap();
let two = Py::new(py, CustomDiscriminant::Two).unwrap(); let two = Py::new(py, CustomDiscriminant::Two).unwrap();
py_run!(py, CustomDiscriminant one two, r#" py_run!(py, CustomDiscriminant one two, r#"
@ -204,7 +204,7 @@ enum RenameAllVariantsEnum {
#[test] #[test]
fn test_renaming_all_enum_variants() { fn test_renaming_all_enum_variants() {
Python::with_gil(|py| { Python::with_gil(|py| {
let enum_obj = py.get_type::<RenameAllVariantsEnum>(); let enum_obj = py.get_type_bound::<RenameAllVariantsEnum>();
py_assert!(py, enum_obj, "enum_obj.VARIANT_ONE == enum_obj.VARIANT_ONE"); py_assert!(py, enum_obj, "enum_obj.VARIANT_ONE == enum_obj.VARIANT_ONE");
py_assert!(py, enum_obj, "enum_obj.VARIANT_TWO == enum_obj.VARIANT_TWO"); py_assert!(py, enum_obj, "enum_obj.VARIANT_TWO == enum_obj.VARIANT_TWO");
py_assert!( py_assert!(

View File

@ -211,11 +211,11 @@ fn inheritance_with_new_methods_with_drop() {
let drop_called2 = Arc::new(AtomicBool::new(false)); let drop_called2 = Arc::new(AtomicBool::new(false));
Python::with_gil(|py| { Python::with_gil(|py| {
let _typebase = py.get_type::<BaseClassWithDrop>(); let _typebase = py.get_type_bound::<BaseClassWithDrop>();
let typeobj = py.get_type::<SubClassWithDrop>(); let typeobj = py.get_type_bound::<SubClassWithDrop>();
let inst = typeobj.call((), None).unwrap(); let inst = typeobj.call((), None).unwrap();
let obj: &PyCell<SubClassWithDrop> = inst.downcast().unwrap(); let obj = inst.downcast::<SubClassWithDrop>().unwrap();
let mut obj_ref_mut = obj.borrow_mut(); let mut obj_ref_mut = obj.borrow_mut();
obj_ref_mut.data = Some(Arc::clone(&drop_called1)); obj_ref_mut.data = Some(Arc::clone(&drop_called1));
let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut(); let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut();
@ -255,8 +255,8 @@ fn gc_during_borrow() {
Python::with_gil(|py| { Python::with_gil(|py| {
unsafe { unsafe {
// get the traverse function // get the traverse function
let ty = py.get_type::<TraversableClass>().as_type_ptr(); let ty = py.get_type_bound::<TraversableClass>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
// create an object and check that traversing it works normally // create an object and check that traversing it works normally
// when it's not borrowed // when it's not borrowed
@ -303,8 +303,8 @@ impl PartialTraverse {
fn traverse_partial() { fn traverse_partial() {
Python::with_gil(|py| unsafe { Python::with_gil(|py| unsafe {
// get the traverse function // get the traverse function
let ty = py.get_type::<PartialTraverse>().as_type_ptr(); let ty = py.get_type_bound::<PartialTraverse>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
// confirm that traversing errors // confirm that traversing errors
let obj = Py::new(py, PartialTraverse::new(py)).unwrap(); let obj = Py::new(py, PartialTraverse::new(py)).unwrap();
@ -338,8 +338,8 @@ impl PanickyTraverse {
fn traverse_panic() { fn traverse_panic() {
Python::with_gil(|py| unsafe { Python::with_gil(|py| unsafe {
// get the traverse function // get the traverse function
let ty = py.get_type::<PanickyTraverse>().as_type_ptr(); let ty = py.get_type_bound::<PanickyTraverse>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
// confirm that traversing errors // confirm that traversing errors
let obj = Py::new(py, PanickyTraverse::new(py)).unwrap(); let obj = Py::new(py, PanickyTraverse::new(py)).unwrap();
@ -361,8 +361,8 @@ impl TriesGILInTraverse {
fn tries_gil_in_traverse() { fn tries_gil_in_traverse() {
Python::with_gil(|py| unsafe { Python::with_gil(|py| unsafe {
// get the traverse function // get the traverse function
let ty = py.get_type::<TriesGILInTraverse>().as_type_ptr(); let ty = py.get_type_bound::<TriesGILInTraverse>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
// confirm that traversing panicks // confirm that traversing panicks
let obj = Py::new(py, TriesGILInTraverse {}).unwrap(); let obj = Py::new(py, TriesGILInTraverse {}).unwrap();
@ -413,8 +413,8 @@ impl<'a> Traversable for PyRef<'a, HijackedTraverse> {
fn traverse_cannot_be_hijacked() { fn traverse_cannot_be_hijacked() {
Python::with_gil(|py| unsafe { Python::with_gil(|py| unsafe {
// get the traverse function // get the traverse function
let ty = py.get_type::<HijackedTraverse>().as_type_ptr(); let ty = py.get_type_bound::<HijackedTraverse>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
let cell = PyCell::new(py, HijackedTraverse::new()).unwrap(); let cell = PyCell::new(py, HijackedTraverse::new()).unwrap();
let obj = cell.to_object(py); let obj = cell.to_object(py);
@ -528,8 +528,8 @@ impl UnsendableTraversal {
#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
fn unsendable_are_not_traversed_on_foreign_thread() { fn unsendable_are_not_traversed_on_foreign_thread() {
Python::with_gil(|py| unsafe { Python::with_gil(|py| unsafe {
let ty = py.get_type::<UnsendableTraversal>().as_type_ptr(); let ty = py.get_type_bound::<UnsendableTraversal>();
let traverse = get_type_traverse(ty).unwrap(); let traverse = get_type_traverse(ty.as_type_ptr()).unwrap();
let obj = Py::new( let obj = Py::new(
py, py,

View File

@ -64,7 +64,7 @@ fn class_with_properties() {
py_run!(py, inst, "assert inst.get_num() == inst.unwrapped == 42"); py_run!(py, inst, "assert inst.get_num() == inst.unwrapped == 42");
py_run!(py, inst, "assert inst.data_list == [42]"); py_run!(py, inst, "assert inst.data_list == [42]");
let d = [("C", py.get_type::<ClassWithProperties>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<ClassWithProperties>())].into_py_dict_bound(py);
py_assert!(py, *d, "C.DATA.__doc__ == 'a getter for data'"); py_assert!(py, *d, "C.DATA.__doc__ == 'a getter for data'");
}); });
} }

View File

@ -20,7 +20,7 @@ struct SubclassAble {}
#[test] #[test]
fn subclass() { fn subclass() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("SubclassAble", py.get_type::<SubclassAble>())].into_py_dict_bound(py); let d = [("SubclassAble", py.get_type_bound::<SubclassAble>())].into_py_dict_bound(py);
py.run_bound( py.run_bound(
"class A(SubclassAble): pass\nassert issubclass(A, SubclassAble)", "class A(SubclassAble): pass\nassert issubclass(A, SubclassAble)",
@ -72,7 +72,7 @@ impl SubClass {
#[test] #[test]
fn inheritance_with_new_methods() { fn inheritance_with_new_methods() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<SubClass>(); let typeobj = py.get_type_bound::<SubClass>();
let inst = typeobj.call((), None).unwrap(); let inst = typeobj.call((), None).unwrap();
py_run!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5"); py_run!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5");
}); });
@ -112,16 +112,16 @@ fn mutation_fails() {
#[test] #[test]
fn is_subclass_and_is_instance() { fn is_subclass_and_is_instance() {
Python::with_gil(|py| { Python::with_gil(|py| {
let sub_ty = py.get_type::<SubClass>(); let sub_ty = py.get_type_bound::<SubClass>();
let base_ty = py.get_type::<BaseClass>(); let base_ty = py.get_type_bound::<BaseClass>();
assert!(sub_ty.is_subclass_of::<BaseClass>().unwrap()); assert!(sub_ty.is_subclass_of::<BaseClass>().unwrap());
assert!(sub_ty.is_subclass(base_ty).unwrap()); assert!(sub_ty.is_subclass(&base_ty).unwrap());
let obj = PyCell::new(py, SubClass::new()).unwrap(); let obj = Bound::new(py, SubClass::new()).unwrap().into_any();
assert!(obj.is_instance_of::<SubClass>()); assert!(obj.is_instance_of::<SubClass>());
assert!(obj.is_instance_of::<BaseClass>()); assert!(obj.is_instance_of::<BaseClass>());
assert!(obj.is_instance(sub_ty).unwrap()); assert!(obj.is_instance(&sub_ty).unwrap());
assert!(obj.is_instance(base_ty).unwrap()); assert!(obj.is_instance(&base_ty).unwrap());
}); });
} }
@ -155,7 +155,7 @@ impl SubClass2 {
#[test] #[test]
fn handle_result_in_new() { fn handle_result_in_new() {
Python::with_gil(|py| { Python::with_gil(|py| {
let subclass = py.get_type::<SubClass2>(); let subclass = py.get_type_bound::<SubClass2>();
py_run!( py_run!(
py, py,
subclass, subclass,
@ -274,15 +274,15 @@ mod inheriting_native_type {
#[test] #[test]
fn custom_exception() { fn custom_exception() {
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<CustomException>(); let cls = py.get_type_bound::<CustomException>();
let dict = [("cls", cls)].into_py_dict_bound(py); let dict = [("cls", &cls)].into_py_dict_bound(py);
let res = py.run_bound( let res = py.run_bound(
"e = cls('hello'); assert str(e) == 'hello'; assert e.context == 'Hello :)'; raise e", "e = cls('hello'); assert str(e) == 'hello'; assert e.context == 'Hello :)'; raise e",
None, None,
Some(&dict) Some(&dict)
); );
let err = res.unwrap_err(); let err = res.unwrap_err();
assert!(err.matches(py, cls), "{}", err); assert!(err.matches(py, &cls), "{}", err);
// catching the exception in Python also works: // catching the exception in Python also works:
py_run!( py_run!(
@ -315,7 +315,7 @@ fn test_subclass_ref_counts() {
// regression test for issue #1363 // regression test for issue #1363
Python::with_gil(|py| { Python::with_gil(|py| {
#[allow(non_snake_case)] #[allow(non_snake_case)]
let SimpleClass = py.get_type::<SimpleClass>(); let SimpleClass = py.get_type_bound::<SimpleClass>();
py_run!( py_run!(
py, py,
SimpleClass, SimpleClass,

View File

@ -23,7 +23,7 @@ impl MacroDocs {
#[test] #[test]
fn meth_doc() { fn meth_doc() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("C", py.get_type::<MacroDocs>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<MacroDocs>())].into_py_dict_bound(py);
py_assert!( py_assert!(
py, py,
*d, *d,

View File

@ -73,7 +73,7 @@ property_rename_via_macro!(my_new_property_name);
#[test] #[test]
fn test_macro_rules_interactions() { fn test_macro_rules_interactions() {
Python::with_gil(|py| { Python::with_gil(|py| {
let my_base = py.get_type::<MyBaseClass>(); let my_base = py.get_type_bound::<MyBaseClass>();
py_assert!(py, my_base, "my_base.__name__ == 'MyClass'"); py_assert!(py, my_base, "my_base.__name__ == 'MyClass'");
let my_func = wrap_pyfunction!(my_function_in_macro, py).unwrap(); let my_func = wrap_pyfunction!(my_function_in_macro, py).unwrap();
@ -83,7 +83,7 @@ fn test_macro_rules_interactions() {
"my_func.__text_signature__ == '(a, b=None, *, c=42)'" "my_func.__text_signature__ == '(a, b=None, *, c=42)'"
); );
let renamed_prop = py.get_type::<ClassWithProperty>(); let renamed_prop = py.get_type_bound::<ClassWithProperty>();
py_assert!( py_assert!(
py, py,
renamed_prop, renamed_prop,

View File

@ -69,7 +69,7 @@ impl Mapping {
/// Return a dict with `m = Mapping(['1', '2', '3'])`. /// Return a dict with `m = Mapping(['1', '2', '3'])`.
fn map_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { fn map_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> {
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict_bound(py); let d = [("Mapping", py.get_type_bound::<Mapping>())].into_py_dict_bound(py);
py_run!(py, *d, "m = Mapping(['1', '2', '3'])"); py_run!(py, *d, "m = Mapping(['1', '2', '3'])");
d d
} }

View File

@ -95,7 +95,7 @@ impl ClassMethod {
#[test] #[test]
fn class_method() { fn class_method() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("C", py.get_type::<ClassMethod>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<ClassMethod>())].into_py_dict_bound(py);
py_assert!(py, *d, "C.method() == 'ClassMethod.method()!'"); py_assert!(py, *d, "C.method() == 'ClassMethod.method()!'");
py_assert!(py, *d, "C().method() == 'ClassMethod.method()!'"); py_assert!(py, *d, "C().method() == 'ClassMethod.method()!'");
py_assert!( py_assert!(
@ -126,7 +126,7 @@ impl ClassMethodWithArgs {
#[test] #[test]
fn class_method_with_args() { fn class_method_with_args() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("C", py.get_type::<ClassMethodWithArgs>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<ClassMethodWithArgs>())].into_py_dict_bound(py);
py_assert!( py_assert!(
py, py,
*d, *d,
@ -157,7 +157,7 @@ fn static_method() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert_eq!(StaticMethod::method(py), "StaticMethod.method()!"); assert_eq!(StaticMethod::method(py), "StaticMethod.method()!");
let d = [("C", py.get_type::<StaticMethod>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<StaticMethod>())].into_py_dict_bound(py);
py_assert!(py, *d, "C.method() == 'StaticMethod.method()!'"); py_assert!(py, *d, "C.method() == 'StaticMethod.method()!'");
py_assert!(py, *d, "C().method() == 'StaticMethod.method()!'"); py_assert!(py, *d, "C().method() == 'StaticMethod.method()!'");
py_assert!(py, *d, "C.method.__doc__ == 'Test static method.'"); py_assert!(py, *d, "C.method.__doc__ == 'Test static method.'");
@ -181,7 +181,7 @@ fn static_method_with_args() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2"); assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2");
let d = [("C", py.get_type::<StaticMethodWithArgs>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<StaticMethodWithArgs>())].into_py_dict_bound(py);
py_assert!(py, *d, "C.method(1337) == '0x539'"); py_assert!(py, *d, "C.method(1337) == '0x539'");
}); });
} }
@ -679,7 +679,7 @@ impl MethDocs {
#[test] #[test]
fn meth_doc() { fn meth_doc() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("C", py.get_type::<MethDocs>())].into_py_dict_bound(py); let d = [("C", py.get_type_bound::<MethDocs>())].into_py_dict_bound(py);
py_assert!(py, *d, "C.__doc__ == 'A class with \"documentation\".'"); py_assert!(py, *d, "C.__doc__ == 'A class with \"documentation\".'");
py_assert!( py_assert!(
py, py,
@ -866,7 +866,7 @@ impl FromSequence {
#[test] #[test]
fn test_from_sequence() { fn test_from_sequence() {
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<FromSequence>(); let typeobj = py.get_type_bound::<FromSequence>();
py_assert!(py, typeobj, "typeobj(range(0, 4)).numbers == [0, 1, 2, 3]"); py_assert!(py, typeobj, "typeobj(range(0, 4)).numbers == [0, 1, 2, 3]");
}); });
} }
@ -946,7 +946,7 @@ impl r#RawIdents {
#[test] #[test]
fn test_raw_idents() { fn test_raw_idents() {
Python::with_gil(|py| { Python::with_gil(|py| {
let raw_idents_type = py.get_type::<r#RawIdents>(); let raw_idents_type = py.get_type_bound::<r#RawIdents>();
assert_eq!(raw_idents_type.qualname().unwrap(), "RawIdents"); assert_eq!(raw_idents_type.qualname().unwrap(), "RawIdents");
py_run!( py_run!(
py, py,

View File

@ -65,7 +65,7 @@ impl PyClassWithMultiplePyMethods {
#[test] #[test]
fn test_class_with_multiple_pymethods() { fn test_class_with_multiple_pymethods() {
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<PyClassWithMultiplePyMethods>(); let cls = py.get_type_bound::<PyClassWithMultiplePyMethods>();
py_assert!(py, cls, "cls()() == 'call'"); py_assert!(py, cls, "cls()() == 'call'");
py_assert!(py, cls, "cls().method() == 'method'"); py_assert!(py, cls, "cls().method() == 'method'");
py_assert!(py, cls, "cls.classmethod() == 'classmethod'"); py_assert!(py, cls, "cls.classmethod() == 'classmethod'");

View File

@ -2,6 +2,8 @@
#![cfg(feature = "macros")] #![cfg(feature = "macros")]
use pyo3::prelude::PyAnyMethods;
#[pyo3::pyfunction] #[pyo3::pyfunction]
#[pyo3(name = "identity", signature = (x = None))] #[pyo3(name = "identity", signature = (x = None))]
fn basic_function(py: pyo3::Python<'_>, x: Option<pyo3::PyObject>) -> pyo3::PyObject { fn basic_function(py: pyo3::Python<'_>, x: Option<pyo3::PyObject>) -> pyo3::PyObject {
@ -91,13 +93,13 @@ impl BasicClass {
fn test_basic() { fn test_basic() {
pyo3::Python::with_gil(|py| { pyo3::Python::with_gil(|py| {
let module = pyo3::wrap_pymodule!(basic_module)(py); let module = pyo3::wrap_pymodule!(basic_module)(py);
let cls = py.get_type::<BasicClass>(); let cls = py.get_type_bound::<BasicClass>();
let d = pyo3::types::IntoPyDict::into_py_dict_bound( let d = pyo3::types::IntoPyDict::into_py_dict_bound(
[ [
("mod", module.as_ref(py).as_ref()), ("mod", module.bind(py).as_any()),
("cls", cls.as_ref()), ("cls", &cls),
("a", cls.call1((8,)).unwrap()), ("a", &cls.call1((8,)).unwrap()),
("b", cls.call1(("foo",)).unwrap()), ("b", &cls.call1(("foo",)).unwrap()),
], ],
py, py,
); );
@ -144,7 +146,7 @@ impl NewClassMethod {
#[test] #[test]
fn test_new_class_method() { fn test_new_class_method() {
pyo3::Python::with_gil(|py| { pyo3::Python::with_gil(|py| {
let cls = py.get_type::<NewClassMethod>(); let cls = py.get_type_bound::<NewClassMethod>();
pyo3::py_run!(py, cls, "assert cls().cls is cls"); pyo3::py_run!(py, cls, "assert cls().cls is cls");
}); });
} }

View File

@ -672,7 +672,7 @@ impl OnceFuture {
#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop) #[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop)
fn test_await() { fn test_await() {
Python::with_gil(|py| { Python::with_gil(|py| {
let once = py.get_type::<OnceFuture>(); let once = py.get_type_bound::<OnceFuture>();
let source = r#" let source = r#"
import asyncio import asyncio
import sys import sys
@ -725,7 +725,7 @@ impl AsyncIterator {
#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop) #[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop)
fn test_anext_aiter() { fn test_anext_aiter() {
Python::with_gil(|py| { Python::with_gil(|py| {
let once = py.get_type::<OnceFuture>(); let once = py.get_type_bound::<OnceFuture>();
let source = r#" let source = r#"
import asyncio import asyncio
import sys import sys
@ -750,7 +750,7 @@ asyncio.run(main())
.as_borrowed(); .as_borrowed();
globals.set_item("Once", once).unwrap(); globals.set_item("Once", once).unwrap();
globals globals
.set_item("AsyncIterator", py.get_type::<AsyncIterator>()) .set_item("AsyncIterator", py.get_type_bound::<AsyncIterator>())
.unwrap(); .unwrap();
py.run_bound(source, Some(&globals), None) py.run_bound(source, Some(&globals), None)
.map_err(|e| e.display(py)) .map_err(|e| e.display(py))
@ -793,7 +793,7 @@ impl DescrCounter {
#[test] #[test]
fn descr_getset() { fn descr_getset() {
Python::with_gil(|py| { Python::with_gil(|py| {
let counter = py.get_type::<DescrCounter>(); let counter = py.get_type_bound::<DescrCounter>();
let source = pyo3::indoc::indoc!( let source = pyo3::indoc::indoc!(
r#" r#"
class Class: class Class:

View File

@ -106,7 +106,7 @@ impl ByteSequence {
/// Return a dict with `s = ByteSequence([1, 2, 3])`. /// Return a dict with `s = ByteSequence([1, 2, 3])`.
fn seq_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { fn seq_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> {
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict_bound(py); let d = [("ByteSequence", py.get_type_bound::<ByteSequence>())].into_py_dict_bound(py);
// Though we can construct `s` in Rust, let's test `__new__` works. // Though we can construct `s` in Rust, let's test `__new__` works.
py_run!(py, *d, "s = ByteSequence([1, 2, 3])"); py_run!(py, *d, "s = ByteSequence([1, 2, 3])");
d d
@ -138,7 +138,7 @@ fn test_setitem() {
#[test] #[test]
fn test_delitem() { fn test_delitem() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict_bound(py); let d = [("ByteSequence", py.get_type_bound::<ByteSequence>())].into_py_dict_bound(py);
py_run!( py_run!(
py, py,
@ -234,7 +234,7 @@ fn test_repeat() {
#[test] #[test]
fn test_inplace_repeat() { fn test_inplace_repeat() {
Python::with_gil(|py| { Python::with_gil(|py| {
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict_bound(py); let d = [("ByteSequence", py.get_type_bound::<ByteSequence>())].into_py_dict_bound(py);
py_run!( py_run!(
py, py,

View File

@ -38,7 +38,7 @@ impl Count5 {
/// Return a dict with `s = Count5()`. /// Return a dict with `s = Count5()`.
fn test_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { fn test_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> {
let d = [("Count5", py.get_type::<Count5>())].into_py_dict_bound(py); let d = [("Count5", py.get_type_bound::<Count5>())].into_py_dict_bound(py);
// Though we can construct `s` in Rust, let's test `__new__` works. // Though we can construct `s` in Rust, let's test `__new__` works.
py_run!(py, *d, "s = Count5()"); py_run!(py, *d, "s = Count5()");
d d

View File

@ -44,7 +44,7 @@ impl SubClass {
#[test] #[test]
fn test_call_super_method() { fn test_call_super_method() {
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<SubClass>(); let cls = py.get_type_bound::<SubClass>();
pyo3::py_run!( pyo3::py_run!(
py, py,
cls, cls,

View File

@ -13,7 +13,7 @@ fn class_without_docs_or_signature() {
struct MyClass {} struct MyClass {}
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!(py, typeobj, "typeobj.__doc__ is None"); py_assert!(py, typeobj, "typeobj.__doc__ is None");
py_assert!(py, typeobj, "typeobj.__text_signature__ is None"); py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
@ -28,7 +28,7 @@ fn class_with_docs() {
struct MyClass {} struct MyClass {}
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'"); py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'");
py_assert!(py, typeobj, "typeobj.__text_signature__ is None"); py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
@ -52,7 +52,7 @@ fn class_with_signature_no_doc() {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!(py, typeobj, "typeobj.__doc__ == ''"); py_assert!(py, typeobj, "typeobj.__doc__ == ''");
py_assert!( py_assert!(
py, py,
@ -81,7 +81,7 @@ fn class_with_docs_and_signature() {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'"); py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'");
py_assert!( py_assert!(
@ -238,7 +238,7 @@ fn test_auto_test_signature_method() {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let cls = py.get_type::<MyClass>(); let cls = py.get_type_bound::<MyClass>();
#[cfg(any(not(Py_LIMITED_API), Py_3_10))] #[cfg(any(not(Py_LIMITED_API), Py_3_10))]
py_assert!(py, cls, "cls.__text_signature__ == '(a, b, c)'"); py_assert!(py, cls, "cls.__text_signature__ == '(a, b, c)'");
py_assert!( py_assert!(
@ -323,7 +323,7 @@ fn test_auto_test_signature_opt_out() {
let f = wrap_pyfunction!(my_function_2)(py).unwrap(); let f = wrap_pyfunction!(my_function_2)(py).unwrap();
py_assert!(py, f, "f.__text_signature__ == None"); py_assert!(py, f, "f.__text_signature__ == None");
let cls = py.get_type::<MyClass>(); let cls = py.get_type_bound::<MyClass>();
py_assert!(py, cls, "cls.__text_signature__ == None"); py_assert!(py, cls, "cls.__text_signature__ == None");
py_assert!(py, cls, "cls.method.__text_signature__ == None"); py_assert!(py, cls, "cls.method.__text_signature__ == None");
py_assert!(py, cls, "cls.method_2.__text_signature__ == None"); py_assert!(py, cls, "cls.method_2.__text_signature__ == None");
@ -383,7 +383,7 @@ fn test_methods() {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!( py_assert!(
py, py,
@ -424,7 +424,7 @@ fn test_raw_identifiers() {
} }
Python::with_gil(|py| { Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>(); let typeobj = py.get_type_bound::<MyClass>();
py_assert!(py, typeobj, "typeobj.__text_signature__ == '()'"); py_assert!(py, typeobj, "typeobj.__text_signature__ == '()'");

View File

@ -27,7 +27,7 @@ impl MyClass {
#[test] #[test]
fn variable_args() { fn variable_args() {
Python::with_gil(|py| { Python::with_gil(|py| {
let my_obj = py.get_type::<MyClass>(); let my_obj = py.get_type_bound::<MyClass>();
py_assert!(py, my_obj, "my_obj.test_args() == ()"); py_assert!(py, my_obj, "my_obj.test_args() == ()");
py_assert!(py, my_obj, "my_obj.test_args(1) == (1,)"); py_assert!(py, my_obj, "my_obj.test_args(1) == (1,)");
py_assert!(py, my_obj, "my_obj.test_args(1, 2) == (1, 2)"); py_assert!(py, my_obj, "my_obj.test_args(1, 2) == (1, 2)");
@ -37,7 +37,7 @@ fn variable_args() {
#[test] #[test]
fn variable_kwargs() { fn variable_kwargs() {
Python::with_gil(|py| { Python::with_gil(|py| {
let my_obj = py.get_type::<MyClass>(); let my_obj = py.get_type_bound::<MyClass>();
py_assert!(py, my_obj, "my_obj.test_kwargs() == None"); py_assert!(py, my_obj, "my_obj.test_kwargs() == None");
py_assert!(py, my_obj, "my_obj.test_kwargs(test=1) == {'test': 1}"); py_assert!(py, my_obj, "my_obj.test_kwargs(test=1) == {'test': 1}");
py_assert!( py_assert!(