Use the new bound API instead of .as_ref(py) (#3853)
* Use the new bound API instead of .as_ref(py) * Move import into a nested scope * Use to_cow instead of to_str for compatibility `to_str` is not available before Python 3.10 on the limited api. * Relax &self lifetimes * Use Bound<'py, PyAny> in test Mapping signatures * Use .as_bytes(py) * Simplify ThrowCallback::throw signature * Avoid .as_any call with Py api instead of Bound
This commit is contained in:
parent
5f42c02e4f
commit
0dd568d397
|
@ -87,7 +87,8 @@ mod test_ipaddr {
|
|||
};
|
||||
|
||||
let pyobj = ip.into_py(py);
|
||||
let repr = pyobj.as_ref(py).repr().unwrap().to_string_lossy();
|
||||
let repr = pyobj.bind(py).repr().unwrap();
|
||||
let repr = repr.to_string_lossy();
|
||||
assert_eq!(repr, format!("{}('{}')", py_cls, ip));
|
||||
|
||||
let ip2: IpAddr = pyobj.extract(py).unwrap();
|
||||
|
|
|
@ -68,13 +68,11 @@ impl FromPyObject<'_> for OsString {
|
|||
|
||||
// Create an OsStr view into the raw bytes from Python
|
||||
#[cfg(target_os = "wasi")]
|
||||
let os_str: &OsStr = std::os::wasi::ffi::OsStrExt::from_bytes(
|
||||
fs_encoded_bytes.as_ref(ob.py()).as_bytes(),
|
||||
);
|
||||
let os_str: &OsStr =
|
||||
std::os::wasi::ffi::OsStrExt::from_bytes(fs_encoded_bytes.as_bytes(ob.py()));
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
let os_str: &OsStr = std::os::unix::ffi::OsStrExt::from_bytes(
|
||||
fs_encoded_bytes.as_ref(ob.py()).as_bytes(),
|
||||
);
|
||||
let os_str: &OsStr =
|
||||
std::os::unix::ffi::OsStrExt::from_bytes(fs_encoded_bytes.as_bytes(ob.py()));
|
||||
|
||||
Ok(os_str.to_os_string())
|
||||
}
|
||||
|
|
|
@ -94,10 +94,10 @@ mod tests {
|
|||
.unwrap_err();
|
||||
|
||||
let cow = Cow::<[u8]>::Borrowed(b"foobar").to_object(py);
|
||||
assert!(cow.as_ref(py).is_instance_of::<PyBytes>());
|
||||
assert!(cow.bind(py).is_instance_of::<PyBytes>());
|
||||
|
||||
let cow = Cow::<[u8]>::Owned(b"foobar".to_vec()).to_object(py);
|
||||
assert!(cow.as_ref(py).is_instance_of::<PyBytes>());
|
||||
assert!(cow.bind(py).is_instance_of::<PyBytes>());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ impl FromPyObject<'_> for char {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::Python;
|
||||
use crate::{IntoPy, PyObject, ToPyObject};
|
||||
use std::borrow::Cow;
|
||||
|
@ -200,7 +201,7 @@ mod tests {
|
|||
let s = "Hello Python";
|
||||
let py_string = s.to_object(py);
|
||||
|
||||
let s2: &str = py_string.as_ref(py).extract().unwrap();
|
||||
let s2: &str = py_string.bind(py).extract().unwrap();
|
||||
assert_eq!(s, s2);
|
||||
})
|
||||
}
|
||||
|
@ -210,7 +211,7 @@ mod tests {
|
|||
Python::with_gil(|py| {
|
||||
let ch = '😃';
|
||||
let py_string = ch.to_object(py);
|
||||
let ch2: char = py_string.as_ref(py).extract().unwrap();
|
||||
let ch2: char = py_string.bind(py).extract().unwrap();
|
||||
assert_eq!(ch, ch2);
|
||||
})
|
||||
}
|
||||
|
@ -220,7 +221,7 @@ mod tests {
|
|||
Python::with_gil(|py| {
|
||||
let s = "Hello Python";
|
||||
let py_string = s.to_object(py);
|
||||
let err: crate::PyResult<char> = py_string.as_ref(py).extract();
|
||||
let err: crate::PyResult<char> = py_string.bind(py).extract();
|
||||
assert!(err
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
|
|
|
@ -14,8 +14,8 @@ use crate::{
|
|||
coroutine::{cancel::ThrowCallback, waker::AsyncioWaker},
|
||||
exceptions::{PyAttributeError, PyRuntimeError, PyStopIteration},
|
||||
panic::PanicException,
|
||||
types::{PyIterator, PyString},
|
||||
IntoPy, Py, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python,
|
||||
types::{string::PyStringMethods, PyIterator, PyString},
|
||||
IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python,
|
||||
};
|
||||
|
||||
pub(crate) mod cancel;
|
||||
|
@ -75,7 +75,7 @@ impl Coroutine {
|
|||
};
|
||||
// reraise thrown exception it
|
||||
match (throw, &self.throw_callback) {
|
||||
(Some(exc), Some(cb)) => cb.throw(exc.as_ref(py)),
|
||||
(Some(exc), Some(cb)) => cb.throw(exc),
|
||||
(Some(exc), None) => {
|
||||
self.close();
|
||||
return Err(PyErr::from_value_bound(exc.into_bound(py)));
|
||||
|
@ -135,7 +135,7 @@ impl Coroutine {
|
|||
#[getter]
|
||||
fn __qualname__(&self, py: Python<'_>) -> PyResult<Py<PyString>> {
|
||||
match (&self.name, &self.qualname_prefix) {
|
||||
(Some(name), Some(prefix)) => Ok(format!("{}.{}", prefix, name.as_ref(py).to_str()?)
|
||||
(Some(name), Some(prefix)) => Ok(format!("{}.{}", prefix, name.bind(py).to_cow()?)
|
||||
.as_str()
|
||||
.into_py(py)),
|
||||
(Some(name), None) => Ok(name.clone_ref(py)),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{PyAny, PyObject};
|
||||
use crate::{Py, PyAny, PyObject};
|
||||
use parking_lot::Mutex;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
@ -68,9 +68,9 @@ impl Future for Cancelled<'_> {
|
|||
pub struct ThrowCallback(Arc<Mutex<Inner>>);
|
||||
|
||||
impl ThrowCallback {
|
||||
pub(super) fn throw(&self, exc: &PyAny) {
|
||||
pub(super) fn throw(&self, exc: Py<PyAny>) {
|
||||
let mut inner = self.0.lock();
|
||||
inner.exception = Some(exc.into());
|
||||
inner.exception = Some(exc);
|
||||
if let Some(waker) = inner.waker.take() {
|
||||
waker.wake();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::sync::GILOnceCell;
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::PyCFunction;
|
||||
use crate::{intern, wrap_pyfunction, Py, PyAny, PyObject, PyResult, Python};
|
||||
use crate::{intern, wrap_pyfunction, Bound, Py, PyAny, PyObject, PyResult, Python};
|
||||
use pyo3_macros::pyfunction;
|
||||
use std::sync::Arc;
|
||||
use std::task::Wake;
|
||||
|
@ -25,10 +25,13 @@ impl AsyncioWaker {
|
|||
self.0.take();
|
||||
}
|
||||
|
||||
pub(super) fn initialize_future<'a>(&'a self, py: Python<'a>) -> PyResult<Option<&'a PyAny>> {
|
||||
pub(super) fn initialize_future<'py>(
|
||||
&self,
|
||||
py: Python<'py>,
|
||||
) -> PyResult<Option<&Bound<'py, PyAny>>> {
|
||||
let init = || LoopAndFuture::new(py).map(Some);
|
||||
let loop_and_future = self.0.get_or_try_init(py, init)?.as_ref();
|
||||
Ok(loop_and_future.map(|LoopAndFuture { future, .. }| future.as_ref(py)))
|
||||
Ok(loop_and_future.map(|LoopAndFuture { future, .. }| future.bind(py)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +77,7 @@ impl LoopAndFuture {
|
|||
let call_soon_threadsafe = self.event_loop.call_method1(
|
||||
py,
|
||||
intern!(py, "call_soon_threadsafe"),
|
||||
(release_waiter, self.future.as_ref(py)),
|
||||
(release_waiter, self.future.bind(py)),
|
||||
);
|
||||
if let Err(err) = call_soon_threadsafe {
|
||||
// `call_soon_threadsafe` will raise if the event loop is closed;
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::instance::Bound;
|
|||
use crate::panic::PanicException;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::string::PyStringMethods;
|
||||
use crate::types::{PyTraceback, PyType};
|
||||
use crate::{
|
||||
exceptions::{self, PyBaseException},
|
||||
|
@ -403,7 +404,7 @@ impl PyErr {
|
|||
if ptype.as_ptr() == PanicException::type_object_raw(py).cast() {
|
||||
let msg = pvalue
|
||||
.as_ref()
|
||||
.and_then(|obj| obj.as_ref(py).str().ok())
|
||||
.and_then(|obj| obj.bind(py).str().ok())
|
||||
.map(|py_str| py_str.to_string_lossy().into())
|
||||
.unwrap_or_else(|| String::from("Unwrapped panic from Python code"));
|
||||
|
||||
|
@ -425,7 +426,7 @@ impl PyErr {
|
|||
#[cfg(Py_3_12)]
|
||||
fn _take(py: Python<'_>) -> Option<PyErr> {
|
||||
let state = PyErrStateNormalized::take(py)?;
|
||||
let pvalue = state.pvalue.as_ref(py);
|
||||
let pvalue = state.pvalue.bind(py);
|
||||
if pvalue.get_type().as_ptr() == PanicException::type_object_raw(py).cast() {
|
||||
let msg: String = pvalue
|
||||
.str()
|
||||
|
@ -905,7 +906,6 @@ impl std::fmt::Debug for PyErr {
|
|||
|
||||
impl std::fmt::Display for PyErr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use crate::types::string::PyStringMethods;
|
||||
Python::with_gil(|py| {
|
||||
let value = self.value_bound(py);
|
||||
let type_name = value.get_type().qualname().map_err(|_| std::fmt::Error)?;
|
||||
|
|
|
@ -989,7 +989,7 @@ where
|
|||
/// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
|
||||
/// [`try_borrow`](#method.try_borrow).
|
||||
pub fn borrow<'py>(&'py self, py: Python<'py>) -> PyRef<'py, T> {
|
||||
self.as_ref(py).borrow()
|
||||
self.bind(py).borrow()
|
||||
}
|
||||
|
||||
/// Mutably borrows the value `T`.
|
||||
|
@ -1028,7 +1028,7 @@ where
|
|||
where
|
||||
T: PyClass<Frozen = False>,
|
||||
{
|
||||
self.as_ref(py).borrow_mut()
|
||||
self.bind(py).borrow_mut()
|
||||
}
|
||||
|
||||
/// Attempts to immutably borrow the value `T`, returning an error if the value is currently mutably borrowed.
|
||||
|
@ -1042,7 +1042,7 @@ where
|
|||
/// Equivalent to `self.as_ref(py).borrow_mut()` -
|
||||
/// see [`PyCell::try_borrow`](crate::pycell::PyCell::try_borrow).
|
||||
pub fn try_borrow<'py>(&'py self, py: Python<'py>) -> Result<PyRef<'py, T>, PyBorrowError> {
|
||||
self.as_ref(py).try_borrow()
|
||||
self.bind(py).try_borrow()
|
||||
}
|
||||
|
||||
/// Attempts to mutably borrow the value `T`, returning an error if the value is currently borrowed.
|
||||
|
@ -1060,7 +1060,7 @@ where
|
|||
where
|
||||
T: PyClass<Frozen = False>,
|
||||
{
|
||||
self.as_ref(py).try_borrow_mut()
|
||||
self.bind(py).try_borrow_mut()
|
||||
}
|
||||
|
||||
/// Provide an immutable borrow of the value `T` without acquiring the GIL.
|
||||
|
@ -1667,7 +1667,7 @@ where
|
|||
T::AsRefTarget: std::fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Python::with_gil(|py| std::fmt::Display::fmt(self.as_ref(py), f))
|
||||
Python::with_gil(|py| std::fmt::Display::fmt(self.bind(py), f))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
//!
|
||||
//! // We borrow the guard and then dereference
|
||||
//! // it to get a mutable reference to Number
|
||||
//! let mut guard: PyRefMut<'_, Number> = n.as_ref(py).borrow_mut();
|
||||
//! let mut guard: PyRefMut<'_, Number> = n.bind(py).borrow_mut();
|
||||
//! let n_mutable: &mut Number = &mut *guard;
|
||||
//!
|
||||
//! n_mutable.increment();
|
||||
|
@ -105,7 +105,7 @@
|
|||
//! // `PyRefMut` before borrowing again.
|
||||
//! drop(guard);
|
||||
//!
|
||||
//! let n_immutable: &Number = &n.as_ref(py).borrow();
|
||||
//! let n_immutable: &Number = &n.bind(py).borrow();
|
||||
//! assert_eq!(n_immutable.inner, 1);
|
||||
//!
|
||||
//! Ok(())
|
||||
|
|
|
@ -491,7 +491,7 @@ mod tests {
|
|||
});
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let f = unsafe { cap.as_ref(py).reference::<fn(u32) -> u32>() };
|
||||
let f = unsafe { cap.bind(py).reference::<fn(u32) -> u32>() };
|
||||
assert_eq!(f(123), 123);
|
||||
});
|
||||
}
|
||||
|
@ -555,7 +555,7 @@ mod tests {
|
|||
});
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let ctx: &Vec<u8> = unsafe { cap.as_ref(py).reference() };
|
||||
let ctx: &Vec<u8> = unsafe { cap.bind(py).reference() };
|
||||
assert_eq!(ctx, &[1, 2, 3, 4]);
|
||||
})
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ mod tests {
|
|||
});
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let ctx_ptr: *mut c_void = cap.as_ref(py).context().unwrap();
|
||||
let ctx_ptr: *mut c_void = cap.bind(py).context().unwrap();
|
||||
let ctx = unsafe { *Box::from_raw(ctx_ptr.cast::<&Vec<u8>>()) };
|
||||
assert_eq!(ctx, &vec![1_u8, 2, 3, 4]);
|
||||
})
|
||||
|
|
|
@ -235,7 +235,7 @@ fn test_unsendable<T: PyClass + 'static>() -> PyResult<()> {
|
|||
// Accessing the value inside this thread should not panic
|
||||
let caught_panic =
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| -> PyResult<_> {
|
||||
assert_eq!(obj.as_ref(py).getattr("value")?.extract::<usize>()?, 5);
|
||||
assert_eq!(obj.getattr(py, "value")?.extract::<usize>(py)?, 5);
|
||||
Ok(())
|
||||
}))
|
||||
.is_err();
|
||||
|
|
|
@ -89,7 +89,7 @@ fn test_polymorphic_container_stores_sub_class() {
|
|||
.unwrap()
|
||||
.to_object(py);
|
||||
|
||||
p.as_ref(py)
|
||||
p.bind(py)
|
||||
.setattr(
|
||||
"inner",
|
||||
PyCell::new(
|
||||
|
@ -116,7 +116,7 @@ fn test_polymorphic_container_does_not_accept_other_types() {
|
|||
.unwrap()
|
||||
.to_object(py);
|
||||
|
||||
let setattr = |value: PyObject| p.as_ref(py).setattr("inner", value);
|
||||
let setattr = |value: PyObject| p.bind(py).setattr("inner", value);
|
||||
|
||||
assert!(setattr(1i32.into_py(py)).is_err());
|
||||
assert!(setattr(py.None()).is_err());
|
||||
|
|
|
@ -22,8 +22,14 @@ fn test_cfg() {
|
|||
Python::with_gil(|py| {
|
||||
let cfg = CfgClass { b: 3 };
|
||||
let py_cfg = Py::new(py, cfg).unwrap();
|
||||
assert!(py_cfg.as_ref(py).getattr("a").is_err());
|
||||
let b: u32 = py_cfg.as_ref(py).getattr("b").unwrap().extract().unwrap();
|
||||
assert!(py_cfg.bind(py).as_any().getattr("a").is_err());
|
||||
let b: u32 = py_cfg
|
||||
.bind(py)
|
||||
.as_any()
|
||||
.getattr("b")
|
||||
.unwrap()
|
||||
.extract()
|
||||
.unwrap();
|
||||
assert_eq!(b, 3);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ mod inheriting_native_type {
|
|||
let item = &py.eval_bound("object()", None, None).unwrap();
|
||||
assert_eq!(item.get_refcnt(), 1);
|
||||
|
||||
dict_sub.as_ref(py).set_item("foo", item).unwrap();
|
||||
dict_sub.bind(py).as_any().set_item("foo", item).unwrap();
|
||||
assert_eq!(item.get_refcnt(), 2);
|
||||
|
||||
drop(dict_sub);
|
||||
|
|
|
@ -123,7 +123,7 @@ fn mapping_is_not_sequence() {
|
|||
|
||||
PyMapping::register::<Mapping>(py).unwrap();
|
||||
|
||||
assert!(m.as_ref(py).downcast::<PyMapping>().is_ok());
|
||||
assert!(m.as_ref(py).downcast::<PySequence>().is_err());
|
||||
assert!(m.bind(py).as_any().downcast::<PyMapping>().is_ok());
|
||||
assert!(m.bind(py).as_any().downcast::<PySequence>().is_err());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -191,20 +191,20 @@ pub struct Mapping {
|
|||
#[pymethods]
|
||||
impl Mapping {
|
||||
fn __len__(&self, py: Python<'_>) -> usize {
|
||||
self.values.as_ref(py).len()
|
||||
self.values.bind(py).len()
|
||||
}
|
||||
|
||||
fn __getitem__<'a>(&'a self, key: &'a PyAny) -> PyResult<&'a PyAny> {
|
||||
let any: &PyAny = self.values.as_ref(key.py()).as_ref();
|
||||
fn __getitem__<'py>(&self, key: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
|
||||
let any: &Bound<'py, PyAny> = self.values.bind(key.py());
|
||||
any.get_item(key)
|
||||
}
|
||||
|
||||
fn __setitem__(&self, key: &PyAny, value: &PyAny) -> PyResult<()> {
|
||||
self.values.as_ref(key.py()).set_item(key, value)
|
||||
fn __setitem__<'py>(&self, key: &Bound<'py, PyAny>, value: &Bound<'py, PyAny>) -> PyResult<()> {
|
||||
self.values.bind(key.py()).set_item(key, value)
|
||||
}
|
||||
|
||||
fn __delitem__(&self, key: &PyAny) -> PyResult<()> {
|
||||
self.values.as_ref(key.py()).del_item(key)
|
||||
fn __delitem__(&self, key: &Bound<'_, PyAny>) -> PyResult<()> {
|
||||
self.values.bind(key.py()).del_item(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ fn mapping() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let mapping: &PyMapping = inst.as_ref(py).downcast().unwrap();
|
||||
let mapping: &Bound<'_, PyMapping> = inst.bind(py).as_any().downcast().unwrap();
|
||||
|
||||
py_assert!(py, inst, "len(inst) == 0");
|
||||
|
||||
|
@ -323,7 +323,7 @@ fn sequence() {
|
|||
|
||||
let inst = Py::new(py, Sequence { values: vec![] }).unwrap();
|
||||
|
||||
let sequence: &PySequence = inst.as_ref(py).downcast().unwrap();
|
||||
let sequence: &Bound<'_, PySequence> = inst.bind(py).as_any().downcast().unwrap();
|
||||
|
||||
py_assert!(py, inst, "len(inst) == 0");
|
||||
|
||||
|
@ -350,16 +350,16 @@ fn sequence() {
|
|||
// indices.
|
||||
assert!(sequence.len().is_err());
|
||||
// however regular python len() works thanks to mp_len slot
|
||||
assert_eq!(inst.as_ref(py).len().unwrap(), 0);
|
||||
assert_eq!(inst.bind(py).as_any().len().unwrap(), 0);
|
||||
|
||||
py_run!(py, inst, "inst.append(0)");
|
||||
sequence.set_item(0, 5).unwrap();
|
||||
assert_eq!(inst.as_ref(py).len().unwrap(), 1);
|
||||
assert_eq!(inst.bind(py).as_any().len().unwrap(), 1);
|
||||
|
||||
assert_eq!(sequence.get_item(0).unwrap().extract::<u8>().unwrap(), 5);
|
||||
sequence.del_item(0).unwrap();
|
||||
|
||||
assert_eq!(inst.as_ref(py).len().unwrap(), 0);
|
||||
assert_eq!(inst.bind(py).as_any().len().unwrap(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -658,10 +658,10 @@ impl OnceFuture {
|
|||
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
|
||||
slf
|
||||
}
|
||||
fn __next__<'py>(&'py mut self, py: Python<'py>) -> Option<&'py PyAny> {
|
||||
fn __next__<'py>(&mut self, py: Python<'py>) -> Option<&Bound<'py, PyAny>> {
|
||||
if !self.polled {
|
||||
self.polled = true;
|
||||
Some(self.future.as_ref(py))
|
||||
Some(self.future.bind(py))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -63,12 +63,12 @@ impl Iter {
|
|||
}
|
||||
|
||||
fn __next__(mut slf: PyRefMut<'_, Self>) -> PyResult<Option<PyObject>> {
|
||||
let bytes = slf.keys.as_ref(slf.py()).as_bytes();
|
||||
let bytes = slf.keys.bind(slf.py()).as_bytes();
|
||||
match bytes.get(slf.idx) {
|
||||
Some(&b) => {
|
||||
slf.idx += 1;
|
||||
let py = slf.py();
|
||||
let reader = slf.reader.as_ref(py);
|
||||
let reader = slf.reader.bind(py);
|
||||
let reader_ref = reader.try_borrow()?;
|
||||
let res = reader_ref
|
||||
.inner
|
||||
|
|
|
@ -276,7 +276,7 @@ fn test_generic_list_set() {
|
|||
.items
|
||||
.iter()
|
||||
.zip(&[1u32, 2, 3])
|
||||
.all(|(a, b)| a.as_ref(py).eq(&b.into_py(py)).unwrap()));
|
||||
.all(|(a, b)| a.bind(py).eq(&b.into_py(py)).unwrap()));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ fn mut_ref_arg() {
|
|||
let inst2 = Py::new(py, MutRefArg { n: 0 }).unwrap();
|
||||
|
||||
py_run!(py, inst1 inst2, "inst1.set_other(inst2)");
|
||||
let inst2 = inst2.as_ref(py).borrow();
|
||||
let inst2 = inst2.bind(py).borrow();
|
||||
assert_eq!(inst2.n, 100);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue