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