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