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