pyo3/
marker.rs

1//! Fundamental properties of objects tied to the Python interpreter.
2//!
3//! The Python interpreter is not threadsafe. To protect the Python interpreter in multithreaded
4//! scenarios there is a global lock, the *global interpreter lock* (hereafter referred to as *GIL*)
5//! that must be held to safely interact with Python objects. This is why in PyO3 when you acquire
6//! the GIL you get a [`Python`] marker token that carries the *lifetime* of holding the GIL and all
7//! borrowed references to Python objects carry this lifetime as well. This will statically ensure
8//! that you can never use Python objects after dropping the lock - if you mess this up it will be
9//! caught at compile time and your program will fail to compile.
10//!
11//! It also supports this pattern that many extension modules employ:
12//! - Drop the GIL, so that other Python threads can acquire it and make progress themselves
13//! - Do something independently of the Python interpreter, like IO, a long running calculation or
14//!   awaiting a future
15//! - Once that is done, reacquire the GIL
16//!
17//! That API is provided by [`Python::allow_threads`] and enforced via the [`Ungil`] bound on the
18//! closure and the return type. This is done by relying on the [`Send`] auto trait. `Ungil` is
19//! defined as the following:
20//!
21//! ```rust
22//! # #![allow(dead_code)]
23//! pub unsafe trait Ungil {}
24//!
25//! unsafe impl<T: Send> Ungil for T {}
26//! ```
27//!
28//! We piggy-back off the `Send` auto trait because it is not possible to implement custom auto
29//! traits on stable Rust. This is the solution which enables it for as many types as possible while
30//! making the API usable.
31//!
32//! In practice this API works quite well, but it comes with some drawbacks:
33//!
34//! ## Drawbacks
35//!
36//! There is no reason to prevent `!Send` types like [`Rc`] from crossing the closure. After all,
37//! [`Python::allow_threads`] just lets other Python threads run - it does not itself launch a new
38//! thread.
39//!
40//! ```rust, compile_fail
41//! # #[cfg(feature = "nightly")]
42//! # compile_error!("this actually works on nightly")
43//! use pyo3::prelude::*;
44//! use std::rc::Rc;
45//!
46//! fn main() {
47//!     Python::with_gil(|py| {
48//!         let rc = Rc::new(5);
49//!
50//!         py.allow_threads(|| {
51//!             // This would actually be fine...
52//!             println!("{:?}", *rc);
53//!         });
54//!     });
55//! }
56//! ```
57//!
58//! Because we are using `Send` for something it's not quite meant for, other code that
59//! (correctly) upholds the invariants of [`Send`] can cause problems.
60//!
61//! [`SendWrapper`] is one of those. Per its documentation:
62//!
63//! > A wrapper which allows you to move around non-Send-types between threads, as long as you
64//! > access the contained value only from within the original thread and make sure that it is
65//! > dropped from within the original thread.
66//!
67//! This will "work" to smuggle Python references across the closure, because we're not actually
68//! doing anything with threads:
69//!
70//! ```rust, no_run
71//! use pyo3::prelude::*;
72//! use pyo3::types::PyString;
73//! use send_wrapper::SendWrapper;
74//!
75//! Python::with_gil(|py| {
76//!     let string = PyString::new_bound(py, "foo");
77//!
78//!     let wrapped = SendWrapper::new(string);
79//!
80//!     py.allow_threads(|| {
81//! # #[cfg(not(feature = "nightly"))]
82//! # {
83//!         // 💥 Unsound! 💥
84//!         let smuggled: &Bound<'_, PyString> = &*wrapped;
85//!         println!("{:?}", smuggled);
86//! # }
87//!     });
88//! });
89//! ```
90//!
91//! For now the answer to that is "don't do that".
92//!
93//! # A proper implementation using an auto trait
94//!
95//! However on nightly Rust and when PyO3's `nightly` feature is
96//! enabled, `Ungil` is defined as the following:
97//!
98//! ```rust
99//! # #[cfg(any())]
100//! # {
101//! #![feature(auto_traits, negative_impls)]
102//!
103//! pub unsafe auto trait Ungil {}
104//!
105//! // It is unimplemented for the `Python` struct and Python objects.
106//! impl !Ungil for Python<'_> {}
107//! impl !Ungil for ffi::PyObject {}
108//!
109//! // `Py` wraps it in  a safe api, so this is OK
110//! unsafe impl<T> Ungil for Py<T> {}
111//! # }
112//! ```
113//!
114//! With this feature enabled, the above two examples will start working and not working, respectively.
115//!
116//! [`SendWrapper`]: https://docs.rs/send_wrapper/latest/send_wrapper/struct.SendWrapper.html
117//! [`Rc`]: std::rc::Rc
118//! [`Py`]: crate::Py
119use crate::err::{self, PyErr, PyResult};
120use crate::ffi_ptr_ext::FfiPtrExt;
121use crate::gil::{GILGuard, SuspendGIL};
122use crate::impl_::not_send::NotSend;
123use crate::py_result_ext::PyResultExt;
124use crate::types::any::PyAnyMethods;
125use crate::types::{
126    PyAny, PyDict, PyEllipsis, PyModule, PyNone, PyNotImplemented, PyString, PyType,
127};
128use crate::version::PythonVersionInfo;
129use crate::{ffi, Bound, IntoPy, Py, PyObject, PyTypeInfo};
130#[allow(deprecated)]
131#[cfg(feature = "gil-refs")]
132use crate::{gil::GILPool, FromPyPointer, PyNativeType};
133use std::ffi::{CStr, CString};
134use std::marker::PhantomData;
135use std::os::raw::c_int;
136
137/// Types that are safe to access while the GIL is not held.
138///
139/// # Safety
140///
141/// The type must not carry borrowed Python references or, if it does, not allow access to them if
142/// the GIL is not held.
143///
144/// See the [module-level documentation](self) for more information.
145///
146/// # Examples
147///
148/// This tracking is currently imprecise as it relies on the [`Send`] auto trait on stable Rust.
149/// For example, an `Rc` smart pointer should be usable without the GIL, but we currently prevent that:
150///
151/// ```compile_fail
152/// # use pyo3::prelude::*;
153/// use std::rc::Rc;
154///
155/// Python::with_gil(|py| {
156///     let rc = Rc::new(42);
157///
158///     py.allow_threads(|| {
159///         println!("{:?}", rc);
160///     });
161/// });
162/// ```
163///
164/// This also implies that the interplay between `with_gil` and `allow_threads` is unsound, for example
165/// one can circumvent this protection using the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
166///
167/// ```no_run
168/// # use pyo3::prelude::*;
169/// # use pyo3::types::PyString;
170/// use send_wrapper::SendWrapper;
171///
172/// Python::with_gil(|py| {
173///     let string = PyString::new_bound(py, "foo");
174///
175///     let wrapped = SendWrapper::new(string);
176///
177///     py.allow_threads(|| {
178///         let sneaky: &Bound<'_, PyString> = &*wrapped;
179///
180///         println!("{:?}", sneaky);
181///     });
182/// });
183/// ```
184///
185/// Fixing this loophole on stable Rust has significant ergonomic issues, but it is fixed when using
186/// nightly Rust and the `nightly` feature, c.f. [#2141](https://github.com/PyO3/pyo3/issues/2141).
187#[cfg_attr(docsrs, doc(cfg(all())))] // Hide the cfg flag
188#[cfg(not(feature = "nightly"))]
189pub unsafe trait Ungil {}
190
191#[cfg_attr(docsrs, doc(cfg(all())))] // Hide the cfg flag
192#[cfg(not(feature = "nightly"))]
193unsafe impl<T: Send> Ungil for T {}
194
195#[cfg(feature = "nightly")]
196mod nightly {
197    macro_rules! define {
198        ($($tt:tt)*) => { $($tt)* }
199    }
200
201    define! {
202        /// Types that are safe to access while the GIL is not held.
203        ///
204        /// # Safety
205        ///
206        /// The type must not carry borrowed Python references or, if it does, not allow access to them if
207        /// the GIL is not held.
208        ///
209        /// See the [module-level documentation](self) for more information.
210        ///
211        /// # Examples
212        ///
213        /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g.
214        ///
215        /// ```compile_fail
216        /// # use pyo3::prelude::*;
217        /// # use pyo3::types::PyString;
218        /// Python::with_gil(|py| {
219        ///     let string = PyString::new_bound(py, "foo");
220        ///
221        ///     py.allow_threads(|| {
222        ///         println!("{:?}", string);
223        ///     });
224        /// });
225        /// ```
226        ///
227        /// This applies to the GIL token `Python` itself as well, e.g.
228        ///
229        /// ```compile_fail
230        /// # use pyo3::prelude::*;
231        /// Python::with_gil(|py| {
232        ///     py.allow_threads(|| {
233        ///         drop(py);
234        ///     });
235        /// });
236        /// ```
237        ///
238        /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able
239        /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
240        ///
241        /// ```compile_fail
242        /// # use pyo3::prelude::*;
243        /// # use pyo3::types::PyString;
244        /// use send_wrapper::SendWrapper;
245        ///
246        /// Python::with_gil(|py| {
247        ///     let string = PyString::new_bound(py, "foo");
248        ///
249        ///     let wrapped = SendWrapper::new(string);
250        ///
251        ///     py.allow_threads(|| {
252        ///         let sneaky: &PyString = *wrapped;
253        ///
254        ///         println!("{:?}", sneaky);
255        ///     });
256        /// });
257        /// ```
258        ///
259        /// This also enables using non-[`Send`] types in `allow_threads`,
260        /// at least if they are not also bound to the GIL:
261        ///
262        /// ```rust
263        /// # use pyo3::prelude::*;
264        /// use std::rc::Rc;
265        ///
266        /// Python::with_gil(|py| {
267        ///     let rc = Rc::new(42);
268        ///
269        ///     py.allow_threads(|| {
270        ///         println!("{:?}", rc);
271        ///     });
272        /// });
273        /// ```
274        pub unsafe auto trait Ungil {}
275    }
276
277    impl !Ungil for crate::Python<'_> {}
278
279    // This means that PyString, PyList, etc all inherit !Ungil from  this.
280    impl !Ungil for crate::PyAny {}
281
282    // All the borrowing wrappers
283    #[allow(deprecated)]
284    #[cfg(feature = "gil-refs")]
285    impl<T> !Ungil for crate::PyCell<T> {}
286    impl<T> !Ungil for crate::PyRef<'_, T> {}
287    impl<T> !Ungil for crate::PyRefMut<'_, T> {}
288
289    // FFI pointees
290    impl !Ungil for crate::ffi::PyObject {}
291    impl !Ungil for crate::ffi::PyLongObject {}
292
293    impl !Ungil for crate::ffi::PyThreadState {}
294    impl !Ungil for crate::ffi::PyInterpreterState {}
295    impl !Ungil for crate::ffi::PyWeakReference {}
296    impl !Ungil for crate::ffi::PyFrameObject {}
297    impl !Ungil for crate::ffi::PyCodeObject {}
298    #[cfg(not(Py_LIMITED_API))]
299    impl !Ungil for crate::ffi::PyDictKeysObject {}
300    #[cfg(not(any(Py_LIMITED_API, Py_3_10)))]
301    impl !Ungil for crate::ffi::PyArena {}
302}
303
304#[cfg(feature = "nightly")]
305pub use nightly::Ungil;
306
307/// A marker token that represents holding the GIL.
308///
309/// It serves three main purposes:
310/// - It provides a global API for the Python interpreter, such as [`Python::eval_bound`].
311/// - It can be passed to functions that require a proof of holding the GIL, such as
312///   [`Py::clone_ref`].
313/// - Its lifetime represents the scope of holding the GIL which can be used to create Rust
314///   references that are bound to it, such as [`Bound<'py, PyAny>`].
315///
316/// Note that there are some caveats to using it that you might need to be aware of. See the
317/// [Deadlocks](#deadlocks) and [Releasing and freeing memory](#releasing-and-freeing-memory)
318/// paragraphs for more information about that.
319///
320/// # Obtaining a Python token
321///
322/// The following are the recommended ways to obtain a [`Python<'py>`] token, in order of preference:
323/// - If you already have something with a lifetime bound to the GIL, such as [`Bound<'py, PyAny>`], you can
324///   use its `.py()` method to get a token.
325/// - In a function or method annotated with [`#[pyfunction]`](crate::pyfunction) or [`#[pymethods]`](crate::pymethods) you can declare it
326///   as a parameter, and PyO3 will pass in the token when Python code calls it.
327/// - When you need to acquire the GIL yourself, such as when calling Python code from Rust, you
328///   should call [`Python::with_gil`] to do that and pass your code as a closure to it.
329///
330/// The first two options are zero-cost; [`Python::with_gil`] requires runtime checking and may need to block
331/// to acquire the GIL.
332///
333/// # Deadlocks
334///
335/// Note that the GIL can be temporarily released by the Python interpreter during a function call
336/// (e.g. importing a module). In general, you don't need to worry about this because the GIL is
337/// reacquired before returning to the Rust code:
338///
339/// ```text
340/// `Python` exists   |=====================================|
341/// GIL actually held |==========|         |================|
342/// Rust code running |=======|                |==|  |======|
343/// ```
344///
345/// This behaviour can cause deadlocks when trying to lock a Rust mutex while holding the GIL:
346///
347///  * Thread 1 acquires the GIL
348///  * Thread 1 locks a mutex
349///  * Thread 1 makes a call into the Python interpreter which releases the GIL
350///  * Thread 2 acquires the GIL
351///  * Thread 2 tries to locks the mutex, blocks
352///  * Thread 1's Python interpreter call blocks trying to reacquire the GIL held by thread 2
353///
354/// To avoid deadlocking, you should release the GIL before trying to lock a mutex or `await`ing in
355/// asynchronous code, e.g. with [`Python::allow_threads`].
356///
357/// # Releasing and freeing memory
358///
359/// The [`Python<'py>`] type can be used to create references to variables owned by the Python
360/// interpreter, using functions such as [`Python::eval_bound`] and [`PyModule::import_bound`].
361#[derive(Copy, Clone)]
362pub struct Python<'py>(PhantomData<(&'py GILGuard, NotSend)>);
363
364impl Python<'_> {
365    /// Acquires the global interpreter lock, allowing access to the Python interpreter. The
366    /// provided closure `F` will be executed with the acquired `Python` marker token.
367    ///
368    /// If implementing [`#[pymethods]`](crate::pymethods) or [`#[pyfunction]`](crate::pyfunction),
369    /// declare `py: Python` as an argument. PyO3 will pass in the token to grant access to the GIL
370    /// context in which the function is running, avoiding the need to call `with_gil`.
371    ///
372    /// If the [`auto-initialize`] feature is enabled and the Python runtime is not already
373    /// initialized, this function will initialize it. See
374    #[cfg_attr(
375        not(any(PyPy, GraalPy)),
376        doc = "[`prepare_freethreaded_python`](crate::prepare_freethreaded_python)"
377    )]
378    #[cfg_attr(PyPy, doc = "`prepare_freethreaded_python`")]
379    /// for details.
380    ///
381    /// If the current thread does not yet have a Python "thread state" associated with it,
382    /// a new one will be automatically created before `F` is executed and destroyed after `F`
383    /// completes.
384    ///
385    /// # Panics
386    ///
387    /// - If the [`auto-initialize`] feature is not enabled and the Python interpreter is not
388    ///   initialized.
389    ///
390    /// # Examples
391    ///
392    /// ```
393    /// use pyo3::prelude::*;
394    ///
395    /// # fn main() -> PyResult<()> {
396    /// Python::with_gil(|py| -> PyResult<()> {
397    ///     let x: i32 = py.eval_bound("5", None, None)?.extract()?;
398    ///     assert_eq!(x, 5);
399    ///     Ok(())
400    /// })
401    /// # }
402    /// ```
403    ///
404    /// [`auto-initialize`]: https://pyo3.rs/main/features.html#auto-initialize
405    #[inline]
406    pub fn with_gil<F, R>(f: F) -> R
407    where
408        F: for<'py> FnOnce(Python<'py>) -> R,
409    {
410        let guard = GILGuard::acquire();
411
412        // SAFETY: Either the GIL was already acquired or we just created a new `GILGuard`.
413        f(guard.python())
414    }
415
416    /// Like [`Python::with_gil`] except Python interpreter state checking is skipped.
417    ///
418    /// Normally when the GIL is acquired, we check that the Python interpreter is an
419    /// appropriate state (e.g. it is fully initialized). This function skips those
420    /// checks.
421    ///
422    /// # Safety
423    ///
424    /// If [`Python::with_gil`] would succeed, it is safe to call this function.
425    ///
426    /// In most cases, you should use [`Python::with_gil`].
427    ///
428    /// A justified scenario for calling this function is during multi-phase interpreter
429    /// initialization when [`Python::with_gil`] would fail before
430    // this link is only valid on 3.8+not pypy and up.
431    #[cfg_attr(
432        all(Py_3_8, not(PyPy)),
433        doc = "[`_Py_InitializeMain`](crate::ffi::_Py_InitializeMain)"
434    )]
435    #[cfg_attr(any(not(Py_3_8), PyPy), doc = "`_Py_InitializeMain`")]
436    /// is called because the interpreter is only partially initialized.
437    ///
438    /// Behavior in other scenarios is not documented.
439    #[inline]
440    pub unsafe fn with_gil_unchecked<F, R>(f: F) -> R
441    where
442        F: for<'py> FnOnce(Python<'py>) -> R,
443    {
444        let guard = GILGuard::acquire_unchecked();
445
446        f(guard.python())
447    }
448}
449
450impl<'py> Python<'py> {
451    /// Temporarily releases the GIL, thus allowing other Python threads to run. The GIL will be
452    /// reacquired when `F`'s scope ends.
453    ///
454    /// If you don't need to touch the Python
455    /// interpreter for some time and have other Python threads around, this will let you run
456    /// Rust-only code while letting those other Python threads make progress.
457    ///
458    /// Only types that implement [`Ungil`] can cross the closure. See the
459    /// [module level documentation](self) for more information.
460    ///
461    /// If you need to pass Python objects into the closure you can use [`Py`]`<T>`to create a
462    /// reference independent of the GIL lifetime. However, you cannot do much with those without a
463    /// [`Python`] token, for which you'd need to reacquire the GIL.
464    ///
465    /// # Example: Releasing the GIL while running a computation in Rust-only code
466    ///
467    /// ```
468    /// use pyo3::prelude::*;
469    ///
470    /// #[pyfunction]
471    /// fn sum_numbers(py: Python<'_>, numbers: Vec<u32>) -> PyResult<u32> {
472    ///     // We release the GIL here so any other Python threads get a chance to run.
473    ///     py.allow_threads(move || {
474    ///         // An example of an "expensive" Rust calculation
475    ///         let sum = numbers.iter().sum();
476    ///
477    ///         Ok(sum)
478    ///     })
479    /// }
480    /// #
481    /// # fn main() -> PyResult<()> {
482    /// #     Python::with_gil(|py| -> PyResult<()> {
483    /// #         let fun = pyo3::wrap_pyfunction_bound!(sum_numbers, py)?;
484    /// #         let res = fun.call1((vec![1_u32, 2, 3],))?;
485    /// #         assert_eq!(res.extract::<u32>()?, 6_u32);
486    /// #         Ok(())
487    /// #     })
488    /// # }
489    /// ```
490    ///
491    /// Please see the [Parallelism] chapter of the guide for a thorough discussion of using
492    /// [`Python::allow_threads`] in this manner.
493    ///
494    /// # Example: Passing borrowed Python references into the closure is not allowed
495    ///
496    /// ```compile_fail
497    /// use pyo3::prelude::*;
498    /// use pyo3::types::PyString;
499    ///
500    /// fn parallel_print(py: Python<'_>) {
501    ///     let s = PyString::new_bound(py, "This object cannot be accessed without holding the GIL >_<");
502    ///     py.allow_threads(move || {
503    ///         println!("{:?}", s); // This causes a compile error.
504    ///     });
505    /// }
506    /// ```
507    ///
508    /// [`Py`]: crate::Py
509    /// [`PyString`]: crate::types::PyString
510    /// [auto-traits]: https://doc.rust-lang.org/nightly/unstable-book/language-features/auto-traits.html
511    /// [Parallelism]: https://pyo3.rs/main/parallelism.html
512    pub fn allow_threads<T, F>(self, f: F) -> T
513    where
514        F: Ungil + FnOnce() -> T,
515        T: Ungil,
516    {
517        // Use a guard pattern to handle reacquiring the GIL,
518        // so that the GIL will be reacquired even if `f` panics.
519        // The `Send` bound on the closure prevents the user from
520        // transferring the `Python` token into the closure.
521        let _guard = unsafe { SuspendGIL::new() };
522        f()
523    }
524
525    /// Deprecated version of [`Python::eval_bound`]
526    #[cfg(feature = "gil-refs")]
527    #[deprecated(
528        since = "0.21.0",
529        note = "`Python::eval` will be replaced by `Python::eval_bound` in a future PyO3 version"
530    )]
531    pub fn eval(
532        self,
533        code: &str,
534        globals: Option<&'py PyDict>,
535        locals: Option<&'py PyDict>,
536    ) -> PyResult<&'py PyAny> {
537        self.eval_bound(
538            code,
539            globals.map(PyNativeType::as_borrowed).as_deref(),
540            locals.map(PyNativeType::as_borrowed).as_deref(),
541        )
542        .map(Bound::into_gil_ref)
543    }
544
545    /// Evaluates a Python expression in the given context and returns the result.
546    ///
547    /// If `globals` is `None`, it defaults to Python module `__main__`.
548    /// If `locals` is `None`, it defaults to the value of `globals`.
549    ///
550    /// If `globals` doesn't contain `__builtins__`, default `__builtins__`
551    /// will be added automatically.
552    ///
553    /// # Examples
554    ///
555    /// ```
556    /// # use pyo3::prelude::*;
557    /// # Python::with_gil(|py| {
558    /// let result = py.eval_bound("[i * 10 for i in range(5)]", None, None).unwrap();
559    /// let res: Vec<i64> = result.extract().unwrap();
560    /// assert_eq!(res, vec![0, 10, 20, 30, 40])
561    /// # });
562    /// ```
563    pub fn eval_bound(
564        self,
565        code: &str,
566        globals: Option<&Bound<'py, PyDict>>,
567        locals: Option<&Bound<'py, PyDict>>,
568    ) -> PyResult<Bound<'py, PyAny>> {
569        self.run_code(code, ffi::Py_eval_input, globals, locals)
570    }
571
572    /// Deprecated version of [`Python::run_bound`]
573    #[cfg(feature = "gil-refs")]
574    #[deprecated(
575        since = "0.21.0",
576        note = "`Python::run` will be replaced by `Python::run_bound` in a future PyO3 version"
577    )]
578    pub fn run(
579        self,
580        code: &str,
581        globals: Option<&PyDict>,
582        locals: Option<&PyDict>,
583    ) -> PyResult<()> {
584        self.run_bound(
585            code,
586            globals.map(PyNativeType::as_borrowed).as_deref(),
587            locals.map(PyNativeType::as_borrowed).as_deref(),
588        )
589    }
590
591    /// Executes one or more Python statements in the given context.
592    ///
593    /// If `globals` is `None`, it defaults to Python module `__main__`.
594    /// If `locals` is `None`, it defaults to the value of `globals`.
595    ///
596    /// If `globals` doesn't contain `__builtins__`, default `__builtins__`
597    /// will be added automatically.
598    ///
599    /// # Examples
600    /// ```
601    /// use pyo3::{
602    ///     prelude::*,
603    ///     types::{PyBytes, PyDict},
604    /// };
605    /// Python::with_gil(|py| {
606    ///     let locals = PyDict::new_bound(py);
607    ///     py.run_bound(
608    ///         r#"
609    /// import base64
610    /// s = 'Hello Rust!'
611    /// ret = base64.b64encode(s.encode('utf-8'))
612    /// "#,
613    ///         None,
614    ///         Some(&locals),
615    ///     )
616    ///     .unwrap();
617    ///     let ret = locals.get_item("ret").unwrap().unwrap();
618    ///     let b64 = ret.downcast::<PyBytes>().unwrap();
619    ///     assert_eq!(b64.as_bytes(), b"SGVsbG8gUnVzdCE=");
620    /// });
621    /// ```
622    ///
623    /// You can use [`py_run!`](macro.py_run.html) for a handy alternative of `run`
624    /// if you don't need `globals` and unwrapping is OK.
625    pub fn run_bound(
626        self,
627        code: &str,
628        globals: Option<&Bound<'py, PyDict>>,
629        locals: Option<&Bound<'py, PyDict>>,
630    ) -> PyResult<()> {
631        let res = self.run_code(code, ffi::Py_file_input, globals, locals);
632        res.map(|obj| {
633            debug_assert!(obj.is_none());
634        })
635    }
636
637    /// Runs code in the given context.
638    ///
639    /// `start` indicates the type of input expected: one of `Py_single_input`,
640    /// `Py_file_input`, or `Py_eval_input`.
641    ///
642    /// If `globals` is `None`, it defaults to Python module `__main__`.
643    /// If `locals` is `None`, it defaults to the value of `globals`.
644    fn run_code(
645        self,
646        code: &str,
647        start: c_int,
648        globals: Option<&Bound<'py, PyDict>>,
649        locals: Option<&Bound<'py, PyDict>>,
650    ) -> PyResult<Bound<'py, PyAny>> {
651        let code = CString::new(code)?;
652        unsafe {
653            let mptr = ffi::PyImport_AddModule(ffi::c_str!("__main__").as_ptr());
654            if mptr.is_null() {
655                return Err(PyErr::fetch(self));
656            }
657
658            let globals = globals
659                .map(|dict| dict.as_ptr())
660                .unwrap_or_else(|| ffi::PyModule_GetDict(mptr));
661            let locals = locals.map(|dict| dict.as_ptr()).unwrap_or(globals);
662
663            // If `globals` don't provide `__builtins__`, most of the code will fail if Python
664            // version is <3.10. That's probably not what user intended, so insert `__builtins__`
665            // for them.
666            //
667            // See also:
668            // - https://github.com/python/cpython/pull/24564 (the same fix in CPython 3.10)
669            // - https://github.com/PyO3/pyo3/issues/3370
670            let builtins_s = crate::intern!(self, "__builtins__").as_ptr();
671            let has_builtins = ffi::PyDict_Contains(globals, builtins_s);
672            if has_builtins == -1 {
673                return Err(PyErr::fetch(self));
674            }
675            if has_builtins == 0 {
676                // Inherit current builtins.
677                let builtins = ffi::PyEval_GetBuiltins();
678
679                // `PyDict_SetItem` doesn't take ownership of `builtins`, but `PyEval_GetBuiltins`
680                // seems to return a borrowed reference, so no leak here.
681                if ffi::PyDict_SetItem(globals, builtins_s, builtins) == -1 {
682                    return Err(PyErr::fetch(self));
683                }
684            }
685
686            let code_obj =
687                ffi::Py_CompileString(code.as_ptr(), ffi::c_str!("<string>").as_ptr(), start);
688            if code_obj.is_null() {
689                return Err(PyErr::fetch(self));
690            }
691            let res_ptr = ffi::PyEval_EvalCode(code_obj, globals, locals);
692            ffi::Py_DECREF(code_obj);
693
694            res_ptr.assume_owned_or_err(self).downcast_into_unchecked()
695        }
696    }
697
698    /// Gets the Python type object for type `T`.
699    #[cfg(feature = "gil-refs")]
700    #[deprecated(
701        since = "0.21.0",
702        note = "`Python::get_type` will be replaced by `Python::get_type_bound` in a future PyO3 version"
703    )]
704    #[inline]
705    pub fn get_type<T>(self) -> &'py PyType
706    where
707        T: PyTypeInfo,
708    {
709        self.get_type_bound::<T>().into_gil_ref()
710    }
711
712    /// Gets the Python type object for type `T`.
713    #[inline]
714    pub fn get_type_bound<T>(self) -> Bound<'py, PyType>
715    where
716        T: PyTypeInfo,
717    {
718        T::type_object_bound(self)
719    }
720
721    /// Deprecated form of [`Python::import_bound`]
722    #[cfg(feature = "gil-refs")]
723    #[deprecated(
724        since = "0.21.0",
725        note = "`Python::import` will be replaced by `Python::import_bound` in a future PyO3 version"
726    )]
727    pub fn import<N>(self, name: N) -> PyResult<&'py PyModule>
728    where
729        N: IntoPy<Py<PyString>>,
730    {
731        Self::import_bound(self, name).map(Bound::into_gil_ref)
732    }
733
734    /// Imports the Python module with the specified name.
735    pub fn import_bound<N>(self, name: N) -> PyResult<Bound<'py, PyModule>>
736    where
737        N: IntoPy<Py<PyString>>,
738    {
739        PyModule::import_bound(self, name)
740    }
741
742    /// Gets the Python builtin value `None`.
743    #[allow(non_snake_case)] // the Python keyword starts with uppercase
744    #[inline]
745    pub fn None(self) -> PyObject {
746        PyNone::get_bound(self).into_py(self)
747    }
748
749    /// Gets the Python builtin value `Ellipsis`, or `...`.
750    #[allow(non_snake_case)] // the Python keyword starts with uppercase
751    #[inline]
752    pub fn Ellipsis(self) -> PyObject {
753        PyEllipsis::get_bound(self).into_py(self)
754    }
755
756    /// Gets the Python builtin value `NotImplemented`.
757    #[allow(non_snake_case)] // the Python keyword starts with uppercase
758    #[inline]
759    pub fn NotImplemented(self) -> PyObject {
760        PyNotImplemented::get_bound(self).into_py(self)
761    }
762
763    /// Gets the running Python interpreter version as a string.
764    ///
765    /// # Examples
766    /// ```rust
767    /// # use pyo3::Python;
768    /// Python::with_gil(|py| {
769    ///     // The full string could be, for example:
770    ///     // "3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)]"
771    ///     assert!(py.version().starts_with("3."));
772    /// });
773    /// ```
774    pub fn version(self) -> &'py str {
775        unsafe {
776            CStr::from_ptr(ffi::Py_GetVersion())
777                .to_str()
778                .expect("Python version string not UTF-8")
779        }
780    }
781
782    /// Gets the running Python interpreter version as a struct similar to
783    /// `sys.version_info`.
784    ///
785    /// # Examples
786    /// ```rust
787    /// # use pyo3::Python;
788    /// Python::with_gil(|py| {
789    ///     // PyO3 supports Python 3.7 and up.
790    ///     assert!(py.version_info() >= (3, 7));
791    ///     assert!(py.version_info() >= (3, 7, 0));
792    /// });
793    /// ```
794    pub fn version_info(self) -> PythonVersionInfo<'py> {
795        let version_str = self.version();
796
797        // Portion of the version string returned by Py_GetVersion up to the first space is the
798        // version number.
799        let version_number_str = version_str.split(' ').next().unwrap_or(version_str);
800
801        PythonVersionInfo::from_str(version_number_str).unwrap()
802    }
803
804    /// Registers the object in the release pool, and tries to downcast to specific type.
805    #[cfg(feature = "gil-refs")]
806    #[deprecated(
807        since = "0.21.0",
808        note = "use `obj.downcast_bound::<T>(py)` instead of `py.checked_cast_as::<T>(obj)`"
809    )]
810    pub fn checked_cast_as<T>(
811        self,
812        obj: PyObject,
813    ) -> Result<&'py T, crate::err::PyDowncastError<'py>>
814    where
815        T: crate::PyTypeCheck<AsRefTarget = T>,
816    {
817        #[allow(deprecated)]
818        obj.into_ref(self).downcast()
819    }
820
821    /// Registers the object in the release pool, and does an unchecked downcast
822    /// to the specific type.
823    ///
824    /// # Safety
825    ///
826    /// Callers must ensure that ensure that the cast is valid.
827    #[cfg(feature = "gil-refs")]
828    #[deprecated(
829        since = "0.21.0",
830        note = "use `obj.downcast_bound_unchecked::<T>(py)` instead of `py.cast_as::<T>(obj)`"
831    )]
832    pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'py T
833    where
834        T: crate::type_object::HasPyGilRef<AsRefTarget = T>,
835    {
836        #[allow(deprecated)]
837        obj.into_ref(self).downcast_unchecked()
838    }
839
840    /// Registers the object pointer in the release pool,
841    /// and does an unchecked downcast to the specific type.
842    ///
843    /// # Safety
844    ///
845    /// Callers must ensure that ensure that the cast is valid.
846    #[allow(clippy::wrong_self_convention, deprecated)]
847    #[cfg(feature = "gil-refs")]
848    #[deprecated(
849        since = "0.21.0",
850        note = "use `Py::from_owned_ptr(py, ptr)` or `Bound::from_owned_ptr(py, ptr)` instead"
851    )]
852    pub unsafe fn from_owned_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'py T
853    where
854        T: FromPyPointer<'py>,
855    {
856        FromPyPointer::from_owned_ptr(self, ptr)
857    }
858
859    /// Registers the owned object pointer in the release pool.
860    ///
861    /// Returns `Err(PyErr)` if the pointer is NULL.
862    /// Does an unchecked downcast to the specific type.
863    ///
864    /// # Safety
865    ///
866    /// Callers must ensure that ensure that the cast is valid.
867    #[allow(clippy::wrong_self_convention, deprecated)]
868    #[cfg(feature = "gil-refs")]
869    #[deprecated(
870        since = "0.21.0",
871        note = "use `Py::from_owned_ptr_or_err(py, ptr)` or `Bound::from_owned_ptr_or_err(py, ptr)` instead"
872    )]
873    pub unsafe fn from_owned_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'py T>
874    where
875        T: FromPyPointer<'py>,
876    {
877        FromPyPointer::from_owned_ptr_or_err(self, ptr)
878    }
879
880    /// Registers the owned object pointer in release pool.
881    ///
882    /// Returns `None` if the pointer is NULL.
883    /// Does an unchecked downcast to the specific type.
884    ///
885    /// # Safety
886    ///
887    /// Callers must ensure that ensure that the cast is valid.
888    #[allow(clippy::wrong_self_convention, deprecated)]
889    #[cfg(feature = "gil-refs")]
890    #[deprecated(
891        since = "0.21.0",
892        note = "use `Py::from_owned_ptr_or_opt(py, ptr)` or `Bound::from_owned_ptr_or_opt(py, ptr)` instead"
893    )]
894    pub unsafe fn from_owned_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'py T>
895    where
896        T: FromPyPointer<'py>,
897    {
898        FromPyPointer::from_owned_ptr_or_opt(self, ptr)
899    }
900
901    /// Does an unchecked downcast to the specific type.
902    ///
903    /// Panics if the pointer is NULL.
904    ///
905    /// # Safety
906    ///
907    /// Callers must ensure that ensure that the cast is valid.
908    #[allow(clippy::wrong_self_convention, deprecated)]
909    #[cfg(feature = "gil-refs")]
910    #[deprecated(
911        since = "0.21.0",
912        note = "use `Py::from_borrowed_ptr(py, ptr)` or `Bound::from_borrowed_ptr(py, ptr)` instead"
913    )]
914    pub unsafe fn from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'py T
915    where
916        T: FromPyPointer<'py>,
917    {
918        FromPyPointer::from_borrowed_ptr(self, ptr)
919    }
920
921    /// Does an unchecked downcast to the specific type.
922    ///
923    /// Returns `Err(PyErr)` if the pointer is NULL.
924    ///
925    /// # Safety
926    ///
927    /// Callers must ensure that ensure that the cast is valid.
928    #[allow(clippy::wrong_self_convention, deprecated)]
929    #[cfg(feature = "gil-refs")]
930    #[deprecated(
931        since = "0.21.0",
932        note = "use `Py::from_borrowed_ptr_or_err(py, ptr)` or `Bound::from_borrowed_ptr_or_err(py, ptr)` instead"
933    )]
934    pub unsafe fn from_borrowed_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'py T>
935    where
936        T: FromPyPointer<'py>,
937    {
938        FromPyPointer::from_borrowed_ptr_or_err(self, ptr)
939    }
940
941    /// Does an unchecked downcast to the specific type.
942    ///
943    /// Returns `None` if the pointer is NULL.
944    ///
945    /// # Safety
946    ///
947    /// Callers must ensure that ensure that the cast is valid.
948    #[allow(clippy::wrong_self_convention, deprecated)]
949    #[cfg(feature = "gil-refs")]
950    #[deprecated(
951        since = "0.21.0",
952        note = "use `Py::from_borrowed_ptr_or_opt(py, ptr)` or `Bound::from_borrowed_ptr_or_opt(py, ptr)` instead"
953    )]
954    pub unsafe fn from_borrowed_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'py T>
955    where
956        T: FromPyPointer<'py>,
957    {
958        FromPyPointer::from_borrowed_ptr_or_opt(self, ptr)
959    }
960
961    /// Lets the Python interpreter check and handle any pending signals. This will invoke the
962    /// corresponding signal handlers registered in Python (if any).
963    ///
964    /// Returns `Err(`[`PyErr`]`)` if any signal handler raises an exception.
965    ///
966    /// These signals include `SIGINT` (normally raised by CTRL + C), which by default raises
967    /// `KeyboardInterrupt`. For this reason it is good practice to call this function regularly
968    /// as part of long-running Rust functions so that users can cancel it.
969    ///
970    /// # Example
971    ///
972    /// ```rust
973    /// # #![allow(dead_code)] // this example is quite impractical to test
974    /// use pyo3::prelude::*;
975    ///
976    /// # fn main() {
977    /// #[pyfunction]
978    /// fn loop_forever(py: Python<'_>) -> PyResult<()> {
979    ///     loop {
980    ///         // As this loop is infinite it should check for signals every once in a while.
981    ///         // Using `?` causes any `PyErr` (potentially containing `KeyboardInterrupt`)
982    ///         // to break out of the loop.
983    ///         py.check_signals()?;
984    ///
985    ///         // do work here
986    ///         # break Ok(()) // don't actually loop forever
987    ///     }
988    /// }
989    /// # }
990    /// ```
991    ///
992    /// # Note
993    ///
994    /// This function calls [`PyErr_CheckSignals()`][1] which in turn may call signal handlers.
995    /// As Python's [`signal`][2] API allows users to define custom signal handlers, calling this
996    /// function allows arbitrary Python code inside signal handlers to run.
997    ///
998    /// If the function is called from a non-main thread, or under a non-main Python interpreter,
999    /// it does nothing yet still returns `Ok(())`.
1000    ///
1001    /// [1]: https://docs.python.org/3/c-api/exceptions.html?highlight=pyerr_checksignals#c.PyErr_CheckSignals
1002    /// [2]: https://docs.python.org/3/library/signal.html
1003    pub fn check_signals(self) -> PyResult<()> {
1004        err::error_on_minusone(self, unsafe { ffi::PyErr_CheckSignals() })
1005    }
1006
1007    /// Create a new pool for managing PyO3's GIL Refs. This has no functional
1008    /// use for code which does not use the deprecated GIL Refs API.
1009    ///
1010    /// When this `GILPool` is dropped, all GIL Refs created after this `GILPool` will
1011    /// all have their Python reference counts decremented, potentially allowing Python to drop
1012    /// the corresponding Python objects.
1013    ///
1014    /// Typical usage of PyO3 will not need this API, as [`Python::with_gil`] automatically creates
1015    /// a `GILPool` where appropriate.
1016    ///
1017    /// Advanced uses of PyO3 which perform long-running tasks which never free the GIL may need
1018    /// to use this API to clear memory, as PyO3 usually does not clear memory until the GIL is
1019    /// released.
1020    ///
1021    /// # Examples
1022    ///
1023    /// ```rust
1024    /// # use pyo3::prelude::*;
1025    /// Python::with_gil(|py| {
1026    ///     // Some long-running process like a webserver, which never releases the GIL.
1027    ///     loop {
1028    ///         // Create a new pool, so that PyO3 can clear memory at the end of the loop.
1029    ///         #[allow(deprecated)]  // `new_pool` is not needed in code not using the GIL Refs API
1030    ///         let pool = unsafe { py.new_pool() };
1031    ///
1032    ///         // It is recommended to *always* immediately set py to the pool's Python, to help
1033    ///         // avoid creating references with invalid lifetimes.
1034    ///         let py = pool.python();
1035    ///
1036    ///         // do stuff...
1037    /// #       break;  // Exit the loop so that doctest terminates!
1038    ///     }
1039    /// });
1040    /// ```
1041    ///
1042    /// # Safety
1043    ///
1044    /// Extreme care must be taken when using this API, as misuse can lead to accessing invalid
1045    /// memory. In addition, the caller is responsible for guaranteeing that the GIL remains held
1046    /// for the entire lifetime of the returned `GILPool`.
1047    ///
1048    /// Two best practices are required when using this API:
1049    /// - From the moment `new_pool()` is called, only the `Python` token from the returned
1050    ///   `GILPool` (accessible using [`.python()`]) should be used in PyO3 APIs. All other older
1051    ///   `Python` tokens with longer lifetimes are unsafe to use until the `GILPool` is dropped,
1052    ///   because they can be used to create PyO3 owned references which have lifetimes which
1053    ///   outlive the `GILPool`.
1054    /// - Similarly, methods on existing owned references will implicitly refer back to the
1055    ///   `Python` token which that reference was originally created with. If the returned values
1056    ///   from these methods are owned references they will inherit the same lifetime. As a result,
1057    ///   Rust's lifetime rules may allow them to outlive the `GILPool`, even though this is not
1058    ///   safe for reasons discussed above. Care must be taken to never access these return values
1059    ///   after the `GILPool` is dropped, unless they are converted to `Py<T>` *before* the pool
1060    ///   is dropped.
1061    ///
1062    /// [`.python()`]: crate::GILPool::python
1063    #[inline]
1064    #[cfg(feature = "gil-refs")]
1065    #[deprecated(
1066        since = "0.21.0",
1067        note = "code not using the GIL Refs API can safely remove use of `Python::new_pool`"
1068    )]
1069    #[allow(deprecated)]
1070    pub unsafe fn new_pool(self) -> GILPool {
1071        GILPool::new()
1072    }
1073}
1074
1075impl Python<'_> {
1076    /// Creates a scope using a new pool for managing PyO3's GIL Refs. This has no functional
1077    /// use for code which does not use the deprecated GIL Refs API.
1078    ///
1079    /// This is a safe alterantive to [`new_pool`][Self::new_pool] as
1080    /// it limits the closure to using the new GIL token at the cost of
1081    /// being unable to capture existing GIL-bound references.
1082    ///
1083    /// Note that on stable Rust, this API suffers from the same the `SendWrapper` loophole
1084    /// as [`allow_threads`][Self::allow_threads], c.f. the documentation of the [`Ungil`] trait,
1085    ///
1086    /// # Examples
1087    ///
1088    /// ```rust
1089    /// # use pyo3::prelude::*;
1090    /// Python::with_gil(|py| {
1091    ///     // Some long-running process like a webserver, which never releases the GIL.
1092    ///     loop {
1093    ///         // Create a new scope, so that PyO3 can clear memory at the end of the loop.
1094    ///         #[allow(deprecated)]  // `with_pool` is not needed in code not using the GIL Refs API
1095    ///         py.with_pool(|py| {
1096    ///             // do stuff...
1097    ///         });
1098    /// #       break;  // Exit the loop so that doctest terminates!
1099    ///     }
1100    /// });
1101    /// ```
1102    ///
1103    /// The `Ungil` bound on the closure does prevent hanging on to existing GIL-bound references
1104    ///
1105    /// ```compile_fail
1106    /// # #![allow(deprecated)]
1107    /// # use pyo3::prelude::*;
1108    /// # use pyo3::types::PyString;
1109    ///
1110    /// Python::with_gil(|py| {
1111    ///     let old_str = PyString::new(py, "a message from the past");
1112    ///
1113    ///     py.with_pool(|_py| {
1114    ///         print!("{:?}", old_str);
1115    ///     });
1116    /// });
1117    /// ```
1118    ///
1119    /// or continuing to use the old GIL token
1120    ///
1121    /// ```compile_fail
1122    /// # use pyo3::prelude::*;
1123    ///
1124    /// Python::with_gil(|old_py| {
1125    ///     old_py.with_pool(|_new_py| {
1126    ///         let _none = old_py.None();
1127    ///     });
1128    /// });
1129    /// ```
1130    #[inline]
1131    #[cfg(feature = "gil-refs")]
1132    #[deprecated(
1133        since = "0.21.0",
1134        note = "code not using the GIL Refs API can safely remove use of `Python::with_pool`"
1135    )]
1136    #[allow(deprecated)]
1137    pub fn with_pool<F, R>(&self, f: F) -> R
1138    where
1139        F: for<'py> FnOnce(Python<'py>) -> R + Ungil,
1140    {
1141        // SAFETY: The closure is `Ungil`,
1142        // i.e. it does not capture any GIL-bound references
1143        // and accesses only the newly created GIL token.
1144        let pool = unsafe { GILPool::new() };
1145
1146        f(pool.python())
1147    }
1148}
1149
1150impl<'unbound> Python<'unbound> {
1151    /// Unsafely creates a Python token with an unbounded lifetime.
1152    ///
1153    /// Many of PyO3 APIs use `Python<'_>` as proof that the GIL is held, but this function can be
1154    /// used to call them unsafely.
1155    ///
1156    /// # Safety
1157    ///
1158    /// - This token and any borrowed Python references derived from it can only be safely used
1159    ///   whilst the currently executing thread is actually holding the GIL.
1160    /// - This function creates a token with an *unbounded* lifetime. Safe code can assume that
1161    ///   holding a `Python<'py>` token means the GIL is and stays acquired for the lifetime `'py`.
1162    ///   If you let it or borrowed Python references escape to safe code you are
1163    ///   responsible for bounding the lifetime `'unbound` appropriately. For more on unbounded
1164    ///   lifetimes, see the [nomicon].
1165    ///
1166    /// [nomicon]: https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html
1167    #[inline]
1168    pub unsafe fn assume_gil_acquired() -> Python<'unbound> {
1169        Python(PhantomData)
1170    }
1171}
1172
1173#[cfg(test)]
1174mod tests {
1175    use super::*;
1176    use crate::types::{IntoPyDict, PyList};
1177
1178    #[test]
1179    fn test_eval() {
1180        Python::with_gil(|py| {
1181            // Make sure builtin names are accessible
1182            let v: i32 = py
1183                .eval_bound("min(1, 2)", None, None)
1184                .map_err(|e| e.display(py))
1185                .unwrap()
1186                .extract()
1187                .unwrap();
1188            assert_eq!(v, 1);
1189
1190            let d = [("foo", 13)].into_py_dict_bound(py);
1191
1192            // Inject our own global namespace
1193            let v: i32 = py
1194                .eval_bound("foo + 29", Some(&d), None)
1195                .unwrap()
1196                .extract()
1197                .unwrap();
1198            assert_eq!(v, 42);
1199
1200            // Inject our own local namespace
1201            let v: i32 = py
1202                .eval_bound("foo + 29", None, Some(&d))
1203                .unwrap()
1204                .extract()
1205                .unwrap();
1206            assert_eq!(v, 42);
1207
1208            // Make sure builtin names are still accessible when using a local namespace
1209            let v: i32 = py
1210                .eval_bound("min(foo, 2)", None, Some(&d))
1211                .unwrap()
1212                .extract()
1213                .unwrap();
1214            assert_eq!(v, 2);
1215        });
1216    }
1217
1218    #[test]
1219    #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
1220    fn test_allow_threads_releases_and_acquires_gil() {
1221        Python::with_gil(|py| {
1222            let b = std::sync::Arc::new(std::sync::Barrier::new(2));
1223
1224            let b2 = b.clone();
1225            std::thread::spawn(move || Python::with_gil(|_| b2.wait()));
1226
1227            py.allow_threads(|| {
1228                // If allow_threads does not release the GIL, this will deadlock because
1229                // the thread spawned above will never be able to acquire the GIL.
1230                b.wait();
1231            });
1232
1233            unsafe {
1234                // If the GIL is not reacquired at the end of allow_threads, this call
1235                // will crash the Python interpreter.
1236                let tstate = ffi::PyEval_SaveThread();
1237                ffi::PyEval_RestoreThread(tstate);
1238            }
1239        });
1240    }
1241
1242    #[test]
1243    fn test_allow_threads_panics_safely() {
1244        Python::with_gil(|py| {
1245            let result = std::panic::catch_unwind(|| unsafe {
1246                let py = Python::assume_gil_acquired();
1247                py.allow_threads(|| {
1248                    panic!("There was a panic!");
1249                });
1250            });
1251
1252            // Check panic was caught
1253            assert!(result.is_err());
1254
1255            // If allow_threads is implemented correctly, this thread still owns the GIL here
1256            // so the following Python calls should not cause crashes.
1257            let list = PyList::new_bound(py, [1, 2, 3, 4]);
1258            assert_eq!(list.extract::<Vec<i32>>().unwrap(), vec![1, 2, 3, 4]);
1259        });
1260    }
1261
1262    #[cfg(not(pyo3_disable_reference_pool))]
1263    #[test]
1264    fn test_allow_threads_pass_stuff_in() {
1265        let list = Python::with_gil(|py| PyList::new_bound(py, vec!["foo", "bar"]).unbind());
1266        let mut v = vec![1, 2, 3];
1267        let a = std::sync::Arc::new(String::from("foo"));
1268
1269        Python::with_gil(|py| {
1270            py.allow_threads(|| {
1271                drop((list, &mut v, a));
1272            });
1273        });
1274    }
1275
1276    #[test]
1277    #[cfg(not(Py_LIMITED_API))]
1278    fn test_acquire_gil() {
1279        const GIL_NOT_HELD: c_int = 0;
1280        const GIL_HELD: c_int = 1;
1281
1282        // Before starting the interpreter the state of calling `PyGILState_Check`
1283        // seems to be undefined, so let's ensure that Python is up.
1284        #[cfg(not(any(PyPy, GraalPy)))]
1285        crate::prepare_freethreaded_python();
1286
1287        let state = unsafe { crate::ffi::PyGILState_Check() };
1288        assert_eq!(state, GIL_NOT_HELD);
1289
1290        Python::with_gil(|_| {
1291            let state = unsafe { crate::ffi::PyGILState_Check() };
1292            assert_eq!(state, GIL_HELD);
1293        });
1294
1295        let state = unsafe { crate::ffi::PyGILState_Check() };
1296        assert_eq!(state, GIL_NOT_HELD);
1297    }
1298
1299    #[test]
1300    fn test_ellipsis() {
1301        Python::with_gil(|py| {
1302            assert_eq!(py.Ellipsis().to_string(), "Ellipsis");
1303
1304            let v = py
1305                .eval_bound("...", None, None)
1306                .map_err(|e| e.display(py))
1307                .unwrap();
1308
1309            assert!(v.eq(py.Ellipsis()).unwrap());
1310        });
1311    }
1312
1313    #[test]
1314    fn test_py_run_inserts_globals() {
1315        use crate::types::dict::PyDictMethods;
1316
1317        Python::with_gil(|py| {
1318            let namespace = PyDict::new_bound(py);
1319            py.run_bound("class Foo: pass", Some(&namespace), Some(&namespace))
1320                .unwrap();
1321            assert!(matches!(namespace.get_item("Foo"), Ok(Some(..))));
1322            assert!(matches!(namespace.get_item("__builtins__"), Ok(Some(..))));
1323        })
1324    }
1325}