pyo3/instance.rs
1#![warn(clippy::undocumented_unsafe_blocks)] // TODO: remove this when the top-level is "warn" - https://github.com/PyO3/pyo3/issues/5487
2
3use crate::call::PyCallArgs;
4use crate::conversion::IntoPyObject;
5use crate::err::{PyErr, PyResult};
6use crate::impl_::pyclass::PyClassImpl;
7#[cfg(feature = "experimental-inspect")]
8use crate::inspect::PyStaticExpr;
9use crate::pycell::impl_::PyClassObjectLayout;
10use crate::pycell::{PyBorrowError, PyBorrowMutError};
11use crate::pyclass::boolean_struct::{False, True};
12use crate::types::{any::PyAnyMethods, string::PyStringMethods, typeobject::PyTypeMethods};
13use crate::types::{DerefToPyAny, PyDict, PyString};
14#[allow(deprecated)]
15use crate::DowncastError;
16use crate::{
17 ffi, CastError, CastIntoError, FromPyObject, PyAny, PyClass, PyClassInitializer, PyRef,
18 PyRefMut, PyTypeInfo, Python,
19};
20use crate::{internal::state, PyTypeCheck};
21use std::marker::PhantomData;
22use std::mem::ManuallyDrop;
23use std::ops::Deref;
24use std::ptr;
25use std::ptr::NonNull;
26
27/// Owned or borrowed Python smart pointer with a lifetime `'py` signalling
28/// attachment to the Python interpreter.
29///
30/// This is implemented for [`Bound`] and [`Borrowed`].
31pub trait BoundObject<'py, T>: bound_object_sealed::Sealed {
32 /// Type erased version of `Self`
33 type Any: BoundObject<'py, PyAny>;
34 /// Borrow this smart pointer.
35 fn as_borrowed(&self) -> Borrowed<'_, 'py, T>;
36 /// Turns this smart pointer into an owned [`Bound<'py, T>`]
37 fn into_bound(self) -> Bound<'py, T>;
38 /// Upcast the target type of this smart pointer
39 fn into_any(self) -> Self::Any;
40 /// Turn this smart pointer into a strong reference pointer
41 fn into_ptr(self) -> *mut ffi::PyObject;
42 /// Turn this smart pointer into a borrowed reference pointer
43 fn as_ptr(&self) -> *mut ffi::PyObject;
44 /// Turn this smart pointer into an owned [`Py<T>`]
45 fn unbind(self) -> Py<T>;
46}
47
48mod bound_object_sealed {
49 /// # Safety
50 ///
51 /// Type must be layout-compatible with `*mut ffi::PyObject`.
52 pub unsafe trait Sealed {}
53
54 // SAFETY: `Bound` is layout-compatible with `*mut ffi::PyObject`.
55 unsafe impl<T> Sealed for super::Bound<'_, T> {}
56 // SAFETY: `Borrowed` is layout-compatible with `*mut ffi::PyObject`.
57 unsafe impl<T> Sealed for super::Borrowed<'_, '_, T> {}
58}
59
60/// A Python thread-attached equivalent to [`Py<T>`].
61///
62/// This type can be thought of as equivalent to the tuple `(Py<T>, Python<'py>)`. By having the `'py`
63/// lifetime of the [`Python<'py>`] token, this ties the lifetime of the [`Bound<'py, T>`] smart pointer
64/// to the lifetime the thread is attached to the Python interpreter and allows PyO3 to call Python APIs
65/// at maximum efficiency.
66///
67/// To access the object in situations where the thread is not attached, convert it to [`Py<T>`]
68/// using [`.unbind()`][Bound::unbind]. This includes, for example, usage in
69/// [`Python::detach`](crate::Python::detach)'s closure.
70///
71/// See
72#[doc = concat!("[the guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/types.html#boundpy-t)")]
73/// for more detail.
74#[repr(transparent)]
75pub struct Bound<'py, T>(Python<'py>, ManuallyDrop<Py<T>>);
76
77impl<'py, T> Bound<'py, T>
78where
79 T: PyClass,
80{
81 /// Creates a new instance `Bound<T>` of a `#[pyclass]` on the Python heap.
82 ///
83 /// # Examples
84 ///
85 /// ```rust
86 /// use pyo3::prelude::*;
87 ///
88 /// #[pyclass]
89 /// struct Foo {/* fields omitted */}
90 ///
91 /// # fn main() -> PyResult<()> {
92 /// let foo: Py<Foo> = Python::attach(|py| -> PyResult<_> {
93 /// let foo: Bound<'_, Foo> = Bound::new(py, Foo {})?;
94 /// Ok(foo.into())
95 /// })?;
96 /// # Python::attach(move |_py| drop(foo));
97 /// # Ok(())
98 /// # }
99 /// ```
100 pub fn new(
101 py: Python<'py>,
102 value: impl Into<PyClassInitializer<T>>,
103 ) -> PyResult<Bound<'py, T>> {
104 value.into().create_class_object(py)
105 }
106}
107
108impl<'py, T> Bound<'py, T> {
109 /// Cast this to a concrete Python type or pyclass.
110 ///
111 /// Note that you can often avoid casting yourself by just specifying the desired type in
112 /// function or method signatures. However, manual casting is sometimes necessary.
113 ///
114 /// For extracting a Rust-only type, see [`extract`](PyAnyMethods::extract).
115 ///
116 /// This performs a runtime type check using the equivalent of Python's
117 /// `isinstance(self, U)`.
118 ///
119 /// # Example: Casting to a specific Python object
120 ///
121 /// ```rust
122 /// use pyo3::prelude::*;
123 /// use pyo3::types::{PyDict, PyList};
124 ///
125 /// Python::attach(|py| {
126 /// let dict = PyDict::new(py);
127 /// assert!(dict.is_instance_of::<PyAny>());
128 /// let any = dict.as_any();
129 ///
130 /// assert!(any.cast::<PyDict>().is_ok());
131 /// assert!(any.cast::<PyList>().is_err());
132 /// });
133 /// ```
134 ///
135 /// # Example: Getting a reference to a pyclass
136 ///
137 /// This is useful if you want to mutate a `Py<PyAny>` that might actually be a pyclass.
138 ///
139 /// ```rust
140 /// # fn main() -> Result<(), pyo3::PyErr> {
141 /// use pyo3::prelude::*;
142 ///
143 /// #[pyclass]
144 /// struct Class {
145 /// i: i32,
146 /// }
147 ///
148 /// Python::attach(|py| {
149 /// let class = Bound::new(py, Class { i: 0 })?.into_any();
150 ///
151 /// let class_bound: &Bound<'_, Class> = class.cast()?;
152 ///
153 /// class_bound.borrow_mut().i += 1;
154 ///
155 /// // Alternatively you can get a `PyRefMut` directly
156 /// let class_ref: PyRefMut<'_, Class> = class.extract()?;
157 /// assert_eq!(class_ref.i, 1);
158 /// Ok(())
159 /// })
160 /// # }
161 /// ```
162 #[inline]
163 pub fn cast<U>(&self) -> Result<&Bound<'py, U>, CastError<'_, 'py>>
164 where
165 U: PyTypeCheck,
166 {
167 #[inline]
168 fn inner<'a, 'py, U>(
169 any: &'a Bound<'py, PyAny>,
170 ) -> Result<&'a Bound<'py, U>, CastError<'a, 'py>>
171 where
172 U: PyTypeCheck,
173 {
174 if U::type_check(any) {
175 // Safety: type_check is responsible for ensuring that the type is correct
176 Ok(unsafe { any.cast_unchecked() })
177 } else {
178 Err(CastError::new(
179 any.as_borrowed(),
180 U::classinfo_object(any.py()),
181 ))
182 }
183 }
184
185 inner(self.as_any())
186 }
187
188 /// Like [`cast`](Self::cast) but takes ownership of `self`.
189 ///
190 /// In case of an error, it is possible to retrieve `self` again via
191 /// [`CastIntoError::into_inner`].
192 ///
193 /// # Example
194 ///
195 /// ```rust
196 /// use pyo3::prelude::*;
197 /// use pyo3::types::{PyDict, PyList};
198 ///
199 /// Python::attach(|py| {
200 /// let obj: Bound<'_, PyAny> = PyDict::new(py).into_any();
201 ///
202 /// let obj: Bound<'_, PyAny> = match obj.cast_into::<PyList>() {
203 /// Ok(_) => panic!("obj should not be a list"),
204 /// Err(err) => err.into_inner(),
205 /// };
206 ///
207 /// // obj is a dictionary
208 /// assert!(obj.cast_into::<PyDict>().is_ok());
209 /// })
210 /// ```
211 #[inline]
212 pub fn cast_into<U>(self) -> Result<Bound<'py, U>, CastIntoError<'py>>
213 where
214 U: PyTypeCheck,
215 {
216 #[inline]
217 fn inner<U>(any: Bound<'_, PyAny>) -> Result<Bound<'_, U>, CastIntoError<'_>>
218 where
219 U: PyTypeCheck,
220 {
221 if U::type_check(&any) {
222 // Safety: type_check is responsible for ensuring that the type is correct
223 Ok(unsafe { any.cast_into_unchecked() })
224 } else {
225 let to = U::classinfo_object(any.py());
226 Err(CastIntoError::new(any, to))
227 }
228 }
229
230 inner(self.into_any())
231 }
232
233 /// Cast this to a concrete Python type or pyclass (but not a subclass of it).
234 ///
235 /// It is almost always better to use [`cast`](Self::cast) because it accounts for Python
236 /// subtyping. Use this method only when you do not want to allow subtypes.
237 ///
238 /// The advantage of this method over [`cast`](Self::cast) is that it is faster. The
239 /// implementation of `cast_exact` uses the equivalent of the Python expression `type(self) is
240 /// U`, whereas `cast` uses `isinstance(self, U)`.
241 ///
242 /// For extracting a Rust-only type, see [`extract`](PyAnyMethods::extract).
243 ///
244 /// # Example: Casting to a specific Python object but not a subtype
245 ///
246 /// ```rust
247 /// use pyo3::prelude::*;
248 /// use pyo3::types::{PyBool, PyInt};
249 ///
250 /// Python::attach(|py| {
251 /// let b = PyBool::new(py, true);
252 /// assert!(b.is_instance_of::<PyBool>());
253 /// let any: &Bound<'_, PyAny> = b.as_any();
254 ///
255 /// // `bool` is a subtype of `int`, so `cast` will accept a `bool` as an `int`
256 /// // but `cast_exact` will not.
257 /// assert!(any.cast::<PyInt>().is_ok());
258 /// assert!(any.cast_exact::<PyInt>().is_err());
259 ///
260 /// assert!(any.cast_exact::<PyBool>().is_ok());
261 /// });
262 /// ```
263 #[inline]
264 pub fn cast_exact<U>(&self) -> Result<&Bound<'py, U>, CastError<'_, 'py>>
265 where
266 U: PyTypeInfo,
267 {
268 #[inline]
269 fn inner<'a, 'py, U>(
270 any: &'a Bound<'py, PyAny>,
271 ) -> Result<&'a Bound<'py, U>, CastError<'a, 'py>>
272 where
273 U: PyTypeInfo,
274 {
275 if any.is_exact_instance_of::<U>() {
276 // Safety: is_exact_instance_of is responsible for ensuring that the type is correct
277 Ok(unsafe { any.cast_unchecked() })
278 } else {
279 Err(CastError::new(
280 any.as_borrowed(),
281 U::type_object(any.py()).into_any(),
282 ))
283 }
284 }
285
286 inner(self.as_any())
287 }
288
289 /// Like [`cast_exact`](Self::cast_exact) but takes ownership of `self`.
290 #[inline]
291 pub fn cast_into_exact<U>(self) -> Result<Bound<'py, U>, CastIntoError<'py>>
292 where
293 U: PyTypeInfo,
294 {
295 #[inline]
296 fn inner<U>(any: Bound<'_, PyAny>) -> Result<Bound<'_, U>, CastIntoError<'_>>
297 where
298 U: PyTypeInfo,
299 {
300 if any.is_exact_instance_of::<U>() {
301 // Safety: is_exact_instance_of is responsible for ensuring that the type is correct
302 Ok(unsafe { any.cast_into_unchecked() })
303 } else {
304 let to = U::type_object(any.py()).into_any();
305 Err(CastIntoError::new(any, to))
306 }
307 }
308
309 inner(self.into_any())
310 }
311
312 /// Converts this to a concrete Python type without checking validity.
313 ///
314 /// # Safety
315 ///
316 /// Callers must ensure that the type is valid or risk type confusion.
317 #[inline]
318 pub unsafe fn cast_unchecked<U>(&self) -> &Bound<'py, U> {
319 // SAFETY: caller has upheld the safety contract, all `Bound` have the same layout
320 unsafe { NonNull::from(self).cast().as_ref() }
321 }
322
323 /// Like [`cast_unchecked`](Self::cast_unchecked) but takes ownership of `self`.
324 ///
325 /// # Safety
326 ///
327 /// Callers must ensure that the type is valid or risk type confusion.
328 #[inline]
329 pub unsafe fn cast_into_unchecked<U>(self) -> Bound<'py, U> {
330 // SAFETY: caller has upheld the safety contract, all `Bound` have the same layout
331 unsafe { std::mem::transmute(self) }
332 }
333}
334
335impl<'py> Bound<'py, PyAny> {
336 /// Constructs a new `Bound<'py, PyAny>` from a pointer. Panics if `ptr` is null.
337 ///
338 /// # Safety
339 ///
340 /// - `ptr` must be a valid pointer to a Python object (or null, which will cause a panic)
341 /// - `ptr` must be an owned Python reference, as the `Bound<'py, PyAny>` will assume ownership
342 ///
343 /// # Panics
344 ///
345 /// Panics if `ptr` is null.
346 #[inline]
347 #[track_caller]
348 pub unsafe fn from_owned_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
349 let non_null = NonNull::new(ptr).unwrap_or_else(|| panic_on_null(py));
350 // SAFETY: caller has upheld the safety contract, ptr is known to be non-null
351 unsafe { Py::from_non_null(non_null) }.into_bound(py)
352 }
353
354 /// Constructs a new `Bound<'py, PyAny>` from a pointer. Returns `None` if `ptr` is null.
355 ///
356 /// # Safety
357 ///
358 /// - `ptr` must be a valid pointer to a Python object, or null
359 /// - `ptr` must be an owned Python reference, as the `Bound<'py, PyAny>` will assume ownership
360 #[inline]
361 pub unsafe fn from_owned_ptr_or_opt(py: Python<'py>, ptr: *mut ffi::PyObject) -> Option<Self> {
362 NonNull::new(ptr).map(|nonnull_ptr| {
363 // SAFETY: caller has upheld the safety contract
364 unsafe { Py::from_non_null(nonnull_ptr) }.into_bound(py)
365 })
366 }
367
368 /// Constructs a new `Bound<'py, PyAny>` from a pointer. Returns an `Err` by calling `PyErr::fetch`
369 /// if `ptr` is null.
370 ///
371 /// # Safety
372 ///
373 /// - `ptr` must be a valid pointer to a Python object, or null
374 /// - `ptr` must be an owned Python reference, as the `Bound<'py, PyAny>` will assume ownership
375 #[inline]
376 pub unsafe fn from_owned_ptr_or_err(
377 py: Python<'py>,
378 ptr: *mut ffi::PyObject,
379 ) -> PyResult<Self> {
380 match NonNull::new(ptr) {
381 Some(nonnull_ptr) => Ok(
382 // SAFETY: caller has upheld the safety contract, ptr is known to be non-null
383 unsafe { Py::from_non_null(nonnull_ptr) }.into_bound(py),
384 ),
385 None => Err(PyErr::fetch(py)),
386 }
387 }
388
389 /// Constructs a new `Bound<'py, PyAny>` from a pointer without checking for null.
390 ///
391 /// # Safety
392 ///
393 /// - `ptr` must be a valid pointer to a Python object
394 /// - `ptr` must be a strong/owned reference
395 pub(crate) unsafe fn from_owned_ptr_unchecked(
396 py: Python<'py>,
397 ptr: *mut ffi::PyObject,
398 ) -> Self {
399 // SAFETY: caller has upheld the safety contract
400 unsafe { Py::from_non_null(NonNull::new_unchecked(ptr)) }.into_bound(py)
401 }
402
403 /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference.
404 /// Panics if `ptr` is null.
405 ///
406 /// # Safety
407 ///
408 /// - `ptr` must be a valid pointer to a Python object
409 ///
410 /// # Panics
411 ///
412 /// Panics if `ptr` is null
413 #[inline]
414 #[track_caller]
415 pub unsafe fn from_borrowed_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
416 let non_null = NonNull::new(ptr).unwrap_or_else(|| panic_on_null(py));
417 // SAFETY: caller has upheld the safety contract, ptr is known to be non-null
418 unsafe { Py::from_borrowed_non_null(py, non_null) }.into_bound(py)
419 }
420
421 /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference.
422 /// Returns `None` if `ptr` is null.
423 ///
424 /// # Safety
425 ///
426 /// - `ptr` must be a valid pointer to a Python object, or null
427 #[inline]
428 pub unsafe fn from_borrowed_ptr_or_opt(
429 py: Python<'py>,
430 ptr: *mut ffi::PyObject,
431 ) -> Option<Self> {
432 NonNull::new(ptr).map(|nonnull_ptr| {
433 // SAFETY: caller has upheld the safety contract
434 unsafe { Py::from_borrowed_non_null(py, nonnull_ptr) }.into_bound(py)
435 })
436 }
437
438 /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference.
439 /// Returns an `Err` by calling `PyErr::fetch` if `ptr` is null.
440 ///
441 /// # Safety
442 ///
443 /// - `ptr` must be a valid pointer to a Python object, or null
444 #[inline]
445 pub unsafe fn from_borrowed_ptr_or_err(
446 py: Python<'py>,
447 ptr: *mut ffi::PyObject,
448 ) -> PyResult<Self> {
449 match NonNull::new(ptr) {
450 Some(nonnull_ptr) => Ok(
451 // SAFETY: caller has upheld the safety contract
452 unsafe { Py::from_borrowed_non_null(py, nonnull_ptr) }.into_bound(py),
453 ),
454 None => Err(PyErr::fetch(py)),
455 }
456 }
457
458 /// This slightly strange method is used to obtain `&Bound<PyAny>` from a pointer in macro code
459 /// where we need to constrain the lifetime `'a` safely.
460 ///
461 /// Note that `'py` is required to outlive `'a` implicitly by the nature of the fact that
462 /// `&'a Bound<'py>` means that `Bound<'py>` exists for at least the lifetime `'a`.
463 ///
464 /// # Safety
465 /// - `ptr` must be a valid pointer to a Python object for the lifetime `'a`. The `ptr` can
466 /// be either a borrowed reference or an owned reference, it does not matter, as this is
467 /// just `&Bound` there will never be any ownership transfer.
468 #[inline]
469 #[doc(hidden)]
470 pub unsafe fn ref_from_ptr<'a>(_py: Python<'py>, ptr: &'a *mut ffi::PyObject) -> &'a Self {
471 let ptr = NonNull::from(ptr).cast();
472 // SAFETY: caller has upheld the safety contract,
473 // and `Bound<PyAny>` is layout-compatible with `*mut ffi::PyObject`.
474 unsafe { ptr.as_ref() }
475 }
476
477 /// Variant of the above which returns `None` for null pointers.
478 ///
479 /// # Safety
480 /// - `ptr` must be a valid pointer to a Python object for the lifetime `'a, or null.
481 #[inline]
482 pub(crate) unsafe fn ref_from_ptr_or_opt<'a>(
483 _py: Python<'py>,
484 ptr: &'a *mut ffi::PyObject,
485 ) -> &'a Option<Self> {
486 let ptr = NonNull::from(ptr).cast();
487 // SAFETY: caller has upheld the safety contract,
488 // and `Option<Bound<PyAny>>` is layout-compatible with `*mut ffi::PyObject`.
489 unsafe { ptr.as_ref() }
490 }
491
492 /// This slightly strange method is used to obtain `&Bound<PyAny>` from a [`NonNull`] in macro
493 /// code where we need to constrain the lifetime `'a` safely.
494 ///
495 /// Note that `'py` is required to outlive `'a` implicitly by the nature of the fact that `&'a
496 /// Bound<'py>` means that `Bound<'py>` exists for at least the lifetime `'a`.
497 ///
498 /// # Safety
499 /// - `ptr` must be a valid pointer to a Python object for the lifetime `'a`. The `ptr` can be
500 /// either a borrowed reference or an owned reference, it does not matter, as this is just
501 /// `&Bound` there will never be any ownership transfer.
502 #[doc(hidden)]
503 pub unsafe fn ref_from_non_null<'a>(
504 _py: Python<'py>,
505 ptr: &'a NonNull<ffi::PyObject>,
506 ) -> &'a Self {
507 let ptr = NonNull::from(ptr).cast();
508 // SAFETY: caller has upheld the safety contract,
509 // and `Bound<PyAny>` is layout-compatible with `NonNull<ffi::PyObject>`.
510 unsafe { ptr.as_ref() }
511 }
512}
513
514impl<'py, T> Bound<'py, T>
515where
516 T: PyClass,
517{
518 /// Immutably borrows the value `T`.
519 ///
520 /// This borrow lasts while the returned [`PyRef`] exists.
521 /// Multiple immutable borrows can be taken out at the same time.
522 ///
523 /// For frozen classes, the simpler [`get`][Self::get] is available.
524 ///
525 /// # Examples
526 ///
527 /// ```rust
528 /// # use pyo3::prelude::*;
529 /// #
530 /// #[pyclass]
531 /// struct Foo {
532 /// inner: u8,
533 /// }
534 ///
535 /// # fn main() -> PyResult<()> {
536 /// Python::attach(|py| -> PyResult<()> {
537 /// let foo: Bound<'_, Foo> = Bound::new(py, Foo { inner: 73 })?;
538 /// let inner: &u8 = &foo.borrow().inner;
539 ///
540 /// assert_eq!(*inner, 73);
541 /// Ok(())
542 /// })?;
543 /// # Ok(())
544 /// # }
545 /// ```
546 ///
547 /// # Panics
548 ///
549 /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
550 /// [`try_borrow`](#method.try_borrow).
551 #[inline]
552 #[track_caller]
553 pub fn borrow(&self) -> PyRef<'py, T> {
554 PyRef::borrow(self)
555 }
556
557 /// Mutably borrows the value `T`.
558 ///
559 /// This borrow lasts while the returned [`PyRefMut`] exists.
560 ///
561 /// # Examples
562 ///
563 /// ```
564 /// # use pyo3::prelude::*;
565 /// #
566 /// #[pyclass]
567 /// struct Foo {
568 /// inner: u8,
569 /// }
570 ///
571 /// # fn main() -> PyResult<()> {
572 /// Python::attach(|py| -> PyResult<()> {
573 /// let foo: Bound<'_, Foo> = Bound::new(py, Foo { inner: 73 })?;
574 /// foo.borrow_mut().inner = 35;
575 ///
576 /// assert_eq!(foo.borrow().inner, 35);
577 /// Ok(())
578 /// })?;
579 /// # Ok(())
580 /// # }
581 /// ```
582 ///
583 /// # Panics
584 /// Panics if the value is currently borrowed. For a non-panicking variant, use
585 /// [`try_borrow_mut`](#method.try_borrow_mut).
586 #[inline]
587 #[track_caller]
588 pub fn borrow_mut(&self) -> PyRefMut<'py, T>
589 where
590 T: PyClass<Frozen = False>,
591 {
592 PyRefMut::borrow(self)
593 }
594
595 /// Attempts to immutably borrow the value `T`, returning an error if the value is currently mutably borrowed.
596 ///
597 /// The borrow lasts while the returned [`PyRef`] exists.
598 ///
599 /// This is the non-panicking variant of [`borrow`](#method.borrow).
600 ///
601 /// For frozen classes, the simpler [`get`][Self::get] is available.
602 #[inline]
603 pub fn try_borrow(&self) -> Result<PyRef<'py, T>, PyBorrowError> {
604 PyRef::try_borrow(self)
605 }
606
607 /// Attempts to mutably borrow the value `T`, returning an error if the value is currently borrowed.
608 ///
609 /// The borrow lasts while the returned [`PyRefMut`] exists.
610 ///
611 /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
612 #[inline]
613 pub fn try_borrow_mut(&self) -> Result<PyRefMut<'py, T>, PyBorrowMutError>
614 where
615 T: PyClass<Frozen = False>,
616 {
617 PyRefMut::try_borrow(self)
618 }
619
620 /// Provide an immutable borrow of the value `T`.
621 ///
622 /// This is available if the class is [`frozen`][macro@crate::pyclass] and [`Sync`].
623 ///
624 /// # Examples
625 ///
626 /// ```
627 /// use std::sync::atomic::{AtomicUsize, Ordering};
628 /// # use pyo3::prelude::*;
629 ///
630 /// #[pyclass(frozen)]
631 /// struct FrozenCounter {
632 /// value: AtomicUsize,
633 /// }
634 ///
635 /// Python::attach(|py| {
636 /// let counter = FrozenCounter { value: AtomicUsize::new(0) };
637 ///
638 /// let py_counter = Bound::new(py, counter).unwrap();
639 ///
640 /// py_counter.get().value.fetch_add(1, Ordering::Relaxed);
641 /// });
642 /// ```
643 #[inline]
644 pub fn get(&self) -> &T
645 where
646 T: PyClass<Frozen = True> + Sync,
647 {
648 self.as_borrowed().get()
649 }
650
651 /// Upcast this `Bound<PyClass>` to its base type by reference.
652 ///
653 /// If this type defined an explicit base class in its `pyclass` declaration
654 /// (e.g. `#[pyclass(extends = BaseType)]`), the returned type will be
655 /// `&Bound<BaseType>`. If an explicit base class was _not_ declared, the
656 /// return value will be `&Bound<PyAny>` (making this method equivalent
657 /// to [`as_any`]).
658 ///
659 /// This method is particularly useful for calling methods defined in an
660 /// extension trait that has been implemented for `Bound<BaseType>`.
661 ///
662 /// See also the [`into_super`] method to upcast by value, and the
663 /// [`PyRef::as_super`]/[`PyRefMut::as_super`] methods for upcasting a pyclass
664 /// that has already been [`borrow`]ed.
665 ///
666 /// # Example: Calling a method defined on the `Bound` base type
667 ///
668 /// ```rust
669 /// # fn main() {
670 /// use pyo3::prelude::*;
671 ///
672 /// #[pyclass(subclass)]
673 /// struct BaseClass;
674 ///
675 /// trait MyClassMethods<'py> {
676 /// fn pyrepr(&self) -> PyResult<String>;
677 /// }
678 /// impl<'py> MyClassMethods<'py> for Bound<'py, BaseClass> {
679 /// fn pyrepr(&self) -> PyResult<String> {
680 /// self.call_method0("__repr__")?.extract()
681 /// }
682 /// }
683 ///
684 /// #[pyclass(extends = BaseClass)]
685 /// struct SubClass;
686 ///
687 /// Python::attach(|py| {
688 /// let obj = Bound::new(py, (SubClass, BaseClass)).unwrap();
689 /// assert!(obj.as_super().pyrepr().is_ok());
690 /// })
691 /// # }
692 /// ```
693 ///
694 /// [`as_any`]: Bound::as_any
695 /// [`into_super`]: Bound::into_super
696 /// [`borrow`]: Bound::borrow
697 #[inline]
698 pub fn as_super(&self) -> &Bound<'py, T::BaseType> {
699 // SAFETY: a pyclass can always be safely "cast" to its base type
700 unsafe { self.cast_unchecked() }
701 }
702
703 /// Upcast this `Bound<PyClass>` to its base type by value.
704 ///
705 /// If this type defined an explicit base class in its `pyclass` declaration
706 /// (e.g. `#[pyclass(extends = BaseType)]`), the returned type will be
707 /// `Bound<BaseType>`. If an explicit base class was _not_ declared, the
708 /// return value will be `Bound<PyAny>` (making this method equivalent
709 /// to [`into_any`]).
710 ///
711 /// This method is particularly useful for calling methods defined in an
712 /// extension trait that has been implemented for `Bound<BaseType>`.
713 ///
714 /// See also the [`as_super`] method to upcast by reference, and the
715 /// [`PyRef::into_super`]/[`PyRefMut::into_super`] methods for upcasting a pyclass
716 /// that has already been [`borrow`]ed.
717 ///
718 /// # Example: Calling a method defined on the `Bound` base type
719 ///
720 /// ```rust
721 /// # fn main() {
722 /// use pyo3::prelude::*;
723 ///
724 /// #[pyclass(subclass)]
725 /// struct BaseClass;
726 ///
727 /// trait MyClassMethods<'py> {
728 /// fn pyrepr(self) -> PyResult<String>;
729 /// }
730 /// impl<'py> MyClassMethods<'py> for Bound<'py, BaseClass> {
731 /// fn pyrepr(self) -> PyResult<String> {
732 /// self.call_method0("__repr__")?.extract()
733 /// }
734 /// }
735 ///
736 /// #[pyclass(extends = BaseClass)]
737 /// struct SubClass;
738 ///
739 /// Python::attach(|py| {
740 /// let obj = Bound::new(py, (SubClass, BaseClass)).unwrap();
741 /// assert!(obj.into_super().pyrepr().is_ok());
742 /// })
743 /// # }
744 /// ```
745 ///
746 /// [`into_any`]: Bound::into_any
747 /// [`as_super`]: Bound::as_super
748 /// [`borrow`]: Bound::borrow
749 #[inline]
750 pub fn into_super(self) -> Bound<'py, T::BaseType> {
751 // SAFETY: a pyclass can always be safely "cast" to its base type
752 unsafe { self.cast_into_unchecked() }
753 }
754
755 #[inline]
756 pub(crate) fn get_class_object(&self) -> &<T as PyClassImpl>::Layout {
757 self.1.get_class_object()
758 }
759}
760
761impl<T> std::fmt::Debug for Bound<'_, T> {
762 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
763 let any = self.as_any();
764 python_format(any, any.repr(), f)
765 }
766}
767
768impl<T> std::fmt::Display for Bound<'_, T> {
769 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
770 let any = self.as_any();
771 python_format(any, any.str(), f)
772 }
773}
774
775fn python_format(
776 any: &Bound<'_, PyAny>,
777 format_result: PyResult<Bound<'_, PyString>>,
778 f: &mut std::fmt::Formatter<'_>,
779) -> Result<(), std::fmt::Error> {
780 match format_result {
781 Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
782 Result::Err(err) => err.write_unraisable(any.py(), Some(any)),
783 }
784
785 match any.get_type().name() {
786 Result::Ok(name) => std::write!(f, "<unprintable {name} object>"),
787 Result::Err(_err) => f.write_str("<unprintable object>"),
788 }
789}
790
791// The trait bound is needed to avoid running into the auto-deref recursion
792// limit (error[E0055]), because `Bound<PyAny>` would deref into itself. See:
793// https://github.com/rust-lang/rust/issues/19509
794impl<'py, T> Deref for Bound<'py, T>
795where
796 T: DerefToPyAny,
797{
798 type Target = Bound<'py, PyAny>;
799
800 #[inline]
801 fn deref(&self) -> &Bound<'py, PyAny> {
802 self.as_any()
803 }
804}
805
806impl<'py, T> AsRef<Bound<'py, PyAny>> for Bound<'py, T> {
807 #[inline]
808 fn as_ref(&self) -> &Bound<'py, PyAny> {
809 self.as_any()
810 }
811}
812
813impl<T> AsRef<Py<PyAny>> for Bound<'_, T> {
814 #[inline]
815 fn as_ref(&self) -> &Py<PyAny> {
816 self.as_any().as_unbound()
817 }
818}
819
820impl<T> Clone for Bound<'_, T> {
821 #[inline]
822 fn clone(&self) -> Self {
823 Self(self.0, ManuallyDrop::new(self.1.clone_ref(self.0)))
824 }
825}
826
827impl<T> Drop for Bound<'_, T> {
828 #[inline]
829 fn drop(&mut self) {
830 // SAFETY: self is an owned reference and the `Bound` implies the thread
831 // is attached to the interpreter
832 unsafe { ffi::Py_DECREF(self.as_ptr()) }
833 }
834}
835
836impl<'py, T> Bound<'py, T> {
837 /// Returns the [`Python`] token associated with this object.
838 #[inline]
839 pub fn py(&self) -> Python<'py> {
840 self.0
841 }
842
843 /// Returns the raw FFI pointer represented by self.
844 ///
845 /// # Safety
846 ///
847 /// Callers are responsible for ensuring that the pointer does not outlive self.
848 ///
849 /// The reference is borrowed; callers should not decrease the reference count
850 /// when they are finished with the pointer.
851 #[inline]
852 pub fn as_ptr(&self) -> *mut ffi::PyObject {
853 self.1.as_ptr()
854 }
855
856 /// Returns an owned raw FFI pointer represented by self.
857 ///
858 /// # Safety
859 ///
860 /// The reference is owned; when finished the caller should either transfer ownership
861 /// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
862 #[inline]
863 pub fn into_ptr(self) -> *mut ffi::PyObject {
864 ManuallyDrop::new(self).as_ptr()
865 }
866
867 /// Helper to cast to `Bound<'py, PyAny>`.
868 #[inline]
869 pub fn as_any(&self) -> &Bound<'py, PyAny> {
870 let ptr = NonNull::from(self).cast();
871 // Safety: all Bound<T> have the same memory layout, and all Bound<T> are valid
872 // Bound<PyAny>, so pointer casting is valid.
873 unsafe { ptr.as_ref() }
874 }
875
876 /// Helper to cast to `Bound<'py, PyAny>`, transferring ownership.
877 #[inline]
878 pub fn into_any(self) -> Bound<'py, PyAny> {
879 // Safety: all Bound<T> are valid Bound<PyAny>
880 Bound(self.0, ManuallyDrop::new(self.unbind().into_any()))
881 }
882
883 /// Casts this `Bound<T>` to a `Borrowed<T>` smart pointer.
884 #[inline]
885 pub fn as_borrowed<'a>(&'a self) -> Borrowed<'a, 'py, T> {
886 // SAFETY: self is known to be a valid pointer to T and will be borrowed from the lifetime 'a
887 unsafe { Borrowed::from_non_null(self.py(), (self.1).0).cast_unchecked() }
888 }
889
890 /// Removes the connection for this `Bound<T>` from the [`Python<'py>`] token,
891 /// allowing it to cross thread boundaries.
892 #[inline]
893 pub fn unbind(self) -> Py<T> {
894 let non_null = (ManuallyDrop::new(self).1).0;
895 // SAFETY: the type T is known to be correct and the `ManuallyDrop` ensures
896 // the ownership of the reference is transferred into the `Py<T>`.
897 unsafe { Py::from_non_null(non_null) }
898 }
899
900 /// Removes the connection for this `Bound<T>` from the [`Python<'py>`] token,
901 /// allowing it to cross thread boundaries, without transferring ownership.
902 #[inline]
903 pub fn as_unbound(&self) -> &Py<T> {
904 &self.1
905 }
906}
907
908impl<'py, T> BoundObject<'py, T> for Bound<'py, T> {
909 type Any = Bound<'py, PyAny>;
910
911 fn as_borrowed(&self) -> Borrowed<'_, 'py, T> {
912 Bound::as_borrowed(self)
913 }
914
915 fn into_bound(self) -> Bound<'py, T> {
916 self
917 }
918
919 fn into_any(self) -> Self::Any {
920 self.into_any()
921 }
922
923 fn into_ptr(self) -> *mut ffi::PyObject {
924 self.into_ptr()
925 }
926
927 fn as_ptr(&self) -> *mut ffi::PyObject {
928 self.as_ptr()
929 }
930
931 fn unbind(self) -> Py<T> {
932 self.unbind()
933 }
934}
935
936/// A borrowed equivalent to [`Bound`].
937///
938/// [`Borrowed<'a, 'py, T>`] is an advanced type used just occasionally at the edge of interaction
939/// with the Python interpreter. It can be thought of as analogous to the shared reference `&'a
940/// Bound<'py, T>`, similarly this type is `Copy` and `Clone`. The difference is that [`Borrowed<'a,
941/// 'py, T>`] is just a smart pointer rather than a reference-to-a-smart-pointer. For one this
942/// reduces one level of pointer indirection, but additionally it removes the implicit lifetime
943/// relation that `'py` has to outlive `'a` (`'py: 'a`). This opens the possibility to borrow from
944/// the underlying Python object without necessarily requiring attachment to the interpreter for
945/// that duration. Within PyO3 this is used for example for the byte slice (`&[u8]`) extraction.
946///
947/// [`Borrowed<'a, 'py, T>`] dereferences to [`Bound<'py, T>`], so all methods on [`Bound<'py, T>`]
948/// are available on [`Borrowed<'a, 'py, T>`].
949///
950/// Some Python C APIs also return "borrowed" pointers, which need to be increfd by the caller to
951/// keep them alive. This can also be modelled using [`Borrowed`]. However with free-threading these
952/// APIs are gradually replaced, because in absence of the GIL it is very hard to guarantee that the
953/// referred to object is not deallocated between receiving the pointer and incrementing the
954/// reference count. When possible APIs which return a "strong" reference (modelled by [`Bound`])
955/// should be using instead and otherwise great care needs to be taken to ensure safety.
956#[repr(transparent)]
957pub struct Borrowed<'a, 'py, T>(NonNull<ffi::PyObject>, PhantomData<&'a Py<T>>, Python<'py>);
958
959impl<'a, 'py, T> Borrowed<'a, 'py, T> {
960 /// Creates a new owned [`Bound<T>`] from this borrowed reference by
961 /// increasing the reference count.
962 ///
963 /// # Example
964 /// ```
965 /// use pyo3::{prelude::*, types::PyTuple};
966 ///
967 /// # fn main() -> PyResult<()> {
968 /// Python::attach(|py| -> PyResult<()> {
969 /// let tuple = PyTuple::new(py, [1, 2, 3])?;
970 ///
971 /// // borrows from `tuple`, so can only be
972 /// // used while `tuple` stays alive
973 /// let borrowed = tuple.get_borrowed_item(0)?;
974 ///
975 /// // creates a new owned reference, which
976 /// // can be used indendently of `tuple`
977 /// let bound = borrowed.to_owned();
978 /// drop(tuple);
979 ///
980 /// assert_eq!(bound.extract::<i32>().unwrap(), 1);
981 /// Ok(())
982 /// })
983 /// # }
984 pub fn to_owned(self) -> Bound<'py, T> {
985 (*self).clone()
986 }
987
988 /// Returns the raw FFI pointer represented by self.
989 ///
990 /// # Safety
991 ///
992 /// Callers are responsible for ensuring that the pointer does not outlive self.
993 ///
994 /// The reference is borrowed; callers should not decrease the reference count
995 /// when they are finished with the pointer.
996 #[inline]
997 pub fn as_ptr(self) -> *mut ffi::PyObject {
998 self.0.as_ptr()
999 }
1000
1001 pub(crate) fn to_any(self) -> Borrowed<'a, 'py, PyAny> {
1002 Borrowed(self.0, PhantomData, self.2)
1003 }
1004
1005 /// Extracts some type from the Python object.
1006 ///
1007 /// This is a wrapper function around [`FromPyObject::extract()`](crate::FromPyObject::extract).
1008 pub fn extract<O>(self) -> Result<O, O::Error>
1009 where
1010 O: FromPyObject<'a, 'py>,
1011 {
1012 FromPyObject::extract(self.to_any())
1013 }
1014
1015 /// Cast this to a concrete Python type or pyclass.
1016 ///
1017 /// This performs a runtime type check using the equivalent of Python's
1018 /// `isinstance(self, U)`.
1019 #[inline]
1020 pub fn cast<U>(self) -> Result<Borrowed<'a, 'py, U>, CastError<'a, 'py>>
1021 where
1022 U: PyTypeCheck,
1023 {
1024 fn inner<'a, 'py, U>(
1025 any: Borrowed<'a, 'py, PyAny>,
1026 ) -> Result<Borrowed<'a, 'py, U>, CastError<'a, 'py>>
1027 where
1028 U: PyTypeCheck,
1029 {
1030 if U::type_check(&any) {
1031 // Safety: type_check is responsible for ensuring that the type is correct
1032 Ok(unsafe { any.cast_unchecked() })
1033 } else {
1034 Err(CastError::new(any, U::classinfo_object(any.py())))
1035 }
1036 }
1037 inner(self.to_any())
1038 }
1039
1040 /// Cast this to a concrete Python type or pyclass (but not a subclass of it).
1041 ///
1042 /// It is almost always better to use [`cast`](Self::cast) because it accounts for Python
1043 /// subtyping. Use this method only when you do not want to allow subtypes.
1044 ///
1045 /// The advantage of this method over [`cast`](Self::cast) is that it is faster. The
1046 /// implementation of `cast_exact` uses the equivalent of the Python expression `type(self) is
1047 /// U`, whereas `cast` uses `isinstance(self, U)`.
1048 #[inline]
1049 pub fn cast_exact<U>(self) -> Result<Borrowed<'a, 'py, U>, CastError<'a, 'py>>
1050 where
1051 U: PyTypeInfo,
1052 {
1053 fn inner<'a, 'py, U>(
1054 any: Borrowed<'a, 'py, PyAny>,
1055 ) -> Result<Borrowed<'a, 'py, U>, CastError<'a, 'py>>
1056 where
1057 U: PyTypeInfo,
1058 {
1059 if any.is_exact_instance_of::<U>() {
1060 // Safety: is_exact_instance_of is responsible for ensuring that the type is correct
1061 Ok(unsafe { any.cast_unchecked() })
1062 } else {
1063 Err(CastError::new(any, U::classinfo_object(any.py())))
1064 }
1065 }
1066 inner(self.to_any())
1067 }
1068
1069 /// Converts this to a concrete Python type without checking validity.
1070 ///
1071 /// # Safety
1072 /// Callers must ensure that the type is valid or risk type confusion.
1073 #[inline]
1074 pub unsafe fn cast_unchecked<U>(self) -> Borrowed<'a, 'py, U> {
1075 Borrowed(self.0, PhantomData, self.2)
1076 }
1077
1078 /// Provide an immutable borrow of the value `T`.
1079 ///
1080 /// This is available if the class is [`frozen`][macro@crate::pyclass] and [`Sync`].
1081 ///
1082 /// # Examples
1083 ///
1084 /// ```
1085 /// use std::sync::atomic::{AtomicUsize, Ordering};
1086 /// # use pyo3::prelude::*;
1087 ///
1088 /// #[pyclass(frozen)]
1089 /// struct FrozenCounter {
1090 /// value: AtomicUsize,
1091 /// }
1092 ///
1093 /// Python::attach(|py| {
1094 /// let counter = FrozenCounter { value: AtomicUsize::new(0) };
1095 ///
1096 /// let py_counter = Bound::new(py, counter).unwrap();
1097 ///
1098 /// let py_counter_borrowed = py_counter.as_borrowed();
1099 ///
1100 /// py_counter_borrowed.get().value.fetch_add(1, Ordering::Relaxed);
1101 /// });
1102 /// ```
1103 #[inline]
1104 pub fn get(self) -> &'a T
1105 where
1106 T: PyClass<Frozen = True> + Sync,
1107 {
1108 // Safety: The class itself is frozen and `Sync`
1109 unsafe { &*self.get_class_object().get_ptr() }
1110 }
1111}
1112
1113impl<'a, T: PyClass> Borrowed<'a, '_, T> {
1114 /// Get a view on the underlying `PyClass` contents.
1115 #[inline]
1116 pub(crate) fn get_class_object(self) -> &'a <T as PyClassImpl>::Layout {
1117 // Safety: Borrowed<'a, '_, T: PyClass> is known to contain an object
1118 // which is laid out in memory as a PyClassObject<T> and lives for at
1119 // least 'a.
1120 unsafe { &*self.as_ptr().cast::<<T as PyClassImpl>::Layout>() }
1121 }
1122}
1123
1124impl<'a, 'py> Borrowed<'a, 'py, PyAny> {
1125 /// Constructs a new `Borrowed<'a, 'py, PyAny>` from a pointer. Panics if `ptr` is null.
1126 ///
1127 /// Prefer to use [`Bound::from_borrowed_ptr`], as that avoids the major safety risk
1128 /// of needing to precisely define the lifetime `'a` for which the borrow is valid.
1129 ///
1130 /// # Safety
1131 ///
1132 /// - `ptr` must be a valid pointer to a Python object (or null, which will cause a panic)
1133 /// - similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
1134 /// the caller and it is the caller's responsibility to ensure that the reference this is
1135 /// derived from is valid for the lifetime `'a`.
1136 ///
1137 /// # Panics
1138 ///
1139 /// Panics if `ptr` is null
1140 #[inline]
1141 #[track_caller]
1142 pub unsafe fn from_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
1143 let non_null = NonNull::new(ptr).unwrap_or_else(|| panic_on_null(py));
1144 // SAFETY: caller has upheld the safety contract
1145 unsafe { Self::from_non_null(py, non_null) }
1146 }
1147
1148 /// Constructs a new `Borrowed<'a, 'py, PyAny>` from a pointer. Returns `None` if `ptr` is null.
1149 ///
1150 /// Prefer to use [`Bound::from_borrowed_ptr_or_opt`], as that avoids the major safety risk
1151 /// of needing to precisely define the lifetime `'a` for which the borrow is valid.
1152 ///
1153 /// # Safety
1154 ///
1155 /// - `ptr` must be a valid pointer to a Python object, or null
1156 /// - similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
1157 /// the caller and it is the caller's responsibility to ensure that the reference this is
1158 /// derived from is valid for the lifetime `'a`.
1159 #[inline]
1160 pub unsafe fn from_ptr_or_opt(py: Python<'py>, ptr: *mut ffi::PyObject) -> Option<Self> {
1161 NonNull::new(ptr).map(|ptr|
1162 // SAFETY: caller has upheld the safety contract
1163 unsafe { Self::from_non_null(py, ptr) })
1164 }
1165
1166 /// Constructs a new `Borrowed<'a, 'py, PyAny>` from a pointer. Returns an `Err` by calling `PyErr::fetch`
1167 /// if `ptr` is null.
1168 ///
1169 /// Prefer to use [`Bound::from_borrowed_ptr_or_err`], as that avoids the major safety risk
1170 /// of needing to precisely define the lifetime `'a` for which the borrow is valid.
1171 ///
1172 /// # Safety
1173 ///
1174 /// - `ptr` must be a valid pointer to a Python object, or null
1175 /// - similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
1176 /// the caller and it is the caller's responsibility to ensure that the reference this is
1177 /// derived from is valid for the lifetime `'a`.
1178 #[inline]
1179 pub unsafe fn from_ptr_or_err(py: Python<'py>, ptr: *mut ffi::PyObject) -> PyResult<Self> {
1180 NonNull::new(ptr).map_or_else(
1181 || Err(PyErr::fetch(py)),
1182 |ptr| {
1183 Ok(
1184 // SAFETY: ptr is known to be non-null, caller has upheld the safety contract
1185 unsafe { Self::from_non_null(py, ptr) },
1186 )
1187 },
1188 )
1189 }
1190
1191 /// # Safety
1192 ///
1193 /// - `ptr` must be a valid pointer to a Python object. It must not be null.
1194 /// - similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
1195 /// the caller and it is the caller's responsibility to ensure that the reference this is
1196 /// derived from is valid for the lifetime `'a`.
1197 #[inline]
1198 pub(crate) unsafe fn from_ptr_unchecked(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
1199 // SAFETY: caller has upheld the safety contract
1200 unsafe { Self::from_non_null(py, NonNull::new_unchecked(ptr)) }
1201 }
1202
1203 /// # Safety
1204 ///
1205 /// - `ptr` must be a valid pointer to a Python object.
1206 /// - similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
1207 /// the caller and it is the caller's responsibility to ensure that the reference this is
1208 /// derived from is valid for the lifetime `'a`.
1209 #[inline]
1210 pub(crate) unsafe fn from_non_null(py: Python<'py>, ptr: NonNull<ffi::PyObject>) -> Self {
1211 Self(ptr, PhantomData, py)
1212 }
1213}
1214
1215impl<'a, 'py, T> From<&'a Bound<'py, T>> for Borrowed<'a, 'py, T> {
1216 /// Create borrow on a Bound
1217 #[inline]
1218 fn from(instance: &'a Bound<'py, T>) -> Self {
1219 instance.as_borrowed()
1220 }
1221}
1222
1223impl<T> AsRef<Py<PyAny>> for Borrowed<'_, '_, T> {
1224 #[inline]
1225 fn as_ref(&self) -> &Py<PyAny> {
1226 self.as_any().as_unbound()
1227 }
1228}
1229
1230impl<T> std::fmt::Debug for Borrowed<'_, '_, T> {
1231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1232 Bound::fmt(self, f)
1233 }
1234}
1235
1236impl<'py, T> Deref for Borrowed<'_, 'py, T> {
1237 type Target = Bound<'py, T>;
1238
1239 #[inline]
1240 fn deref(&self) -> &Bound<'py, T> {
1241 // SAFETY: self.0 is a valid object of type T
1242 unsafe { Bound::ref_from_non_null(self.2, &self.0).cast_unchecked() }
1243 }
1244}
1245
1246impl<T> Clone for Borrowed<'_, '_, T> {
1247 #[inline]
1248 fn clone(&self) -> Self {
1249 *self
1250 }
1251}
1252
1253impl<T> Copy for Borrowed<'_, '_, T> {}
1254
1255impl<'a, 'py, T> BoundObject<'py, T> for Borrowed<'a, 'py, T> {
1256 type Any = Borrowed<'a, 'py, PyAny>;
1257
1258 fn as_borrowed(&self) -> Borrowed<'a, 'py, T> {
1259 *self
1260 }
1261
1262 fn into_bound(self) -> Bound<'py, T> {
1263 (*self).to_owned()
1264 }
1265
1266 fn into_any(self) -> Self::Any {
1267 self.to_any()
1268 }
1269
1270 fn into_ptr(self) -> *mut ffi::PyObject {
1271 (*self).to_owned().into_ptr()
1272 }
1273
1274 fn as_ptr(&self) -> *mut ffi::PyObject {
1275 (*self).as_ptr()
1276 }
1277
1278 fn unbind(self) -> Py<T> {
1279 (*self).to_owned().unbind()
1280 }
1281}
1282
1283/// A reference to an object allocated on the Python heap.
1284///
1285/// To access the contained data use the following methods:
1286/// - [`Py::bind`] or [`Py::into_bound`], to bind the reference to the lifetime of the [`Python<'py>`] token.
1287/// - [`Py::borrow`], [`Py::try_borrow`], [`Py::borrow_mut`], or [`Py::try_borrow_mut`],
1288///
1289/// to get a (mutable) reference to a contained pyclass, using a scheme similar to std's [`RefCell`].
1290/// See the
1291#[doc = concat!("[guide entry](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#bound-and-interior-mutability)")]
1292/// for more information.
1293/// - You can call methods directly on `Py` with [`Py::call`], [`Py::call_method`] and friends.
1294///
1295/// These require passing in the [`Python<'py>`](crate::Python) token but are otherwise similar to the corresponding
1296/// methods on [`PyAny`].
1297///
1298/// # Example: Storing Python objects in `#[pyclass]` structs
1299///
1300/// Usually `Bound<'py, T>` is recommended for interacting with Python objects as its lifetime `'py`
1301/// proves the thread is attached to the Python interpreter and that enables many operations to be
1302/// done as efficiently as possible.
1303///
1304/// However, `#[pyclass]` structs cannot carry a lifetime, so `Py<T>` is the only way to store
1305/// a Python object in a `#[pyclass]` struct.
1306///
1307/// For example, this won't compile:
1308///
1309/// ```compile_fail
1310/// # use pyo3::prelude::*;
1311/// # use pyo3::types::PyDict;
1312/// #
1313/// #[pyclass]
1314/// struct Foo<'py> {
1315/// inner: Bound<'py, PyDict>,
1316/// }
1317///
1318/// impl Foo {
1319/// fn new() -> Foo {
1320/// let foo = Python::attach(|py| {
1321/// // `py` will only last for this scope.
1322///
1323/// // `Bound<'py, PyDict>` inherits the Python token lifetime from `py`
1324/// // and so won't be able to outlive this closure.
1325/// let dict: Bound<'_, PyDict> = PyDict::new(py);
1326///
1327/// // because `Foo` contains `dict` its lifetime
1328/// // is now also tied to `py`.
1329/// Foo { inner: dict }
1330/// });
1331/// // Foo is no longer valid.
1332/// // Returning it from this function is a 💥 compiler error 💥
1333/// foo
1334/// }
1335/// }
1336/// ```
1337///
1338/// [`Py`]`<T>` can be used to get around this by removing the lifetime from `dict` and with it the proof of attachment.
1339///
1340/// ```rust
1341/// use pyo3::prelude::*;
1342/// use pyo3::types::PyDict;
1343///
1344/// #[pyclass]
1345/// struct Foo {
1346/// inner: Py<PyDict>,
1347/// }
1348///
1349/// #[pymethods]
1350/// impl Foo {
1351/// #[new]
1352/// fn __new__() -> Foo {
1353/// Python::attach(|py| {
1354/// let dict: Py<PyDict> = PyDict::new(py).unbind();
1355/// Foo { inner: dict }
1356/// })
1357/// }
1358/// }
1359/// #
1360/// # fn main() -> PyResult<()> {
1361/// # Python::attach(|py| {
1362/// # let m = pyo3::types::PyModule::new(py, "test")?;
1363/// # m.add_class::<Foo>()?;
1364/// #
1365/// # let foo: Bound<'_, Foo> = m.getattr("Foo")?.call0()?.cast_into()?;
1366/// # let dict = &foo.borrow().inner;
1367/// # let dict: &Bound<'_, PyDict> = dict.bind(py);
1368/// #
1369/// # Ok(())
1370/// # })
1371/// # }
1372/// ```
1373///
1374/// This can also be done with other pyclasses:
1375/// ```rust
1376/// use pyo3::prelude::*;
1377///
1378/// #[pyclass]
1379/// struct Bar {/* ... */}
1380///
1381/// #[pyclass]
1382/// struct Foo {
1383/// inner: Py<Bar>,
1384/// }
1385///
1386/// #[pymethods]
1387/// impl Foo {
1388/// #[new]
1389/// fn __new__() -> PyResult<Foo> {
1390/// Python::attach(|py| {
1391/// let bar: Py<Bar> = Py::new(py, Bar {})?;
1392/// Ok(Foo { inner: bar })
1393/// })
1394/// }
1395/// }
1396/// #
1397/// # fn main() -> PyResult<()> {
1398/// # Python::attach(|py| {
1399/// # let m = pyo3::types::PyModule::new(py, "test")?;
1400/// # m.add_class::<Foo>()?;
1401/// #
1402/// # let foo: Bound<'_, Foo> = m.getattr("Foo")?.call0()?.cast_into()?;
1403/// # let bar = &foo.borrow().inner;
1404/// # let bar: &Bar = &*bar.borrow(py);
1405/// #
1406/// # Ok(())
1407/// # })
1408/// # }
1409/// ```
1410///
1411/// # Example: Shared ownership of Python objects
1412///
1413/// `Py<T>` can be used to share ownership of a Python object, similar to std's [`Rc`]`<T>`.
1414/// As with [`Rc`]`<T>`, cloning it increases its reference count rather than duplicating
1415/// the underlying object.
1416///
1417/// This can be done using either [`Py::clone_ref`] or [`Py<T>`]'s [`Clone`] trait implementation.
1418/// [`Py::clone_ref`] is recommended; the [`Clone`] implementation will panic if the thread
1419/// is not attached to the Python interpreter (and is gated behind the `py-clone` feature flag).
1420///
1421/// ```rust
1422/// use pyo3::prelude::*;
1423/// use pyo3::types::PyDict;
1424///
1425/// # fn main() {
1426/// Python::attach(|py| {
1427/// let first: Py<PyDict> = PyDict::new(py).unbind();
1428///
1429/// // All of these are valid syntax
1430/// let second = Py::clone_ref(&first, py);
1431/// let third = first.clone_ref(py);
1432/// #[cfg(feature = "py-clone")]
1433/// let fourth = Py::clone(&first);
1434/// #[cfg(feature = "py-clone")]
1435/// let fifth = first.clone();
1436///
1437/// // Disposing of our original `Py<PyDict>` just decrements the reference count.
1438/// drop(first);
1439///
1440/// // They all point to the same object
1441/// assert!(second.is(&third));
1442/// #[cfg(feature = "py-clone")]
1443/// assert!(fourth.is(&fifth));
1444/// #[cfg(feature = "py-clone")]
1445/// assert!(second.is(&fourth));
1446/// });
1447/// # }
1448/// ```
1449///
1450/// # Preventing reference cycles
1451///
1452/// It is easy to accidentally create reference cycles using [`Py`]`<T>`.
1453/// The Python interpreter can break these reference cycles within pyclasses if they
1454/// [integrate with the garbage collector][gc]. If your pyclass contains other Python
1455/// objects you should implement it to avoid leaking memory.
1456///
1457/// # A note on Python reference counts
1458///
1459/// Dropping a [`Py`]`<T>` will eventually decrease Python's reference count
1460/// of the pointed-to variable, allowing Python's garbage collector to free
1461/// the associated memory, but this may not happen immediately. This is
1462/// because a [`Py`]`<T>` can be dropped at any time, but the Python reference
1463/// count can only be modified when the thread is attached to the Python interpreter.
1464///
1465/// If a [`Py`]`<T>` is dropped while its thread is attached to the Python interpreter
1466/// then the Python reference count will be decreased immediately.
1467/// Otherwise, the reference count will be decreased the next time the thread is
1468/// attached to the interpreter.
1469///
1470/// If you have a [`Python<'py>`] token, [`Py::drop_ref`] will decrease
1471/// the Python reference count immediately and will execute slightly faster than
1472/// relying on implicit [`Drop`]s.
1473///
1474/// # A note on `Send` and `Sync`
1475///
1476/// [`Py<T>`] implements [`Send`] and [`Sync`], as Python allows objects to be freely
1477/// shared between threads.
1478///
1479/// [`Rc`]: std::rc::Rc
1480/// [`RefCell`]: std::cell::RefCell
1481/// [gc]: https://pyo3.rs/main/class/protocols.html#garbage-collector-integration
1482#[repr(transparent)]
1483pub struct Py<T>(NonNull<ffi::PyObject>, PhantomData<T>);
1484
1485#[cfg(feature = "nightly")]
1486unsafe impl<T> crate::marker::Ungil for Py<T> {}
1487// SAFETY: Python objects can be sent between threads
1488unsafe impl<T> Send for Py<T> {}
1489// SAFETY: Python objects can be shared between threads. Any thread safety is
1490// implemented in the object type itself; `Py<T>` only allows synchronized access
1491// to `T` through:
1492// - `borrow`/`borrow_mut` for `#[pyclass]` types
1493// - `get()` for frozen `#[pyclass(frozen)]` types
1494// - Python native types have their own thread safety mechanisms
1495unsafe impl<T> Sync for Py<T> {}
1496
1497impl<T> Py<T>
1498where
1499 T: PyClass,
1500{
1501 /// Creates a new instance `Py<T>` of a `#[pyclass]` on the Python heap.
1502 ///
1503 /// # Examples
1504 ///
1505 /// ```rust
1506 /// use pyo3::prelude::*;
1507 ///
1508 /// #[pyclass]
1509 /// struct Foo {/* fields omitted */}
1510 ///
1511 /// # fn main() -> PyResult<()> {
1512 /// let foo = Python::attach(|py| -> PyResult<_> {
1513 /// let foo: Py<Foo> = Py::new(py, Foo {})?;
1514 /// Ok(foo)
1515 /// })?;
1516 /// # Python::attach(move |_py| drop(foo));
1517 /// # Ok(())
1518 /// # }
1519 /// ```
1520 pub fn new(py: Python<'_>, value: impl Into<PyClassInitializer<T>>) -> PyResult<Py<T>> {
1521 Bound::new(py, value).map(Bound::unbind)
1522 }
1523}
1524
1525impl<T> Py<T> {
1526 /// Returns the raw FFI pointer represented by self.
1527 ///
1528 /// # Safety
1529 ///
1530 /// Callers are responsible for ensuring that the pointer does not outlive self.
1531 ///
1532 /// The reference is borrowed; callers should not decrease the reference count
1533 /// when they are finished with the pointer.
1534 #[inline]
1535 pub fn as_ptr(&self) -> *mut ffi::PyObject {
1536 self.0.as_ptr()
1537 }
1538
1539 /// Returns an owned raw FFI pointer represented by self.
1540 ///
1541 /// # Safety
1542 ///
1543 /// The reference is owned; when finished the caller should either transfer ownership
1544 /// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
1545 #[inline]
1546 pub fn into_ptr(self) -> *mut ffi::PyObject {
1547 ManuallyDrop::new(self).0.as_ptr()
1548 }
1549
1550 /// Helper to cast to `Py<PyAny>`.
1551 #[inline]
1552 pub fn as_any(&self) -> &Py<PyAny> {
1553 let ptr = NonNull::from(self).cast();
1554 // Safety: all Py<T> have the same memory layout, and all Py<T> are valid
1555 // Py<PyAny>, so pointer casting is valid.
1556 unsafe { ptr.as_ref() }
1557 }
1558
1559 /// Helper to cast to `Py<PyAny>`, transferring ownership.
1560 #[inline]
1561 pub fn into_any(self) -> Py<PyAny> {
1562 // Safety: all Py<T> are valid Py<PyAny>
1563 unsafe { Py::from_non_null(ManuallyDrop::new(self).0) }
1564 }
1565}
1566
1567impl<T> Py<T>
1568where
1569 T: PyClass,
1570{
1571 /// Immutably borrows the value `T`.
1572 ///
1573 /// This borrow lasts while the returned [`PyRef`] exists.
1574 /// Multiple immutable borrows can be taken out at the same time.
1575 ///
1576 /// For frozen classes, the simpler [`get`][Self::get] is available.
1577 ///
1578 /// Equivalent to `self.bind(py).borrow()` - see [`Bound::borrow`].
1579 ///
1580 /// # Examples
1581 ///
1582 /// ```rust
1583 /// # use pyo3::prelude::*;
1584 /// #
1585 /// #[pyclass]
1586 /// struct Foo {
1587 /// inner: u8,
1588 /// }
1589 ///
1590 /// # fn main() -> PyResult<()> {
1591 /// Python::attach(|py| -> PyResult<()> {
1592 /// let foo: Py<Foo> = Py::new(py, Foo { inner: 73 })?;
1593 /// let inner: &u8 = &foo.borrow(py).inner;
1594 ///
1595 /// assert_eq!(*inner, 73);
1596 /// Ok(())
1597 /// })?;
1598 /// # Ok(())
1599 /// # }
1600 /// ```
1601 ///
1602 /// # Panics
1603 ///
1604 /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
1605 /// [`try_borrow`](#method.try_borrow).
1606 #[inline]
1607 #[track_caller]
1608 pub fn borrow<'py>(&'py self, py: Python<'py>) -> PyRef<'py, T> {
1609 self.bind(py).borrow()
1610 }
1611
1612 /// Mutably borrows the value `T`.
1613 ///
1614 /// This borrow lasts while the returned [`PyRefMut`] exists.
1615 ///
1616 /// Equivalent to `self.bind(py).borrow_mut()` - see [`Bound::borrow_mut`].
1617 ///
1618 /// # Examples
1619 ///
1620 /// ```
1621 /// # use pyo3::prelude::*;
1622 /// #
1623 /// #[pyclass]
1624 /// struct Foo {
1625 /// inner: u8,
1626 /// }
1627 ///
1628 /// # fn main() -> PyResult<()> {
1629 /// Python::attach(|py| -> PyResult<()> {
1630 /// let foo: Py<Foo> = Py::new(py, Foo { inner: 73 })?;
1631 /// foo.borrow_mut(py).inner = 35;
1632 ///
1633 /// assert_eq!(foo.borrow(py).inner, 35);
1634 /// Ok(())
1635 /// })?;
1636 /// # Ok(())
1637 /// # }
1638 /// ```
1639 ///
1640 /// # Panics
1641 /// Panics if the value is currently borrowed. For a non-panicking variant, use
1642 /// [`try_borrow_mut`](#method.try_borrow_mut).
1643 #[inline]
1644 #[track_caller]
1645 pub fn borrow_mut<'py>(&'py self, py: Python<'py>) -> PyRefMut<'py, T>
1646 where
1647 T: PyClass<Frozen = False>,
1648 {
1649 self.bind(py).borrow_mut()
1650 }
1651
1652 /// Attempts to immutably borrow the value `T`, returning an error if the value is currently mutably borrowed.
1653 ///
1654 /// The borrow lasts while the returned [`PyRef`] exists.
1655 ///
1656 /// This is the non-panicking variant of [`borrow`](#method.borrow).
1657 ///
1658 /// For frozen classes, the simpler [`get`][Self::get] is available.
1659 ///
1660 /// Equivalent to `self.bind(py).try_borrow()` - see [`Bound::try_borrow`].
1661 #[inline]
1662 pub fn try_borrow<'py>(&'py self, py: Python<'py>) -> Result<PyRef<'py, T>, PyBorrowError> {
1663 self.bind(py).try_borrow()
1664 }
1665
1666 /// Attempts to mutably borrow the value `T`, returning an error if the value is currently borrowed.
1667 ///
1668 /// The borrow lasts while the returned [`PyRefMut`] exists.
1669 ///
1670 /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
1671 ///
1672 /// Equivalent to `self.bind(py).try_borrow_mut()` - see [`Bound::try_borrow_mut`].
1673 #[inline]
1674 pub fn try_borrow_mut<'py>(
1675 &'py self,
1676 py: Python<'py>,
1677 ) -> Result<PyRefMut<'py, T>, PyBorrowMutError>
1678 where
1679 T: PyClass<Frozen = False>,
1680 {
1681 self.bind(py).try_borrow_mut()
1682 }
1683
1684 /// Provide an immutable borrow of the value `T`.
1685 ///
1686 /// This is available if the class is [`frozen`][macro@crate::pyclass] and [`Sync`], and
1687 /// does not require attaching to the Python interpreter.
1688 ///
1689 /// # Examples
1690 ///
1691 /// ```
1692 /// use std::sync::atomic::{AtomicUsize, Ordering};
1693 /// # use pyo3::prelude::*;
1694 ///
1695 /// #[pyclass(frozen)]
1696 /// struct FrozenCounter {
1697 /// value: AtomicUsize,
1698 /// }
1699 ///
1700 /// let cell = Python::attach(|py| {
1701 /// let counter = FrozenCounter { value: AtomicUsize::new(0) };
1702 ///
1703 /// Py::new(py, counter).unwrap()
1704 /// });
1705 ///
1706 /// cell.get().value.fetch_add(1, Ordering::Relaxed);
1707 /// # Python::attach(move |_py| drop(cell));
1708 /// ```
1709 #[inline]
1710 pub fn get(&self) -> &T
1711 where
1712 T: PyClass<Frozen = True> + Sync,
1713 {
1714 // Safety: The class itself is frozen and `Sync`
1715 unsafe { &*self.get_class_object().get_ptr() }
1716 }
1717
1718 /// Get a view on the underlying `PyClass` contents.
1719 #[inline]
1720 pub(crate) fn get_class_object(&self) -> &<T as PyClassImpl>::Layout {
1721 let class_object = self.as_ptr().cast::<<T as PyClassImpl>::Layout>();
1722 // Safety: Bound<T: PyClass> is known to contain an object which is laid out in memory as a
1723 // <T as PyClassImpl>::Layout object
1724 unsafe { &*class_object }
1725 }
1726}
1727
1728impl<T> Py<T> {
1729 /// Attaches this `Py` to the given Python context, allowing access to further Python APIs.
1730 #[inline]
1731 pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
1732 // SAFETY: `Bound` has the same layout as `Py`
1733 unsafe { NonNull::from(self).cast().as_ref() }
1734 }
1735
1736 /// Same as `bind` but takes ownership of `self`.
1737 #[inline]
1738 pub fn into_bound(self, py: Python<'_>) -> Bound<'_, T> {
1739 Bound(py, ManuallyDrop::new(self))
1740 }
1741
1742 /// Same as `bind` but produces a `Borrowed<T>` instead of a `Bound<T>`.
1743 #[inline]
1744 pub fn bind_borrowed<'a, 'py>(&'a self, py: Python<'py>) -> Borrowed<'a, 'py, T> {
1745 // NB cannot go via `self.bind(py)` because the `&Bound` would imply `'a: 'py`
1746
1747 // SAFETY: `self.0` is a valid pointer to a PyObject for the lifetime 'a
1748 let borrowed = unsafe { Borrowed::from_non_null(py, self.0) };
1749 // SAFETY: object is known to be of type T
1750 unsafe { borrowed.cast_unchecked() }
1751 }
1752
1753 /// Returns whether `self` and `other` point to the same object. To compare
1754 /// the equality of two objects (the `==` operator), use [`eq`](PyAnyMethods::eq).
1755 ///
1756 /// This is equivalent to the Python expression `self is other`.
1757 #[inline]
1758 pub fn is<U: AsRef<Py<PyAny>>>(&self, o: U) -> bool {
1759 ptr::eq(self.as_ptr(), o.as_ref().as_ptr())
1760 }
1761
1762 /// Gets the reference count of the `ffi::PyObject` pointer.
1763 #[inline]
1764 #[deprecated(
1765 since = "0.29.0",
1766 note = "use `pyo3::ffi::Py_REFCNT(obj.as_ptr())` instead"
1767 )]
1768 pub fn get_refcnt(&self, py: Python<'_>) -> isize {
1769 self._get_refcnt(py)
1770 }
1771
1772 #[inline]
1773 pub(crate) fn _get_refcnt(&self, _py: Python<'_>) -> isize {
1774 // SAFETY: Self is a valid pointer to a PyObject
1775 unsafe { ffi::Py_REFCNT(self.0.as_ptr()) }
1776 }
1777
1778 /// Makes a clone of `self`.
1779 ///
1780 /// This creates another pointer to the same object, increasing its reference count.
1781 ///
1782 /// You should prefer using this method over [`Clone`].
1783 ///
1784 /// # Examples
1785 ///
1786 /// ```rust
1787 /// use pyo3::prelude::*;
1788 /// use pyo3::types::PyDict;
1789 ///
1790 /// # fn main() {
1791 /// Python::attach(|py| {
1792 /// let first: Py<PyDict> = PyDict::new(py).unbind();
1793 /// let second = Py::clone_ref(&first, py);
1794 ///
1795 /// // Both point to the same object
1796 /// assert!(first.is(&second));
1797 /// });
1798 /// # }
1799 /// ```
1800 #[inline]
1801 pub fn clone_ref(&self, _py: Python<'_>) -> Py<T> {
1802 // NB cannot use self.bind(py) because Bound::clone is implemented using Py::clone_ref
1803 // (infinite recursion)
1804
1805 // SAFETY: object is known to be valid
1806 unsafe { ffi::Py_INCREF(self.0.as_ptr()) };
1807 // SAFETY: newly created reference is transferred to the new Py<T>
1808 unsafe { Self::from_non_null(self.0) }
1809 }
1810
1811 /// Drops `self` and immediately decreases its reference count.
1812 ///
1813 /// This method is a micro-optimisation over [`Drop`] if you happen to have a [`Python<'py>`]
1814 /// token to prove attachment to the Python interpreter.
1815 ///
1816 /// Note that if you are using [`Bound`], you do not need to use [`Self::drop_ref`] since
1817 /// [`Bound`] guarantees that the thread is attached to the interpreter.
1818 ///
1819 /// # Examples
1820 ///
1821 /// ```rust
1822 /// use pyo3::prelude::*;
1823 /// use pyo3::types::PyDict;
1824 ///
1825 /// # fn main() {
1826 /// Python::attach(|py| {
1827 /// let object: Py<PyDict> = PyDict::new(py).unbind();
1828 ///
1829 /// // some usage of object
1830 ///
1831 /// object.drop_ref(py);
1832 /// });
1833 /// # }
1834 /// ```
1835 #[inline]
1836 pub fn drop_ref(self, py: Python<'_>) {
1837 let _ = self.into_bound(py);
1838 }
1839
1840 /// Returns whether the object is considered to be None.
1841 ///
1842 /// This is equivalent to the Python expression `self is None`.
1843 pub fn is_none(&self, py: Python<'_>) -> bool {
1844 self.bind(py).as_any().is_none()
1845 }
1846
1847 /// Returns whether the object is considered to be true.
1848 ///
1849 /// This applies truth value testing equivalent to the Python expression `bool(self)`.
1850 pub fn is_truthy(&self, py: Python<'_>) -> PyResult<bool> {
1851 self.bind(py).as_any().is_truthy()
1852 }
1853
1854 /// Extracts some type from the Python object.
1855 ///
1856 /// This is a wrapper function around `FromPyObject::extract()`.
1857 pub fn extract<'a, 'py, D>(&'a self, py: Python<'py>) -> Result<D, D::Error>
1858 where
1859 D: FromPyObject<'a, 'py>,
1860 {
1861 self.bind_borrowed(py).extract()
1862 }
1863
1864 /// Retrieves an attribute value.
1865 ///
1866 /// This is equivalent to the Python expression `self.attr_name`.
1867 ///
1868 /// If calling this method becomes performance-critical, the [`intern!`](crate::intern) macro
1869 /// can be used to intern `attr_name`, thereby avoiding repeated temporary allocations of
1870 /// Python strings.
1871 ///
1872 /// # Example: `intern!`ing the attribute name
1873 ///
1874 /// ```
1875 /// # use pyo3::{prelude::*, intern};
1876 /// #
1877 /// #[pyfunction]
1878 /// fn version(sys: Py<PyModule>, py: Python<'_>) -> PyResult<Py<PyAny>> {
1879 /// sys.getattr(py, intern!(py, "version"))
1880 /// }
1881 /// #
1882 /// # Python::attach(|py| {
1883 /// # let sys = py.import("sys").unwrap().unbind();
1884 /// # version(sys, py).unwrap();
1885 /// # });
1886 /// ```
1887 pub fn getattr<'py, N>(&self, py: Python<'py>, attr_name: N) -> PyResult<Py<PyAny>>
1888 where
1889 N: IntoPyObject<'py, Target = PyString>,
1890 {
1891 self.bind(py).as_any().getattr(attr_name).map(Bound::unbind)
1892 }
1893
1894 /// Sets an attribute value.
1895 ///
1896 /// This is equivalent to the Python expression `self.attr_name = value`.
1897 ///
1898 /// To avoid repeated temporary allocations of Python strings, the [`intern!`](crate::intern)
1899 /// macro can be used to intern `attr_name`.
1900 ///
1901 /// # Example: `intern!`ing the attribute name
1902 ///
1903 /// ```
1904 /// # use pyo3::{intern, pyfunction, types::PyModule, IntoPyObjectExt, Py, PyAny, Python, PyResult};
1905 /// #
1906 /// #[pyfunction]
1907 /// fn set_answer(ob: Py<PyAny>, py: Python<'_>) -> PyResult<()> {
1908 /// ob.setattr(py, intern!(py, "answer"), 42)
1909 /// }
1910 /// #
1911 /// # Python::attach(|py| {
1912 /// # let ob = PyModule::new(py, "empty").unwrap().into_py_any(py).unwrap();
1913 /// # set_answer(ob, py).unwrap();
1914 /// # });
1915 /// ```
1916 pub fn setattr<'py, N, V>(&self, py: Python<'py>, attr_name: N, value: V) -> PyResult<()>
1917 where
1918 N: IntoPyObject<'py, Target = PyString>,
1919 V: IntoPyObject<'py>,
1920 {
1921 self.bind(py).as_any().setattr(attr_name, value)
1922 }
1923
1924 /// Calls the object.
1925 ///
1926 /// This is equivalent to the Python expression `self(*args, **kwargs)`.
1927 pub fn call<'py, A>(
1928 &self,
1929 py: Python<'py>,
1930 args: A,
1931 kwargs: Option<&Bound<'py, PyDict>>,
1932 ) -> PyResult<Py<PyAny>>
1933 where
1934 A: PyCallArgs<'py>,
1935 {
1936 self.bind(py).as_any().call(args, kwargs).map(Bound::unbind)
1937 }
1938
1939 /// Calls the object with only positional arguments.
1940 ///
1941 /// This is equivalent to the Python expression `self(*args)`.
1942 pub fn call1<'py, A>(&self, py: Python<'py>, args: A) -> PyResult<Py<PyAny>>
1943 where
1944 A: PyCallArgs<'py>,
1945 {
1946 self.bind(py).as_any().call1(args).map(Bound::unbind)
1947 }
1948
1949 /// Calls the object without arguments.
1950 ///
1951 /// This is equivalent to the Python expression `self()`.
1952 pub fn call0(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
1953 self.bind(py).as_any().call0().map(Bound::unbind)
1954 }
1955
1956 /// Calls a method on the object.
1957 ///
1958 /// This is equivalent to the Python expression `self.name(*args, **kwargs)`.
1959 ///
1960 /// To avoid repeated temporary allocations of Python strings, the [`intern!`](crate::intern)
1961 /// macro can be used to intern `name`.
1962 pub fn call_method<'py, N, A>(
1963 &self,
1964 py: Python<'py>,
1965 name: N,
1966 args: A,
1967 kwargs: Option<&Bound<'py, PyDict>>,
1968 ) -> PyResult<Py<PyAny>>
1969 where
1970 N: IntoPyObject<'py, Target = PyString>,
1971 A: PyCallArgs<'py>,
1972 {
1973 self.bind(py)
1974 .as_any()
1975 .call_method(name, args, kwargs)
1976 .map(Bound::unbind)
1977 }
1978
1979 /// Calls a method on the object with only positional arguments.
1980 ///
1981 /// This is equivalent to the Python expression `self.name(*args)`.
1982 ///
1983 /// To avoid repeated temporary allocations of Python strings, the [`intern!`](crate::intern)
1984 /// macro can be used to intern `name`.
1985 pub fn call_method1<'py, N, A>(&self, py: Python<'py>, name: N, args: A) -> PyResult<Py<PyAny>>
1986 where
1987 N: IntoPyObject<'py, Target = PyString>,
1988 A: PyCallArgs<'py>,
1989 {
1990 self.bind(py)
1991 .as_any()
1992 .call_method1(name, args)
1993 .map(Bound::unbind)
1994 }
1995
1996 /// Calls a method on the object with no arguments.
1997 ///
1998 /// This is equivalent to the Python expression `self.name()`.
1999 ///
2000 /// To avoid repeated temporary allocations of Python strings, the [`intern!`](crate::intern)
2001 /// macro can be used to intern `name`.
2002 pub fn call_method0<'py, N>(&self, py: Python<'py>, name: N) -> PyResult<Py<PyAny>>
2003 where
2004 N: IntoPyObject<'py, Target = PyString>,
2005 {
2006 self.bind(py).as_any().call_method0(name).map(Bound::unbind)
2007 }
2008
2009 /// Create a `Py<T>` instance by taking ownership of the given FFI pointer.
2010 ///
2011 /// # Safety
2012 ///
2013 /// - `ptr` must be a valid pointer to a Python object (or null, which will cause a panic)
2014 /// - `ptr` must be an owned Python reference, as the `Py<T>` will assume ownership
2015 ///
2016 /// # Panics
2017 ///
2018 /// Panics if `ptr` is null.
2019 #[inline]
2020 #[track_caller]
2021 #[deprecated(note = "use `Bound::from_owned_ptr` instead", since = "0.28.0")]
2022 pub unsafe fn from_owned_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py<T> {
2023 match NonNull::new(ptr) {
2024 Some(nonnull_ptr) => {
2025 // SAFETY: caller has upheld the safety contract, ptr is known to be non-null
2026 unsafe { Self::from_non_null(nonnull_ptr) }
2027 }
2028 None => panic_on_null(py),
2029 }
2030 }
2031
2032 /// Create a `Py<T>` instance by taking ownership of the given FFI pointer.
2033 ///
2034 /// If `ptr` is null then the current Python exception is fetched as a [`PyErr`].
2035 ///
2036 /// # Safety
2037 ///
2038 /// - `ptr` must be a valid pointer to a Python object, or null
2039 /// - a non-null `ptr` must be an owned Python reference, as the `Py<T>` will assume ownership
2040 #[inline]
2041 #[deprecated(note = "use `Bound::from_owned_ptr_or_err` instead", since = "0.28.0")]
2042 pub unsafe fn from_owned_ptr_or_err(
2043 py: Python<'_>,
2044 ptr: *mut ffi::PyObject,
2045 ) -> PyResult<Py<T>> {
2046 match NonNull::new(ptr) {
2047 Some(nonnull_ptr) => Ok(
2048 // SAFETY: caller has upheld the safety contract, ptr is known to be non-null
2049 unsafe { Self::from_non_null(nonnull_ptr) },
2050 ),
2051 None => Err(PyErr::fetch(py)),
2052 }
2053 }
2054
2055 /// Create a `Py<T>` instance by taking ownership of the given FFI pointer.
2056 ///
2057 /// If `ptr` is null then `None` is returned.
2058 ///
2059 /// # Safety
2060 ///
2061 /// - `ptr` must be a valid pointer to a Python object, or null
2062 /// - a non-null `ptr` must be an owned Python reference, as the `Py<T>` will assume ownership
2063 #[inline]
2064 #[deprecated(note = "use `Bound::from_owned_ptr_or_opt` instead", since = "0.28.0")]
2065 pub unsafe fn from_owned_ptr_or_opt(_py: Python<'_>, ptr: *mut ffi::PyObject) -> Option<Self> {
2066 NonNull::new(ptr).map(|nonnull_ptr| {
2067 // SAFETY: caller has upheld the safety contract
2068 unsafe { Self::from_non_null(nonnull_ptr) }
2069 })
2070 }
2071
2072 /// Create a `Py<T>` instance by creating a new reference from the given FFI pointer.
2073 ///
2074 /// # Safety
2075 /// `ptr` must be a pointer to a Python object of type T.
2076 ///
2077 /// # Panics
2078 ///
2079 /// Panics if `ptr` is null.
2080 #[inline]
2081 #[track_caller]
2082 #[deprecated(note = "use `Borrowed::from_borrowed_ptr` instead", since = "0.28.0")]
2083 pub unsafe fn from_borrowed_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py<T> {
2084 // SAFETY: caller has upheld the safety contract
2085 #[allow(deprecated)]
2086 unsafe { Self::from_borrowed_ptr_or_opt(py, ptr) }.unwrap_or_else(|| panic_on_null(py))
2087 }
2088
2089 /// Create a `Py<T>` instance by creating a new reference from the given FFI pointer.
2090 ///
2091 /// If `ptr` is null then the current Python exception is fetched as a `PyErr`.
2092 ///
2093 /// # Safety
2094 /// `ptr` must be a pointer to a Python object of type T.
2095 #[inline]
2096 #[deprecated(
2097 note = "use `Borrowed::from_borrowed_ptr_or_err` instead",
2098 since = "0.28.0"
2099 )]
2100 pub unsafe fn from_borrowed_ptr_or_err(
2101 py: Python<'_>,
2102 ptr: *mut ffi::PyObject,
2103 ) -> PyResult<Self> {
2104 // SAFETY: caller has upheld the safety contract
2105 #[allow(deprecated)]
2106 unsafe { Self::from_borrowed_ptr_or_opt(py, ptr) }.ok_or_else(|| PyErr::fetch(py))
2107 }
2108
2109 /// Create a `Py<T>` instance by creating a new reference from the given FFI pointer.
2110 ///
2111 /// If `ptr` is null then `None` is returned.
2112 ///
2113 /// # Safety
2114 /// `ptr` must be a pointer to a Python object of type T, or null.
2115 #[inline]
2116 #[deprecated(
2117 note = "use `Borrowed::from_borrowed_ptr_or_opt` instead",
2118 since = "0.28.0"
2119 )]
2120 pub unsafe fn from_borrowed_ptr_or_opt(
2121 _py: Python<'_>,
2122 ptr: *mut ffi::PyObject,
2123 ) -> Option<Self> {
2124 NonNull::new(ptr).map(|nonnull_ptr| {
2125 // SAFETY: ptr is a valid python object, thread is attached to the interpreter
2126 unsafe { ffi::Py_INCREF(ptr) };
2127 // SAFETY: caller has upheld the safety contract, and object was just made owned
2128 unsafe { Self::from_non_null(nonnull_ptr) }
2129 })
2130 }
2131
2132 /// For internal conversions.
2133 ///
2134 /// # Safety
2135 ///
2136 /// `ptr` must point to an owned Python object type T.
2137 #[inline(always)]
2138 unsafe fn from_non_null(ptr: NonNull<ffi::PyObject>) -> Self {
2139 Self(ptr, PhantomData)
2140 }
2141
2142 /// As with `from_non_null`, while calling incref.
2143 ///
2144 /// # Safety
2145 ///
2146 /// `ptr` must point to a valid Python object type T.
2147 #[inline(always)]
2148 unsafe fn from_borrowed_non_null(_py: Python<'_>, ptr: NonNull<ffi::PyObject>) -> Self {
2149 // SAFETY: caller has upheld the safety contract, thread is attached to the interpreter
2150 unsafe { ffi::Py_INCREF(ptr.as_ptr()) };
2151 // SAFETY: caller has upheld the safety contract
2152 unsafe { Self::from_non_null(ptr) }
2153 }
2154}
2155
2156impl<T> AsRef<Py<PyAny>> for Py<T> {
2157 #[inline]
2158 fn as_ref(&self) -> &Py<PyAny> {
2159 self.as_any()
2160 }
2161}
2162
2163impl<T> std::convert::From<Py<T>> for Py<PyAny>
2164where
2165 T: DerefToPyAny,
2166{
2167 #[inline]
2168 fn from(other: Py<T>) -> Self {
2169 other.into_any()
2170 }
2171}
2172
2173impl<T> std::convert::From<Bound<'_, T>> for Py<PyAny>
2174where
2175 T: DerefToPyAny,
2176{
2177 #[inline]
2178 fn from(other: Bound<'_, T>) -> Self {
2179 other.into_any().unbind()
2180 }
2181}
2182
2183impl<T> std::convert::From<Bound<'_, T>> for Py<T> {
2184 #[inline]
2185 fn from(other: Bound<'_, T>) -> Self {
2186 other.unbind()
2187 }
2188}
2189
2190impl<'py, T> From<&Bound<'py, T>> for Bound<'py, T> {
2191 fn from(value: &Bound<'py, T>) -> Self {
2192 value.clone()
2193 }
2194}
2195
2196impl<T> From<&Bound<'_, T>> for Py<T> {
2197 fn from(value: &Bound<'_, T>) -> Self {
2198 value.clone().unbind()
2199 }
2200}
2201
2202impl<T> std::convert::From<Borrowed<'_, '_, T>> for Py<T> {
2203 fn from(value: Borrowed<'_, '_, T>) -> Self {
2204 value.unbind()
2205 }
2206}
2207
2208impl<'py, T> std::convert::From<PyRef<'py, T>> for Py<T>
2209where
2210 T: PyClass,
2211{
2212 fn from(pyref: PyRef<'py, T>) -> Self {
2213 // SAFETY: PyRef::as_ptr returns a borrowed reference to a valid object of type T
2214 unsafe { Bound::from_borrowed_ptr(pyref.py(), pyref.as_ptr()).cast_into_unchecked() }
2215 .unbind()
2216 }
2217}
2218
2219impl<'py, T> std::convert::From<PyRefMut<'py, T>> for Py<T>
2220where
2221 T: PyClass<Frozen = False>,
2222{
2223 fn from(pyref: PyRefMut<'py, T>) -> Self {
2224 // SAFETY: PyRefMut::as_ptr returns a borrowed reference to a valid object of type T
2225 unsafe { Bound::from_borrowed_ptr(pyref.py(), pyref.as_ptr()).cast_into_unchecked() }
2226 .unbind()
2227 }
2228}
2229
2230/// If the thread is attached to the Python interpreter this increments `self`'s reference count.
2231/// Otherwise, it will panic.
2232///
2233/// Only available if the `py-clone` feature is enabled.
2234#[cfg(feature = "py-clone")]
2235impl<T> Clone for Py<T> {
2236 #[track_caller]
2237 #[inline]
2238 fn clone(&self) -> Self {
2239 #[track_caller]
2240 #[inline]
2241 fn try_incref(obj: NonNull<ffi::PyObject>) {
2242 use crate::internal::state::thread_is_attached;
2243
2244 if thread_is_attached() {
2245 // SAFETY: Py_INCREF is safe to call on a valid Python object if the thread is attached.
2246 unsafe { ffi::Py_INCREF(obj.as_ptr()) }
2247 } else {
2248 incref_failed()
2249 }
2250 }
2251
2252 #[cold]
2253 #[track_caller]
2254 fn incref_failed() -> ! {
2255 panic!("Cannot clone pointer into Python heap without the thread being attached.");
2256 }
2257
2258 try_incref(self.0);
2259
2260 Self(self.0, PhantomData)
2261 }
2262}
2263
2264/// Dropping a `Py` instance decrements the reference count
2265/// on the object by one if the thread is attached to the Python interpreter.
2266///
2267/// Otherwise and by default, this registers the underlying pointer to have its reference count
2268/// decremented the next time PyO3 attaches to the Python interpreter.
2269///
2270/// However, if the `pyo3_disable_reference_pool` conditional compilation flag
2271/// is enabled, it will abort the process.
2272impl<T> Drop for Py<T> {
2273 #[inline]
2274 fn drop(&mut self) {
2275 // non generic inlineable inner function to reduce code bloat
2276 #[inline]
2277 fn inner(obj: NonNull<ffi::PyObject>) {
2278 use crate::internal::state::thread_is_attached;
2279
2280 if thread_is_attached() {
2281 // SAFETY: Py_DECREF is safe to call on a valid Python object if the thread is attached.
2282 unsafe { ffi::Py_DECREF(obj.as_ptr()) }
2283 } else {
2284 drop_slow(obj)
2285 }
2286 }
2287
2288 #[cold]
2289 fn drop_slow(obj: NonNull<ffi::PyObject>) {
2290 // SAFETY: handing ownership of the reference to `register_decref`.
2291 unsafe {
2292 state::register_decref(obj);
2293 }
2294 }
2295
2296 inner(self.0)
2297 }
2298}
2299
2300impl<'a, 'py, T> FromPyObject<'a, 'py> for Py<T>
2301where
2302 T: PyTypeCheck + 'a,
2303{
2304 type Error = CastError<'a, 'py>;
2305
2306 #[cfg(feature = "experimental-inspect")]
2307 const INPUT_TYPE: PyStaticExpr = T::TYPE_HINT;
2308
2309 /// Extracts `Self` from the source `PyObject`.
2310 fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
2311 ob.extract::<Bound<'py, T>>().map(Bound::unbind)
2312 }
2313}
2314
2315impl<'a, 'py, T> FromPyObject<'a, 'py> for Bound<'py, T>
2316where
2317 T: PyTypeCheck + 'a,
2318{
2319 type Error = CastError<'a, 'py>;
2320
2321 #[cfg(feature = "experimental-inspect")]
2322 const INPUT_TYPE: PyStaticExpr = T::TYPE_HINT;
2323
2324 /// Extracts `Self` from the source `PyObject`.
2325 fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
2326 ob.cast().map(Borrowed::to_owned)
2327 }
2328}
2329
2330impl<T> std::fmt::Display for Py<T>
2331where
2332 T: PyTypeInfo,
2333{
2334 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2335 Python::attach(|py| std::fmt::Display::fmt(self.bind(py), f))
2336 }
2337}
2338
2339impl<T> std::fmt::Debug for Py<T> {
2340 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2341 f.debug_tuple("Py").field(&self.0.as_ptr()).finish()
2342 }
2343}
2344
2345impl Py<PyAny> {
2346 /// Downcast this `Py<PyAny>` to a concrete Python type or pyclass.
2347 ///
2348 /// Note that you can often avoid casting yourself by just specifying the desired type in
2349 /// function or method signatures. However, manual casting is sometimes necessary.
2350 ///
2351 /// For extracting a Rust-only type, see [`Py::extract`].
2352 ///
2353 /// # Example: Downcasting to a specific Python object
2354 ///
2355 /// ```rust
2356 /// # #![allow(deprecated)]
2357 /// use pyo3::prelude::*;
2358 /// use pyo3::types::{PyDict, PyList};
2359 ///
2360 /// Python::attach(|py| {
2361 /// let any = PyDict::new(py).into_any().unbind();
2362 ///
2363 /// assert!(any.downcast_bound::<PyDict>(py).is_ok());
2364 /// assert!(any.downcast_bound::<PyList>(py).is_err());
2365 /// });
2366 /// ```
2367 ///
2368 /// # Example: Getting a reference to a pyclass
2369 ///
2370 /// This is useful if you want to mutate a `Py<PyAny>` that might actually be a pyclass.
2371 ///
2372 /// ```rust
2373 /// # #![allow(deprecated)]
2374 /// # fn main() -> Result<(), pyo3::PyErr> {
2375 /// use pyo3::prelude::*;
2376 ///
2377 /// #[pyclass]
2378 /// struct Class {
2379 /// i: i32,
2380 /// }
2381 ///
2382 /// Python::attach(|py| {
2383 /// let class = Py::new(py, Class { i: 0 })?.into_any();
2384 ///
2385 /// let class_bound = class.downcast_bound::<Class>(py)?;
2386 ///
2387 /// class_bound.borrow_mut().i += 1;
2388 ///
2389 /// // Alternatively you can get a `PyRefMut` directly
2390 /// let class_ref: PyRefMut<'_, Class> = class.extract(py)?;
2391 /// assert_eq!(class_ref.i, 1);
2392 /// Ok(())
2393 /// })
2394 /// # }
2395 /// ```
2396 #[deprecated(since = "0.27.0", note = "use `Py::cast_bound` instead")]
2397 #[inline]
2398 #[allow(deprecated)]
2399 pub fn downcast_bound<'py, T>(
2400 &self,
2401 py: Python<'py>,
2402 ) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
2403 where
2404 T: PyTypeCheck,
2405 {
2406 #[allow(deprecated)]
2407 self.bind(py).downcast()
2408 }
2409
2410 /// Casts the `Py<PyAny>` to a concrete Python object type without checking validity.
2411 ///
2412 /// # Safety
2413 ///
2414 /// Callers must ensure that the type is valid or risk type confusion.
2415 #[deprecated(since = "0.27.0", note = "use `Py::cast_bound_unchecked` instead")]
2416 #[inline]
2417 pub unsafe fn downcast_bound_unchecked<'py, T>(&self, py: Python<'py>) -> &Bound<'py, T> {
2418 // SAFETY: caller has upheld the safety contract
2419 unsafe { self.cast_bound_unchecked(py) }
2420 }
2421}
2422
2423impl<T> Py<T> {
2424 /// Cast this `Py<T>` to a concrete Python type or pyclass.
2425 ///
2426 /// Note that you can often avoid casting yourself by just specifying the desired type in
2427 /// function or method signatures. However, manual casting is sometimes necessary.
2428 ///
2429 /// For extracting a Rust-only type, see [`Py::extract`].
2430 ///
2431 /// # Example: Casting to a specific Python object
2432 ///
2433 /// ```rust
2434 /// use pyo3::prelude::*;
2435 /// use pyo3::types::{PyDict, PyList};
2436 ///
2437 /// Python::attach(|py| {
2438 /// let any = PyDict::new(py).into_any().unbind();
2439 ///
2440 /// assert!(any.cast_bound::<PyDict>(py).is_ok());
2441 /// assert!(any.cast_bound::<PyList>(py).is_err());
2442 /// });
2443 /// ```
2444 ///
2445 /// # Example: Getting a reference to a pyclass
2446 ///
2447 /// This is useful if you want to mutate a `Py<PyAny>` that might actually be a pyclass.
2448 ///
2449 /// ```rust
2450 /// # fn main() -> Result<(), pyo3::PyErr> {
2451 /// use pyo3::prelude::*;
2452 ///
2453 /// #[pyclass]
2454 /// struct Class {
2455 /// i: i32,
2456 /// }
2457 ///
2458 /// Python::attach(|py| {
2459 /// let class = Py::new(py, Class { i: 0 })?.into_any();
2460 ///
2461 /// let class_bound = class.cast_bound::<Class>(py)?;
2462 ///
2463 /// class_bound.borrow_mut().i += 1;
2464 ///
2465 /// // Alternatively you can get a `PyRefMut` directly
2466 /// let class_ref: PyRefMut<'_, Class> = class.extract(py)?;
2467 /// assert_eq!(class_ref.i, 1);
2468 /// Ok(())
2469 /// })
2470 /// # }
2471 /// ```
2472 pub fn cast_bound<'py, U>(&self, py: Python<'py>) -> Result<&Bound<'py, U>, CastError<'_, 'py>>
2473 where
2474 U: PyTypeCheck,
2475 {
2476 self.bind(py).cast()
2477 }
2478
2479 /// Casts the `Py<T>` to a concrete Python object type without checking validity.
2480 ///
2481 /// # Safety
2482 ///
2483 /// Callers must ensure that the type is valid or risk type confusion.
2484 #[inline]
2485 pub unsafe fn cast_bound_unchecked<'py, U>(&self, py: Python<'py>) -> &Bound<'py, U> {
2486 // Safety: caller has upheld the safety contract
2487 unsafe { self.bind(py).cast_unchecked() }
2488 }
2489}
2490
2491#[track_caller]
2492#[cold]
2493fn panic_on_null(py: Python<'_>) -> ! {
2494 if let Some(err) = PyErr::take(py) {
2495 err.write_unraisable(py, None);
2496 }
2497 panic!("PyObject pointer is null");
2498}
2499
2500#[cfg(test)]
2501mod tests {
2502 use super::{Bound, IntoPyObject, Py};
2503 #[cfg(all(feature = "macros", panic = "unwind"))]
2504 use crate::exceptions::PyValueError;
2505 use crate::test_utils::generate_unique_module_name;
2506 #[cfg(all(feature = "macros", panic = "unwind"))]
2507 use crate::test_utils::UnraisableCapture;
2508 use crate::types::{dict::IntoPyDict, PyAnyMethods, PyCapsule, PyDict, PyString};
2509 use crate::{ffi, Borrowed, IntoPyObjectExt, PyAny, PyResult, Python};
2510 use std::ffi::CStr;
2511
2512 #[test]
2513 fn test_call() {
2514 Python::attach(|py| {
2515 let obj = py.get_type::<PyDict>().into_pyobject(py).unwrap();
2516
2517 let assert_repr = |obj: Bound<'_, PyAny>, expected: &str| {
2518 assert_eq!(obj.repr().unwrap(), expected);
2519 };
2520
2521 assert_repr(obj.call0().unwrap(), "{}");
2522 assert_repr(obj.call1(()).unwrap(), "{}");
2523 assert_repr(obj.call((), None).unwrap(), "{}");
2524
2525 assert_repr(obj.call1(((('x', 1),),)).unwrap(), "{'x': 1}");
2526 assert_repr(
2527 obj.call((), Some(&[('x', 1)].into_py_dict(py).unwrap()))
2528 .unwrap(),
2529 "{'x': 1}",
2530 );
2531 })
2532 }
2533
2534 #[test]
2535 fn test_call_tuple_ref() {
2536 let assert_repr = |obj: &Bound<'_, PyAny>, expected: &str| {
2537 use crate::prelude::PyStringMethods;
2538 assert_eq!(
2539 obj.repr()
2540 .unwrap()
2541 .to_cow()
2542 .unwrap()
2543 .trim_matches(|c| c == '{' || c == '}'),
2544 expected.trim_matches(|c| c == ',' || c == ' ')
2545 );
2546 };
2547
2548 macro_rules! tuple {
2549 ($py:ident, $($key: literal => $value: literal),+) => {
2550 let ty_obj = $py.get_type::<PyDict>().into_pyobject($py).unwrap();
2551 assert!(ty_obj.call1(&(($(($key),)+),)).is_err());
2552 let obj = ty_obj.call1(&(($(($key, i32::from($value)),)+),)).unwrap();
2553 assert_repr(&obj, concat!($("'", $key, "'", ": ", stringify!($value), ", ",)+));
2554 assert!(obj.call_method1("update", &(($(($key),)+),)).is_err());
2555 obj.call_method1("update", &(($((i32::from($value), $key),)+),)).unwrap();
2556 assert_repr(&obj, concat!(
2557 concat!($("'", $key, "'", ": ", stringify!($value), ", ",)+),
2558 concat!($(stringify!($value), ": ", "'", $key, "'", ", ",)+)
2559 ));
2560 };
2561 }
2562
2563 Python::attach(|py| {
2564 tuple!(py, "a" => 1);
2565 tuple!(py, "a" => 1, "b" => 2);
2566 tuple!(py, "a" => 1, "b" => 2, "c" => 3);
2567 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4);
2568 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5);
2569 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6);
2570 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7);
2571 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7, "h" => 8);
2572 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7, "h" => 8, "i" => 9);
2573 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7, "h" => 8, "i" => 9, "j" => 10, "k" => 11);
2574 tuple!(py, "a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5, "f" => 6, "g" => 7, "h" => 8, "i" => 9, "j" => 10, "k" => 11, "l" => 12);
2575 })
2576 }
2577
2578 #[test]
2579 fn test_call_for_non_existing_method() {
2580 Python::attach(|py| {
2581 let obj: Py<PyAny> = PyDict::new(py).into();
2582 assert!(obj.call_method0(py, "asdf").is_err());
2583 assert!(obj
2584 .call_method(py, "nonexistent_method", (1,), None)
2585 .is_err());
2586 assert!(obj.call_method0(py, "nonexistent_method").is_err());
2587 assert!(obj.call_method1(py, "nonexistent_method", (1,)).is_err());
2588 });
2589 }
2590
2591 #[test]
2592 fn py_from_dict() {
2593 let dict: Py<PyDict> = Python::attach(|py| {
2594 let native = PyDict::new(py);
2595 Py::from(native)
2596 });
2597
2598 Python::attach(move |py| {
2599 assert_eq!(dict._get_refcnt(py), 1);
2600 });
2601 }
2602
2603 #[test]
2604 fn pyobject_from_py() {
2605 Python::attach(|py| {
2606 let dict: Py<PyDict> = PyDict::new(py).unbind();
2607 let cnt = dict._get_refcnt(py);
2608 let p: Py<PyAny> = dict.into();
2609 assert_eq!(p._get_refcnt(py), cnt);
2610 });
2611 }
2612
2613 #[test]
2614 fn attr() -> PyResult<()> {
2615 use crate::types::PyModule;
2616
2617 Python::attach(|py| {
2618 const CODE: &CStr = cr#"
2619class A:
2620 pass
2621a = A()
2622 "#;
2623 let module = PyModule::from_code(py, CODE, c"", &generate_unique_module_name(""))?;
2624 let instance: Py<PyAny> = module.getattr("a")?.into();
2625
2626 instance.getattr(py, "foo").unwrap_err();
2627
2628 instance.setattr(py, "foo", "bar")?;
2629
2630 assert!(instance
2631 .getattr(py, "foo")?
2632 .bind(py)
2633 .eq(PyString::new(py, "bar"))?);
2634
2635 instance.getattr(py, "foo")?;
2636 Ok(())
2637 })
2638 }
2639
2640 #[test]
2641 fn pystring_attr() -> PyResult<()> {
2642 use crate::types::PyModule;
2643
2644 Python::attach(|py| {
2645 const CODE: &CStr = cr#"
2646class A:
2647 pass
2648a = A()
2649 "#;
2650 let module = PyModule::from_code(py, CODE, c"", &generate_unique_module_name(""))?;
2651 let instance: Py<PyAny> = module.getattr("a")?.into();
2652
2653 let foo = crate::intern!(py, "foo");
2654 let bar = crate::intern!(py, "bar");
2655
2656 instance.getattr(py, foo).unwrap_err();
2657 instance.setattr(py, foo, bar)?;
2658 assert!(instance.getattr(py, foo)?.bind(py).eq(bar)?);
2659 Ok(())
2660 })
2661 }
2662
2663 #[test]
2664 fn invalid_attr() -> PyResult<()> {
2665 Python::attach(|py| {
2666 let instance: Py<PyAny> = py.eval(c"object()", None, None)?.into();
2667
2668 instance.getattr(py, "foo").unwrap_err();
2669
2670 // Cannot assign arbitrary attributes to `object`
2671 instance.setattr(py, "foo", "bar").unwrap_err();
2672 Ok(())
2673 })
2674 }
2675
2676 #[test]
2677 fn test_py2_from_py_object() {
2678 Python::attach(|py| {
2679 let instance = py.eval(c"object()", None, None).unwrap();
2680 let ptr = instance.as_ptr();
2681 let instance: Bound<'_, PyAny> = instance.extract().unwrap();
2682 assert_eq!(instance.as_ptr(), ptr);
2683 })
2684 }
2685
2686 #[test]
2687 fn test_py2_into_py_object() {
2688 Python::attach(|py| {
2689 let instance = py.eval(c"object()", None, None).unwrap();
2690 let ptr = instance.as_ptr();
2691 let instance: Py<PyAny> = instance.clone().unbind();
2692 assert_eq!(instance.as_ptr(), ptr);
2693 })
2694 }
2695
2696 #[test]
2697 fn test_debug_fmt() {
2698 Python::attach(|py| {
2699 let obj = "hello world".into_pyobject(py).unwrap();
2700 assert_eq!(format!("{obj:?}"), "'hello world'");
2701 });
2702 }
2703
2704 #[test]
2705 fn test_display_fmt() {
2706 Python::attach(|py| {
2707 let obj = "hello world".into_pyobject(py).unwrap();
2708 assert_eq!(format!("{obj}"), "hello world");
2709 });
2710 }
2711
2712 #[test]
2713 fn test_bound_as_any() {
2714 Python::attach(|py| {
2715 let obj = PyString::new(py, "hello world");
2716 let any = obj.as_any();
2717 assert_eq!(any.as_ptr(), obj.as_ptr());
2718 });
2719 }
2720
2721 #[test]
2722 fn test_bound_into_any() {
2723 Python::attach(|py| {
2724 let obj = PyString::new(py, "hello world");
2725 let any = obj.clone().into_any();
2726 assert_eq!(any.as_ptr(), obj.as_ptr());
2727 });
2728 }
2729
2730 #[test]
2731 fn test_bound_py_conversions() {
2732 Python::attach(|py| {
2733 let obj: Bound<'_, PyString> = PyString::new(py, "hello world");
2734 let obj_unbound: &Py<PyString> = obj.as_unbound();
2735 let _: &Bound<'_, PyString> = obj_unbound.bind(py);
2736
2737 let obj_unbound: Py<PyString> = obj.unbind();
2738 let obj: Bound<'_, PyString> = obj_unbound.into_bound(py);
2739
2740 assert_eq!(obj, "hello world");
2741 });
2742 }
2743
2744 #[test]
2745 fn test_borrowed_identity() {
2746 Python::attach(|py| {
2747 let yes = true.into_pyobject(py).unwrap();
2748 let no = false.into_pyobject(py).unwrap();
2749
2750 assert!(yes.is(yes));
2751 assert!(!yes.is(no));
2752 });
2753 }
2754
2755 #[test]
2756 #[expect(
2757 clippy::undocumented_unsafe_blocks,
2758 reason = "Doing evil things to try to make `Bound` blow up"
2759 )]
2760 fn bound_from_borrowed_ptr_constructors() {
2761 Python::attach(|py| {
2762 fn check_drop<'py>(
2763 py: Python<'py>,
2764 method: impl FnOnce(*mut ffi::PyObject) -> Bound<'py, PyAny>,
2765 ) {
2766 let mut dropped = false;
2767 let capsule = PyCapsule::new_with_value_and_destructor(
2768 py,
2769 (&mut dropped) as *mut _ as usize,
2770 c"bound_from_borrowed_ptr_constructors",
2771 |ptr, _| unsafe { std::ptr::write(ptr as *mut bool, true) },
2772 )
2773 .unwrap();
2774
2775 let bound = method(capsule.as_ptr());
2776 assert!(!dropped);
2777
2778 // creating the bound should have increased the refcount
2779 drop(capsule);
2780 assert!(!dropped);
2781
2782 // dropping the bound should now also decrease the refcount and free the object
2783 drop(bound);
2784 assert!(dropped);
2785 }
2786
2787 check_drop(py, |ptr| unsafe { Bound::from_borrowed_ptr(py, ptr) });
2788 check_drop(py, |ptr| unsafe {
2789 Bound::from_borrowed_ptr_or_opt(py, ptr).unwrap()
2790 });
2791 check_drop(py, |ptr| unsafe {
2792 Bound::from_borrowed_ptr_or_err(py, ptr).unwrap()
2793 });
2794 })
2795 }
2796
2797 #[test]
2798 #[expect(
2799 clippy::undocumented_unsafe_blocks,
2800 reason = "Doing evil things to try to make `Borrowed` blow up"
2801 )]
2802 fn borrowed_ptr_constructors() {
2803 Python::attach(|py| {
2804 fn check_drop<'py>(
2805 py: Python<'py>,
2806 method: impl FnOnce(&*mut ffi::PyObject) -> Borrowed<'_, 'py, PyAny>,
2807 ) {
2808 let mut dropped = false;
2809 let capsule = PyCapsule::new_with_value_and_destructor(
2810 py,
2811 (&mut dropped) as *mut _ as usize,
2812 c"borrowed_ptr_constructors",
2813 |ptr, _| unsafe { std::ptr::write(ptr as *mut bool, true) },
2814 )
2815 .unwrap();
2816
2817 let ptr = &capsule.as_ptr();
2818 let _borrowed = method(ptr);
2819 assert!(!dropped);
2820
2821 // creating the borrow should not have increased the refcount
2822 drop(capsule);
2823 assert!(dropped);
2824 }
2825
2826 check_drop(py, |&ptr| unsafe { Borrowed::from_ptr(py, ptr) });
2827 check_drop(py, |&ptr| unsafe {
2828 Borrowed::from_ptr_or_opt(py, ptr).unwrap()
2829 });
2830 check_drop(py, |&ptr| unsafe {
2831 Borrowed::from_ptr_or_err(py, ptr).unwrap()
2832 });
2833 })
2834 }
2835
2836 #[test]
2837 fn explicit_drop_ref() {
2838 Python::attach(|py| {
2839 let object: Py<PyDict> = PyDict::new(py).unbind();
2840 let object2 = object.clone_ref(py);
2841
2842 assert_eq!(object.as_ptr(), object2.as_ptr());
2843 assert_eq!(object._get_refcnt(py), 2);
2844
2845 object.drop_ref(py);
2846
2847 assert_eq!(object2._get_refcnt(py), 1);
2848
2849 object2.drop_ref(py);
2850 });
2851 }
2852
2853 #[test]
2854 fn test_py_is_truthy() {
2855 Python::attach(|py| {
2856 let yes = true.into_py_any(py).unwrap();
2857 let no = false.into_py_any(py).unwrap();
2858
2859 assert!(yes.is_truthy(py).unwrap());
2860 assert!(!no.is_truthy(py).unwrap());
2861 });
2862 }
2863
2864 #[cfg(all(feature = "macros", panic = "unwind"))]
2865 #[test]
2866 fn test_constructors_panic_on_null() {
2867 Python::attach(|py| {
2868 const NULL: *mut ffi::PyObject = std::ptr::null_mut();
2869
2870 #[expect(deprecated, reason = "Py<T> constructors")]
2871 // SAFETY: calling all constructors with null pointer to test panic behavior
2872 for constructor in unsafe {
2873 [
2874 (|py| {
2875 Py::<PyAny>::from_owned_ptr(py, NULL);
2876 }) as fn(Python<'_>),
2877 (|py| {
2878 Py::<PyAny>::from_borrowed_ptr(py, NULL);
2879 }) as fn(Python<'_>),
2880 (|py| {
2881 Bound::from_owned_ptr(py, NULL);
2882 }) as fn(Python<'_>),
2883 (|py| {
2884 Bound::from_borrowed_ptr(py, NULL);
2885 }) as fn(Python<'_>),
2886 (|py| {
2887 Borrowed::from_ptr(py, NULL);
2888 }) as fn(Python<'_>),
2889 ]
2890 } {
2891 UnraisableCapture::enter(py, |capture| {
2892 // panic without exception set, no unraisable hook called
2893 let result = std::panic::catch_unwind(|| {
2894 constructor(py);
2895 });
2896 assert_eq!(
2897 result.unwrap_err().downcast_ref::<&str>(),
2898 Some(&"PyObject pointer is null")
2899 );
2900 assert!(capture.take_capture().is_none());
2901
2902 // set an exception, panic, unraisable hook called
2903 PyValueError::new_err("error").restore(py);
2904 let result = std::panic::catch_unwind(|| {
2905 constructor(py);
2906 });
2907 assert_eq!(
2908 result.unwrap_err().downcast_ref::<&str>(),
2909 Some(&"PyObject pointer is null")
2910 );
2911 assert!(capture.take_capture().is_some_and(|(err, obj)| {
2912 err.is_instance_of::<PyValueError>(py) && obj.is_none()
2913 }));
2914 });
2915 }
2916 });
2917 }
2918
2919 #[cfg(feature = "macros")]
2920 mod using_macros {
2921 use super::*;
2922
2923 #[crate::pyclass(crate = "crate")]
2924 struct SomeClass(i32);
2925
2926 #[test]
2927 fn py_borrow_methods() {
2928 // More detailed tests of the underlying semantics in pycell.rs
2929 Python::attach(|py| {
2930 let instance = Py::new(py, SomeClass(0)).unwrap();
2931 assert_eq!(instance.borrow(py).0, 0);
2932 assert_eq!(instance.try_borrow(py).unwrap().0, 0);
2933 assert_eq!(instance.borrow_mut(py).0, 0);
2934 assert_eq!(instance.try_borrow_mut(py).unwrap().0, 0);
2935
2936 instance.borrow_mut(py).0 = 123;
2937
2938 assert_eq!(instance.borrow(py).0, 123);
2939 assert_eq!(instance.try_borrow(py).unwrap().0, 123);
2940 assert_eq!(instance.borrow_mut(py).0, 123);
2941 assert_eq!(instance.try_borrow_mut(py).unwrap().0, 123);
2942 })
2943 }
2944
2945 #[test]
2946 fn bound_borrow_methods() {
2947 // More detailed tests of the underlying semantics in pycell.rs
2948 Python::attach(|py| {
2949 let instance = Bound::new(py, SomeClass(0)).unwrap();
2950 assert_eq!(instance.borrow().0, 0);
2951 assert_eq!(instance.try_borrow().unwrap().0, 0);
2952 assert_eq!(instance.borrow_mut().0, 0);
2953 assert_eq!(instance.try_borrow_mut().unwrap().0, 0);
2954
2955 instance.borrow_mut().0 = 123;
2956
2957 assert_eq!(instance.borrow().0, 123);
2958 assert_eq!(instance.try_borrow().unwrap().0, 123);
2959 assert_eq!(instance.borrow_mut().0, 123);
2960 assert_eq!(instance.try_borrow_mut().unwrap().0, 123);
2961 })
2962 }
2963
2964 #[crate::pyclass(frozen, crate = "crate")]
2965 struct FrozenClass(i32);
2966
2967 #[test]
2968 fn test_frozen_get() {
2969 Python::attach(|py| {
2970 for i in 0..10 {
2971 let instance = Py::new(py, FrozenClass(i)).unwrap();
2972 assert_eq!(instance.get().0, i);
2973
2974 assert_eq!(instance.bind(py).get().0, i);
2975
2976 assert_eq!(instance.bind_borrowed(py).get().0, i);
2977 }
2978 })
2979 }
2980
2981 #[crate::pyclass(crate = "crate", subclass)]
2982 struct BaseClass;
2983
2984 trait MyClassMethods<'py>: Sized {
2985 fn pyrepr_by_ref(&self) -> PyResult<String>;
2986 fn pyrepr_by_val(self) -> PyResult<String> {
2987 self.pyrepr_by_ref()
2988 }
2989 }
2990 impl<'py> MyClassMethods<'py> for Bound<'py, BaseClass> {
2991 fn pyrepr_by_ref(&self) -> PyResult<String> {
2992 self.call_method0("__repr__")?.extract()
2993 }
2994 }
2995
2996 #[crate::pyclass(crate = "crate", extends = BaseClass)]
2997 struct SubClass;
2998
2999 #[test]
3000 fn test_as_super() {
3001 Python::attach(|py| {
3002 let obj = Bound::new(py, (SubClass, BaseClass)).unwrap();
3003 let _: &Bound<'_, BaseClass> = obj.as_super();
3004 let _: &Bound<'_, PyAny> = obj.as_super().as_super();
3005 assert!(obj.as_super().pyrepr_by_ref().is_ok());
3006 })
3007 }
3008
3009 #[test]
3010 fn test_into_super() {
3011 Python::attach(|py| {
3012 let obj = Bound::new(py, (SubClass, BaseClass)).unwrap();
3013 let _: Bound<'_, BaseClass> = obj.clone().into_super();
3014 let _: Bound<'_, PyAny> = obj.clone().into_super().into_super();
3015 assert!(obj.into_super().pyrepr_by_val().is_ok());
3016 })
3017 }
3018 }
3019}