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