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