@@ -185,84 +185,87 @@ pub unsafe trait Ungil {}
185
185
#[ cfg( not( feature = "nightly" ) ) ]
186
186
unsafe impl < T : Send > Ungil for T { }
187
187
188
- /// Types that are safe to access while the GIL is not held.
189
- ///
190
- /// # Safety
191
- ///
192
- /// The type must not carry borrowed Python references or, if it does, not allow access to them if
193
- /// the GIL is not held.
194
- ///
195
- /// See the [module-level documentation](self) for more information.
196
- ///
197
- /// # Examples
198
- ///
199
- /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g.
200
- ///
201
- /// ```compile_fail
202
- /// # use pyo3::prelude::*;
203
- /// # use pyo3::types::PyString;
204
- /// Python::with_gil(|py| {
205
- /// let string = PyString::new(py, "foo");
206
- ///
207
- /// py.allow_threads(|| {
208
- /// println!("{:?}", string);
209
- /// });
210
- /// });
211
- /// ```
212
- ///
213
- /// This applies to the GIL token `Python` itself as well, e.g.
214
- ///
215
- /// ```compile_fail
216
- /// # use pyo3::prelude::*;
217
- /// Python::with_gil(|py| {
218
- /// py.allow_threads(|| {
219
- /// drop(py);
220
- /// });
221
- /// });
222
- /// ```
223
- ///
224
- /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able
225
- /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
226
- ///
227
- /// ```compile_fail
228
- /// # use pyo3::prelude::*;
229
- /// # use pyo3::types::PyString;
230
- /// use send_wrapper::SendWrapper;
231
- ///
232
- /// Python::with_gil(|py| {
233
- /// let string = PyString::new(py, "foo");
234
- ///
235
- /// let wrapped = SendWrapper::new(string);
236
- ///
237
- /// py.allow_threads(|| {
238
- /// let sneaky: &PyString = *wrapped;
239
- ///
240
- /// println!("{:?}", sneaky);
241
- /// });
242
- /// });
243
- /// ```
244
- ///
245
- /// This also enables using non-[`Send`] types in `allow_threads`,
246
- /// at least if they are not also bound to the GIL:
247
- ///
248
- /// ```rust
249
- /// # use pyo3::prelude::*;
250
- /// use std::rc::Rc;
251
- ///
252
- /// Python::with_gil(|py| {
253
- /// let rc = Rc::new(42);
254
- ///
255
- /// py.allow_threads(|| {
256
- /// println!("{:?}", rc);
257
- /// });
258
- /// });
259
- /// ```
260
188
#[ cfg( feature = "nightly" ) ]
261
- pub unsafe auto trait Ungil { }
189
+ mod nightly {
190
+ macro_rules! define {
191
+ ( $( $tt: tt) * ) => { $( $tt) * }
192
+ }
262
193
263
- #[ cfg( feature = "nightly" ) ]
264
- mod negative_impls {
265
- use super :: Ungil ;
194
+ define ! {
195
+ /// Types that are safe to access while the GIL is not held.
196
+ ///
197
+ /// # Safety
198
+ ///
199
+ /// The type must not carry borrowed Python references or, if it does, not allow access to them if
200
+ /// the GIL is not held.
201
+ ///
202
+ /// See the [module-level documentation](self) for more information.
203
+ ///
204
+ /// # Examples
205
+ ///
206
+ /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g.
207
+ ///
208
+ /// ```compile_fail
209
+ /// # use pyo3::prelude::*;
210
+ /// # use pyo3::types::PyString;
211
+ /// Python::with_gil(|py| {
212
+ /// let string = PyString::new(py, "foo");
213
+ ///
214
+ /// py.allow_threads(|| {
215
+ /// println!("{:?}", string);
216
+ /// });
217
+ /// });
218
+ /// ```
219
+ ///
220
+ /// This applies to the GIL token `Python` itself as well, e.g.
221
+ ///
222
+ /// ```compile_fail
223
+ /// # use pyo3::prelude::*;
224
+ /// Python::with_gil(|py| {
225
+ /// py.allow_threads(|| {
226
+ /// drop(py);
227
+ /// });
228
+ /// });
229
+ /// ```
230
+ ///
231
+ /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able
232
+ /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
233
+ ///
234
+ /// ```compile_fail
235
+ /// # use pyo3::prelude::*;
236
+ /// # use pyo3::types::PyString;
237
+ /// use send_wrapper::SendWrapper;
238
+ ///
239
+ /// Python::with_gil(|py| {
240
+ /// let string = PyString::new(py, "foo");
241
+ ///
242
+ /// let wrapped = SendWrapper::new(string);
243
+ ///
244
+ /// py.allow_threads(|| {
245
+ /// let sneaky: &PyString = *wrapped;
246
+ ///
247
+ /// println!("{:?}", sneaky);
248
+ /// });
249
+ /// });
250
+ /// ```
251
+ ///
252
+ /// This also enables using non-[`Send`] types in `allow_threads`,
253
+ /// at least if they are not also bound to the GIL:
254
+ ///
255
+ /// ```rust
256
+ /// # use pyo3::prelude::*;
257
+ /// use std::rc::Rc;
258
+ ///
259
+ /// Python::with_gil(|py| {
260
+ /// let rc = Rc::new(42);
261
+ ///
262
+ /// py.allow_threads(|| {
263
+ /// println!("{:?}", rc);
264
+ /// });
265
+ /// });
266
+ /// ```
267
+ pub unsafe auto trait Ungil { }
268
+ }
266
269
267
270
impl !Ungil for crate :: Python < ' _ > { }
268
271
@@ -289,6 +292,9 @@ mod negative_impls {
289
292
impl !Ungil for crate :: ffi:: PyArena { }
290
293
}
291
294
295
+ #[ cfg( feature = "nightly" ) ]
296
+ pub use nightly:: Ungil ;
297
+
292
298
/// A marker token that represents holding the GIL.
293
299
///
294
300
/// It serves three main purposes:
0 commit comments