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