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