Add `Py::bind`, `Py::into_bound`, and `Py::bind_borrowed`
This commit is contained in:
parent
0f242c399d
commit
e8e6fb93d7
|
@ -832,17 +832,18 @@ where
|
|||
|
||||
impl<T> Py<T> {
|
||||
/// Attaches this `Py` to the given Python context, allowing access to further Python APIs.
|
||||
pub(crate) fn attach<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
|
||||
pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
|
||||
// Safety: `Bound` has the same layout as `Py`
|
||||
unsafe { &*(self as *const Py<T>).cast() }
|
||||
}
|
||||
|
||||
/// Same as `attach` but takes ownership of `self`.
|
||||
pub(crate) fn attach_into(self, py: Python<'_>) -> Bound<'_, T> {
|
||||
/// Same as `bind` but takes ownership of `self`.
|
||||
pub fn into_bound(self, py: Python<'_>) -> Bound<'_, T> {
|
||||
Bound(py, ManuallyDrop::new(self))
|
||||
}
|
||||
|
||||
pub(crate) fn attach_borrow<'a, 'py>(&'a self, py: Python<'py>) -> Borrowed<'a, 'py, T> {
|
||||
/// Same as `bind` but produces a `Borrowed<T>` instead of a `Bound<T>`.
|
||||
pub fn bind_borrowed<'a, 'py>(&'a self, py: Python<'py>) -> Borrowed<'a, 'py, T> {
|
||||
Borrowed(self.0, PhantomData, py)
|
||||
}
|
||||
|
||||
|
@ -957,7 +958,7 @@ impl<T> Py<T> {
|
|||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
self.attach(py).as_any().getattr(attr_name).map(Into::into)
|
||||
self.bind(py).as_any().getattr(attr_name).map(Into::into)
|
||||
}
|
||||
|
||||
/// Sets an attribute value.
|
||||
|
@ -987,9 +988,9 @@ impl<T> Py<T> {
|
|||
N: IntoPy<Py<PyString>>,
|
||||
V: IntoPy<Py<PyAny>>,
|
||||
{
|
||||
self.attach(py)
|
||||
self.bind(py)
|
||||
.as_any()
|
||||
.setattr(attr_name, value.into_py(py).attach_into(py))
|
||||
.setattr(attr_name, value.into_py(py).into_bound(py))
|
||||
}
|
||||
|
||||
/// Calls the object.
|
||||
|
@ -1001,21 +1002,21 @@ impl<T> Py<T> {
|
|||
args: impl IntoPy<Py<PyTuple>>,
|
||||
kwargs: Option<&PyDict>,
|
||||
) -> PyResult<PyObject> {
|
||||
self.attach(py).as_any().call(args, kwargs).map(Into::into)
|
||||
self.bind(py).as_any().call(args, kwargs).map(Into::into)
|
||||
}
|
||||
|
||||
/// Calls the object with only positional arguments.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self(*args)`.
|
||||
pub fn call1(&self, py: Python<'_>, args: impl IntoPy<Py<PyTuple>>) -> PyResult<PyObject> {
|
||||
self.attach(py).as_any().call1(args).map(Into::into)
|
||||
self.bind(py).as_any().call1(args).map(Into::into)
|
||||
}
|
||||
|
||||
/// Calls the object without arguments.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self()`.
|
||||
pub fn call0(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||
self.attach(py).as_any().call0().map(Into::into)
|
||||
self.bind(py).as_any().call0().map(Into::into)
|
||||
}
|
||||
|
||||
/// Calls a method on the object.
|
||||
|
@ -1035,7 +1036,7 @@ impl<T> Py<T> {
|
|||
N: IntoPy<Py<PyString>>,
|
||||
A: IntoPy<Py<PyTuple>>,
|
||||
{
|
||||
self.attach(py)
|
||||
self.bind(py)
|
||||
.as_any()
|
||||
.call_method(name, args, kwargs)
|
||||
.map(Into::into)
|
||||
|
@ -1052,7 +1053,7 @@ impl<T> Py<T> {
|
|||
N: IntoPy<Py<PyString>>,
|
||||
A: IntoPy<Py<PyTuple>>,
|
||||
{
|
||||
self.attach(py)
|
||||
self.bind(py)
|
||||
.as_any()
|
||||
.call_method1(name, args)
|
||||
.map(Into::into)
|
||||
|
@ -1068,7 +1069,7 @@ impl<T> Py<T> {
|
|||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
self.attach(py).as_any().call_method0(name).map(Into::into)
|
||||
self.bind(py).as_any().call_method0(name).map(Into::into)
|
||||
}
|
||||
|
||||
/// Create a `Py<T>` instance by taking ownership of the given FFI pointer.
|
||||
|
@ -1624,7 +1625,7 @@ a = A()
|
|||
#[test]
|
||||
fn test_debug_fmt() {
|
||||
Python::with_gil(|py| {
|
||||
let obj = "hello world".to_object(py).attach_into(py);
|
||||
let obj = "hello world".to_object(py).into_bound(py);
|
||||
assert_eq!(format!("{:?}", obj), "'hello world'");
|
||||
});
|
||||
}
|
||||
|
@ -1632,7 +1633,7 @@ a = A()
|
|||
#[test]
|
||||
fn test_display_fmt() {
|
||||
Python::with_gil(|py| {
|
||||
let obj = "hello world".to_object(py).attach_into(py);
|
||||
let obj = "hello world".to_object(py).into_bound(py);
|
||||
assert_eq!(format!("{}", obj), "hello world");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1728,7 +1728,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, attr_name.into_py(self.py()).attach_into(py))
|
||||
inner(self, attr_name.into_py(self.py()).into_bound(py))
|
||||
}
|
||||
|
||||
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
|
||||
|
@ -1749,8 +1749,8 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
let py = self.py();
|
||||
inner(
|
||||
self,
|
||||
attr_name.into_py(py).attach_into(py),
|
||||
value.to_object(py).attach_into(py),
|
||||
attr_name.into_py(py).into_bound(py),
|
||||
value.to_object(py).into_bound(py),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1765,7 +1765,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, attr_name.into_py(py).attach_into(py))
|
||||
inner(self, attr_name.into_py(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn compare<O>(&self, other: O) -> PyResult<Ordering>
|
||||
|
@ -1795,7 +1795,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, other.to_object(py).attach_into(py))
|
||||
inner(self, other.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
|
||||
|
@ -1814,7 +1814,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, other.to_object(py).attach_into(py), compare_op)
|
||||
inner(self, other.to_object(py).into_bound(py), compare_op)
|
||||
}
|
||||
|
||||
fn lt<O>(&self, other: O) -> PyResult<bool>
|
||||
|
@ -1890,7 +1890,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, args.into_py(py).attach_into(py), kwargs)
|
||||
inner(self, args.into_py(py).into_bound(py), kwargs)
|
||||
}
|
||||
|
||||
fn call0(&self) -> PyResult<Bound<'py, PyAny>> {
|
||||
|
@ -1937,7 +1937,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
|
||||
// Optimized path on python 3.9+
|
||||
unsafe {
|
||||
let name = name.into_py(py).attach_into(py);
|
||||
let name = name.into_py(py).into_bound(py);
|
||||
ffi::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr()).assume_owned_or_err(py)
|
||||
}
|
||||
} else {
|
||||
|
@ -1987,7 +1987,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, key.to_object(py).attach_into(py))
|
||||
inner(self, key.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
|
@ -2008,8 +2008,8 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
let py = self.py();
|
||||
inner(
|
||||
self,
|
||||
key.to_object(py).attach_into(py),
|
||||
value.to_object(py).attach_into(py),
|
||||
key.to_object(py).into_bound(py),
|
||||
value.to_object(py).into_bound(py),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -2024,7 +2024,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, key.to_object(py).attach_into(py))
|
||||
inner(self, key.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn iter(&self) -> PyResult<Bound<'py, PyIterator>> {
|
||||
|
@ -2184,7 +2184,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, value.to_object(py).attach_into(py))
|
||||
inner(self, value.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
#[cfg(not(PyPy))]
|
||||
|
|
|
@ -129,7 +129,7 @@ impl Py<PyBytes> {
|
|||
/// immutable, the result may be used for as long as the reference to
|
||||
/// `self` is held, including when the GIL is released.
|
||||
pub fn as_bytes<'a>(&'a self, py: Python<'_>) -> &'a [u8] {
|
||||
self.attach_borrow(py).as_bytes()
|
||||
self.bind_borrowed(py).as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -391,7 +391,7 @@ impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, key.to_object(py).attach_into(py))
|
||||
inner(self, key.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn get_item<K>(&self, key: K) -> PyResult<Option<Bound<'py, PyAny>>>
|
||||
|
@ -414,7 +414,7 @@ impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, key.to_object(py).attach_into(py))
|
||||
inner(self, key.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
|
@ -435,8 +435,8 @@ impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
|
|||
let py = self.py();
|
||||
inner(
|
||||
self,
|
||||
key.to_object(py).attach_into(py),
|
||||
value.to_object(py).attach_into(py),
|
||||
key.to_object(py).into_bound(py),
|
||||
value.to_object(py).into_bound(py),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, key.to_object(py).attach_into(py))
|
||||
inner(self, key.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
fn keys(&self) -> Bound<'py, PyList> {
|
||||
|
|
|
@ -437,7 +437,7 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, index, item.to_object(py).attach_into(py))
|
||||
inner(self, index, item.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
/// Deletes the `index`th element of self.
|
||||
|
@ -483,7 +483,7 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, item.to_object(py).attach_into(py))
|
||||
inner(self, item.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
/// Inserts an item at the specified index.
|
||||
|
@ -500,7 +500,7 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, index, item.to_object(py).attach_into(py))
|
||||
inner(self, index, item.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
/// Determines if self contains `value`.
|
||||
|
|
|
@ -375,7 +375,7 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, i, item.to_object(py).attach_into(py))
|
||||
inner(self, i, item.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -417,7 +417,7 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, value.to_object(py).attach_into(py))
|
||||
inner(self, value.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -435,7 +435,7 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, value.to_object(py).attach_into(py))
|
||||
inner(self, value.to_object(py).into_bound(py))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -450,7 +450,7 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
|
|||
}
|
||||
|
||||
let py = self.py();
|
||||
inner(self, value.to_object(self.py()).attach_into(py))
|
||||
inner(self, value.to_object(self.py()).into_bound(py))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -407,7 +407,7 @@ impl Py<PyString> {
|
|||
/// the GIL lifetime.
|
||||
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
|
||||
pub fn to_str<'a>(&'a self, py: Python<'_>) -> PyResult<&'a str> {
|
||||
self.attach_borrow(py).to_str()
|
||||
self.bind_borrowed(py).to_str()
|
||||
}
|
||||
|
||||
/// Converts the `PyString` into a Rust string, avoiding copying when possible.
|
||||
|
@ -418,7 +418,7 @@ impl Py<PyString> {
|
|||
/// Because `str` objects are immutable, the returned slice is independent of
|
||||
/// the GIL lifetime.
|
||||
pub fn to_cow<'a>(&'a self, py: Python<'_>) -> PyResult<Cow<'a, str>> {
|
||||
self.attach_borrow(py).to_cow()
|
||||
self.bind_borrowed(py).to_cow()
|
||||
}
|
||||
|
||||
/// Converts the `PyString` into a Rust string.
|
||||
|
@ -429,7 +429,7 @@ impl Py<PyString> {
|
|||
/// Because `str` objects are immutable, the returned slice is independent of
|
||||
/// the GIL lifetime.
|
||||
pub fn to_string_lossy<'a>(&'a self, py: Python<'_>) -> Cow<'a, str> {
|
||||
self.attach_borrow(py).to_string_lossy()
|
||||
self.bind_borrowed(py).to_string_lossy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue