Update MSRV to 1.63 (#4129)
* Bump MSRV to 1.63 * Drop parking_lot in favor of std::sync * Make portable-atomic dep conditional * Remove no longer required cfg
This commit is contained in:
parent
6fb972b232
commit
9e1960ea34
|
@ -54,7 +54,7 @@ jobs:
|
||||||
name: Prepare LD_LIBRARY_PATH (Ubuntu only)
|
name: Prepare LD_LIBRARY_PATH (Ubuntu only)
|
||||||
run: echo LD_LIBRARY_PATH=${pythonLocation}/lib >> $GITHUB_ENV
|
run: echo LD_LIBRARY_PATH=${pythonLocation}/lib >> $GITHUB_ENV
|
||||||
|
|
||||||
- if: inputs.rust == '1.56.0'
|
- if: inputs.rust == '1.63.0'
|
||||||
name: Prepare minimal package versions (MSRV only)
|
name: Prepare minimal package versions (MSRV only)
|
||||||
run: nox -s set-minimal-package-versions
|
run: nox -s set-minimal-package-versions
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@master
|
- uses: dtolnay/rust-toolchain@master
|
||||||
with:
|
with:
|
||||||
toolchain: 1.56.0
|
toolchain: 1.63.0
|
||||||
targets: x86_64-unknown-linux-gnu
|
targets: x86_64-unknown-linux-gnu
|
||||||
components: rust-src
|
components: rust-src
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
|
@ -255,7 +255,7 @@ jobs:
|
||||||
]
|
]
|
||||||
include:
|
include:
|
||||||
# Test minimal supported Rust version
|
# Test minimal supported Rust version
|
||||||
- rust: 1.56.0
|
- rust: 1.63.0
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
platform:
|
platform:
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,14 +12,12 @@ categories = ["api-bindings", "development-tools::ffi"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
exclude = ["/.gitignore", ".cargo/config", "/codecov.yml", "/Makefile", "/pyproject.toml", "/noxfile.py", "/.github", "/tests/test_compile_error.rs", "/tests/ui"]
|
exclude = ["/.gitignore", ".cargo/config", "/codecov.yml", "/Makefile", "/pyproject.toml", "/noxfile.py", "/.github", "/tests/test_compile_error.rs", "/tests/ui"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.56"
|
rust-version = "1.63"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
libc = "0.2.62"
|
libc = "0.2.62"
|
||||||
parking_lot = ">= 0.11, < 0.13"
|
|
||||||
memoffset = "0.9"
|
memoffset = "0.9"
|
||||||
portable-atomic = "1.0"
|
|
||||||
|
|
||||||
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently
|
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently
|
||||||
pyo3-ffi = { path = "pyo3-ffi", version = "=0.21.2" }
|
pyo3-ffi = { path = "pyo3-ffi", version = "=0.21.2" }
|
||||||
|
@ -46,6 +44,9 @@ rust_decimal = { version = "1.0.0", default-features = false, optional = true }
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
smallvec = { version = "1.0", optional = true }
|
smallvec = { version = "1.0", optional = true }
|
||||||
|
|
||||||
|
[target.'cfg(not(target_has_atomic = "64"))'.dependencies]
|
||||||
|
portable-atomic = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_approx_eq = "1.1.0"
|
assert_approx_eq = "1.1.0"
|
||||||
chrono = "0.4.25"
|
chrono = "0.4.25"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[![benchmark](https://img.shields.io/badge/benchmark-✓-Green?logo=github)](https://pyo3.rs/dev/bench/)
|
[![benchmark](https://img.shields.io/badge/benchmark-✓-Green?logo=github)](https://pyo3.rs/dev/bench/)
|
||||||
[![codecov](https://img.shields.io/codecov/c/gh/PyO3/pyo3?logo=codecov)](https://codecov.io/gh/PyO3/pyo3)
|
[![codecov](https://img.shields.io/codecov/c/gh/PyO3/pyo3?logo=codecov)](https://codecov.io/gh/PyO3/pyo3)
|
||||||
[![crates.io](https://img.shields.io/crates/v/pyo3?logo=rust)](https://crates.io/crates/pyo3)
|
[![crates.io](https://img.shields.io/crates/v/pyo3?logo=rust)](https://crates.io/crates/pyo3)
|
||||||
[![minimum rustc 1.56](https://img.shields.io/badge/rustc-1.56+-blue?logo=rust)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
|
[![minimum rustc 1.63](https://img.shields.io/badge/rustc-1.63+-blue?logo=rust)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
|
||||||
[![discord server](https://img.shields.io/discord/1209263839632424990?logo=discord)](https://discord.gg/33kcChzH7f)
|
[![discord server](https://img.shields.io/discord/1209263839632424990?logo=discord)](https://discord.gg/33kcChzH7f)
|
||||||
[![contributing notes](https://img.shields.io/badge/contribute-on%20github-Green?logo=github)](https://github.com/PyO3/pyo3/blob/main/Contributing.md)
|
[![contributing notes](https://img.shields.io/badge/contribute-on%20github-Green?logo=github)](https://github.com/PyO3/pyo3/blob/main/Contributing.md)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
PyO3 supports the following software versions:
|
PyO3 supports the following software versions:
|
||||||
- Python 3.7 and up (CPython, PyPy, and GraalPy)
|
- Python 3.7 and up (CPython, PyPy, and GraalPy)
|
||||||
- Rust 1.56 and up
|
- Rust 1.63 and up
|
||||||
|
|
||||||
You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.
|
You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.
|
||||||
|
|
||||||
|
|
2
build.rs
2
build.rs
|
@ -39,7 +39,7 @@ fn configure_pyo3() -> Result<()> {
|
||||||
println!("{}", cfg)
|
println!("{}", cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit cfgs like `thread_local_const_init`
|
// Emit cfgs like `invalid_from_utf8_lint`
|
||||||
print_feature_cfgs();
|
print_feature_cfgs();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -151,7 +151,7 @@ rustflags = [
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, on rust >= 1.56, one can include in `build.rs`:
|
Alternatively, one can include in `build.rs`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -6,7 +6,7 @@ To get started using PyO3 you will need three things: a Rust toolchain, a Python
|
||||||
|
|
||||||
## Rust
|
## Rust
|
||||||
|
|
||||||
First, make sure you have Rust installed on your system. If you haven't already done so, try following the instructions [here](https://www.rust-lang.org/tools/install). PyO3 runs on both the `stable` and `nightly` versions so you can choose whichever one fits you best. The minimum required Rust version is 1.56.
|
First, make sure you have Rust installed on your system. If you haven't already done so, try following the instructions [here](https://www.rust-lang.org/tools/install). PyO3 runs on both the `stable` and `nightly` versions so you can choose whichever one fits you best. The minimum required Rust version is 1.63.
|
||||||
|
|
||||||
If you can run `rustc --version` and the version is new enough you're good to go!
|
If you can run `rustc --version` and the version is new enough you're good to go!
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Raised the MSRV to 1.63
|
21
noxfile.py
21
noxfile.py
|
@ -557,22 +557,11 @@ def set_minimal_package_versions(session: nox.Session):
|
||||||
"examples/word-count",
|
"examples/word-count",
|
||||||
)
|
)
|
||||||
min_pkg_versions = {
|
min_pkg_versions = {
|
||||||
"rust_decimal": "1.26.1",
|
"regex": "1.9.6",
|
||||||
"csv": "1.1.6",
|
"proptest": "1.2.0",
|
||||||
"indexmap": "1.6.2",
|
"trybuild": "1.0.89",
|
||||||
"hashbrown": "0.9.1",
|
"eyre": "0.6.8",
|
||||||
"log": "0.4.17",
|
"allocator-api2": "0.2.10",
|
||||||
"once_cell": "1.17.2",
|
|
||||||
"rayon": "1.6.1",
|
|
||||||
"rayon-core": "1.10.2",
|
|
||||||
"regex": "1.7.3",
|
|
||||||
"proptest": "1.0.0",
|
|
||||||
"chrono": "0.4.25",
|
|
||||||
"byteorder": "1.4.3",
|
|
||||||
"crossbeam-channel": "0.5.8",
|
|
||||||
"crossbeam-deque": "0.8.3",
|
|
||||||
"crossbeam-epoch": "0.9.15",
|
|
||||||
"crossbeam-utils": "0.8.16",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# run cargo update first to ensure that everything is at highest
|
# run cargo update first to ensure that everything is at highest
|
||||||
|
|
|
@ -145,11 +145,6 @@ pub fn print_feature_cfgs() {
|
||||||
|
|
||||||
let rustc_minor_version = rustc_minor_version().unwrap_or(0);
|
let rustc_minor_version = rustc_minor_version().unwrap_or(0);
|
||||||
|
|
||||||
// Enable use of const initializer for thread_local! on Rust 1.59 and greater
|
|
||||||
if rustc_minor_version >= 59 {
|
|
||||||
println!("cargo:rustc-cfg=thread_local_const_init");
|
|
||||||
}
|
|
||||||
|
|
||||||
// invalid_from_utf8 lint was added in Rust 1.74
|
// invalid_from_utf8 lint was added in Rust 1.74
|
||||||
if rustc_minor_version >= 74 {
|
if rustc_minor_version >= 74 {
|
||||||
println!("cargo:rustc-cfg=invalid_from_utf8_lint");
|
println!("cargo:rustc-cfg=invalid_from_utf8_lint");
|
||||||
|
|
|
@ -14,7 +14,7 @@ Manual][capi] for up-to-date documentation.
|
||||||
|
|
||||||
PyO3 supports the following software versions:
|
PyO3 supports the following software versions:
|
||||||
- Python 3.7 and up (CPython and PyPy)
|
- Python 3.7 and up (CPython and PyPy)
|
||||||
- Rust 1.56 and up
|
- Rust 1.63 and up
|
||||||
|
|
||||||
# Example: Building Python Native modules
|
# Example: Building Python Native modules
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ fn configure_pyo3() -> Result<()> {
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit cfgs like `thread_local_const_init`
|
// Emit cfgs like `invalid_from_utf8_lint`
|
||||||
print_feature_cfgs();
|
print_feature_cfgs();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
//!
|
//!
|
||||||
//! PyO3 supports the following software versions:
|
//! PyO3 supports the following software versions:
|
||||||
//! - Python 3.7 and up (CPython and PyPy)
|
//! - Python 3.7 and up (CPython and PyPy)
|
||||||
//! - Rust 1.56 and up
|
//! - Rust 1.63 and up
|
||||||
//!
|
//!
|
||||||
//! # Example: Building Python Native modules
|
//! # Example: Building Python Native modules
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::{Py, PyAny, PyObject};
|
use crate::{Py, PyAny, PyObject};
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
use std::task::{Context, Poll, Waker};
|
use std::task::{Context, Poll, Waker};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -25,12 +24,12 @@ impl CancelHandle {
|
||||||
|
|
||||||
/// Returns whether the associated coroutine has been cancelled.
|
/// Returns whether the associated coroutine has been cancelled.
|
||||||
pub fn is_cancelled(&self) -> bool {
|
pub fn is_cancelled(&self) -> bool {
|
||||||
self.0.lock().exception.is_some()
|
self.0.lock().unwrap().exception.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Poll to retrieve the exception thrown in the associated coroutine.
|
/// Poll to retrieve the exception thrown in the associated coroutine.
|
||||||
pub fn poll_cancelled(&mut self, cx: &mut Context<'_>) -> Poll<PyObject> {
|
pub fn poll_cancelled(&mut self, cx: &mut Context<'_>) -> Poll<PyObject> {
|
||||||
let mut inner = self.0.lock();
|
let mut inner = self.0.lock().unwrap();
|
||||||
if let Some(exc) = inner.exception.take() {
|
if let Some(exc) = inner.exception.take() {
|
||||||
return Poll::Ready(exc);
|
return Poll::Ready(exc);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +68,7 @@ pub struct ThrowCallback(Arc<Mutex<Inner>>);
|
||||||
|
|
||||||
impl ThrowCallback {
|
impl ThrowCallback {
|
||||||
pub(super) fn throw(&self, exc: Py<PyAny>) {
|
pub(super) fn throw(&self, exc: Py<PyAny>) {
|
||||||
let mut inner = self.0.lock();
|
let mut inner = self.0.lock().unwrap();
|
||||||
inner.exception = Some(exc);
|
inner.exception = Some(exc);
|
||||||
if let Some(waker) = inner.waker.take() {
|
if let Some(waker) = inner.waker.take() {
|
||||||
waker.wake();
|
waker.wake();
|
||||||
|
|
67
src/gil.rs
67
src/gil.rs
|
@ -2,29 +2,16 @@
|
||||||
|
|
||||||
use crate::impl_::not_send::{NotSend, NOT_SEND};
|
use crate::impl_::not_send::{NotSend, NOT_SEND};
|
||||||
use crate::{ffi, Python};
|
use crate::{ffi, Python};
|
||||||
use parking_lot::{const_mutex, Mutex, Once};
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::{mem, ptr::NonNull};
|
use std::{mem, ptr::NonNull, sync};
|
||||||
|
|
||||||
static START: Once = Once::new();
|
static START: sync::Once = sync::Once::new();
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
std::thread_local! {
|
||||||
if #[cfg(thread_local_const_init)] {
|
|
||||||
use std::thread_local as thread_local_const_init;
|
|
||||||
} else {
|
|
||||||
macro_rules! thread_local_const_init {
|
|
||||||
($($(#[$attr:meta])* static $name:ident: $ty:ty = const { $init:expr };)*) => (
|
|
||||||
thread_local! { $($(#[$attr])* static $name: $ty = $init;)* }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local_const_init! {
|
|
||||||
/// This is an internal counter in pyo3 monitoring whether this thread has the GIL.
|
/// This is an internal counter in pyo3 monitoring whether this thread has the GIL.
|
||||||
///
|
///
|
||||||
/// It will be incremented whenever a GILGuard or GILPool is created, and decremented whenever
|
/// It will be incremented whenever a GILGuard or GILPool is created, and decremented whenever
|
||||||
|
@ -249,26 +236,26 @@ type PyObjVec = Vec<NonNull<ffi::PyObject>>;
|
||||||
/// Thread-safe storage for objects which were inc_ref / dec_ref while the GIL was not held.
|
/// Thread-safe storage for objects which were inc_ref / dec_ref while the GIL was not held.
|
||||||
struct ReferencePool {
|
struct ReferencePool {
|
||||||
// .0 is INCREFs, .1 is DECREFs
|
// .0 is INCREFs, .1 is DECREFs
|
||||||
pointer_ops: Mutex<(PyObjVec, PyObjVec)>,
|
pointer_ops: sync::Mutex<(PyObjVec, PyObjVec)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReferencePool {
|
impl ReferencePool {
|
||||||
const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
pointer_ops: const_mutex((Vec::new(), Vec::new())),
|
pointer_ops: sync::Mutex::new((Vec::new(), Vec::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_incref(&self, obj: NonNull<ffi::PyObject>) {
|
fn register_incref(&self, obj: NonNull<ffi::PyObject>) {
|
||||||
self.pointer_ops.lock().0.push(obj);
|
self.pointer_ops.lock().unwrap().0.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_decref(&self, obj: NonNull<ffi::PyObject>) {
|
fn register_decref(&self, obj: NonNull<ffi::PyObject>) {
|
||||||
self.pointer_ops.lock().1.push(obj);
|
self.pointer_ops.lock().unwrap().1.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_counts(&self, _py: Python<'_>) {
|
fn update_counts(&self, _py: Python<'_>) {
|
||||||
let mut ops = self.pointer_ops.lock();
|
let mut ops = self.pointer_ops.lock().unwrap();
|
||||||
if ops.0.is_empty() && ops.1.is_empty() {
|
if ops.0.is_empty() && ops.1.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -523,9 +510,9 @@ mod tests {
|
||||||
use super::{gil_is_acquired, GIL_COUNT, OWNED_OBJECTS, POOL};
|
use super::{gil_is_acquired, GIL_COUNT, OWNED_OBJECTS, POOL};
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::{ffi, gil, PyObject, Python};
|
use crate::{ffi, gil, PyObject, Python};
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
use parking_lot::{const_mutex, Condvar, Mutex};
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
use std::sync;
|
||||||
|
|
||||||
fn get_object(py: Python<'_>) -> PyObject {
|
fn get_object(py: Python<'_>) -> PyObject {
|
||||||
py.eval_bound("object()", None, None).unwrap().unbind()
|
py.eval_bound("object()", None, None).unwrap().unbind()
|
||||||
|
@ -543,6 +530,7 @@ mod tests {
|
||||||
!POOL
|
!POOL
|
||||||
.pointer_ops
|
.pointer_ops
|
||||||
.lock()
|
.lock()
|
||||||
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
@ -551,6 +539,7 @@ mod tests {
|
||||||
!POOL
|
!POOL
|
||||||
.pointer_ops
|
.pointer_ops
|
||||||
.lock()
|
.lock()
|
||||||
|
.unwrap()
|
||||||
.1
|
.1
|
||||||
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
@ -559,6 +548,7 @@ mod tests {
|
||||||
fn pool_dec_refs_contains(obj: &PyObject) -> bool {
|
fn pool_dec_refs_contains(obj: &PyObject) -> bool {
|
||||||
POOL.pointer_ops
|
POOL.pointer_ops
|
||||||
.lock()
|
.lock()
|
||||||
|
.unwrap()
|
||||||
.1
|
.1
|
||||||
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
.contains(&unsafe { NonNull::new_unchecked(obj.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
@ -671,8 +661,8 @@ mod tests {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
assert_eq!(obj.get_refcnt(py), 1);
|
assert_eq!(obj.get_refcnt(py), 1);
|
||||||
let non_null = unsafe { NonNull::new_unchecked(obj.as_ptr()) };
|
let non_null = unsafe { NonNull::new_unchecked(obj.as_ptr()) };
|
||||||
assert!(!POOL.pointer_ops.lock().0.contains(&non_null));
|
assert!(!POOL.pointer_ops.lock().unwrap().0.contains(&non_null));
|
||||||
assert!(!POOL.pointer_ops.lock().1.contains(&non_null));
|
assert!(!POOL.pointer_ops.lock().unwrap().1.contains(&non_null));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,29 +760,30 @@ mod tests {
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
struct Event {
|
struct Event {
|
||||||
set: Mutex<bool>,
|
set: sync::Mutex<bool>,
|
||||||
wait: Condvar,
|
wait: sync::Condvar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
impl Event {
|
impl Event {
|
||||||
const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
set: const_mutex(false),
|
set: sync::Mutex::new(false),
|
||||||
wait: Condvar::new(),
|
wait: sync::Condvar::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set(&self) {
|
fn set(&self) {
|
||||||
*self.set.lock() = true;
|
*self.set.lock().unwrap() = true;
|
||||||
self.wait.notify_all();
|
self.wait.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait(&self) {
|
fn wait(&self) {
|
||||||
let mut set = self.set.lock();
|
drop(
|
||||||
while !*set {
|
self.wait
|
||||||
self.wait.wait(&mut set);
|
.wait_while(self.set.lock().unwrap(), |s| !*s)
|
||||||
}
|
.unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,16 +882,16 @@ mod tests {
|
||||||
|
|
||||||
// The pointer should appear once in the incref pool, and once in the
|
// The pointer should appear once in the incref pool, and once in the
|
||||||
// decref pool (for the clone being created and also dropped)
|
// decref pool (for the clone being created and also dropped)
|
||||||
assert!(POOL.pointer_ops.lock().0.contains(&ptr));
|
assert!(POOL.pointer_ops.lock().unwrap().0.contains(&ptr));
|
||||||
assert!(POOL.pointer_ops.lock().1.contains(&ptr));
|
assert!(POOL.pointer_ops.lock().unwrap().1.contains(&ptr));
|
||||||
|
|
||||||
(obj, count, ptr)
|
(obj, count, ptr)
|
||||||
});
|
});
|
||||||
|
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
// Acquiring the gil clears the pool
|
// Acquiring the gil clears the pool
|
||||||
assert!(!POOL.pointer_ops.lock().0.contains(&ptr));
|
assert!(!POOL.pointer_ops.lock().unwrap().0.contains(&ptr));
|
||||||
assert!(!POOL.pointer_ops.lock().1.contains(&ptr));
|
assert!(!POOL.pointer_ops.lock().unwrap().1.contains(&ptr));
|
||||||
|
|
||||||
// Overall count is still unchanged
|
// Overall count is still unchanged
|
||||||
assert_eq!(count, obj.get_refcnt(py));
|
assert_eq!(count, obj.get_refcnt(py));
|
||||||
|
|
|
@ -5,9 +5,17 @@ use std::{cell::UnsafeCell, marker::PhantomData};
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(any(PyPy, GraalPy)),
|
not(any(PyPy, GraalPy)),
|
||||||
Py_3_9,
|
Py_3_9,
|
||||||
not(all(windows, Py_LIMITED_API, not(Py_3_10)))
|
not(all(windows, Py_LIMITED_API, not(Py_3_10))),
|
||||||
|
not(target_has_atomic = "64"),
|
||||||
))]
|
))]
|
||||||
use portable_atomic::{AtomicI64, Ordering};
|
use portable_atomic::{AtomicI64, Ordering};
|
||||||
|
#[cfg(all(
|
||||||
|
not(any(PyPy, GraalPy)),
|
||||||
|
Py_3_9,
|
||||||
|
not(all(windows, Py_LIMITED_API, not(Py_3_10))),
|
||||||
|
target_has_atomic = "64",
|
||||||
|
))]
|
||||||
|
use std::sync::atomic::{AtomicI64, Ordering};
|
||||||
|
|
||||||
#[cfg(not(any(PyPy, GraalPy)))]
|
#[cfg(not(any(PyPy, GraalPy)))]
|
||||||
use crate::exceptions::PyImportError;
|
use crate::exceptions::PyImportError;
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
//!
|
//!
|
||||||
//! PyO3 supports the following software versions:
|
//! PyO3 supports the following software versions:
|
||||||
//! - Python 3.7 and up (CPython and PyPy)
|
//! - Python 3.7 and up (CPython and PyPy)
|
||||||
//! - Rust 1.56 and up
|
//! - Rust 1.63 and up
|
||||||
//!
|
//!
|
||||||
//! # Example: Building a native Python module
|
//! # Example: Building a native Python module
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use std::{task::Poll, thread, time::Duration};
|
use std::{task::Poll, thread, time::Duration};
|
||||||
|
|
||||||
use futures::{channel::oneshot, future::poll_fn, FutureExt};
|
use futures::{channel::oneshot, future::poll_fn, FutureExt};
|
||||||
|
#[cfg(not(target_has_atomic = "64"))]
|
||||||
use portable_atomic::{AtomicBool, Ordering};
|
use portable_atomic::{AtomicBool, Ordering};
|
||||||
use pyo3::{
|
use pyo3::{
|
||||||
coroutine::CancelHandle,
|
coroutine::CancelHandle,
|
||||||
|
@ -10,6 +11,8 @@ use pyo3::{
|
||||||
py_run,
|
py_run,
|
||||||
types::{IntoPyDict, PyType},
|
types::{IntoPyDict, PyType},
|
||||||
};
|
};
|
||||||
|
#[cfg(target_has_atomic = "64")]
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
#[path = "../src/tests/common.rs"]
|
#[path = "../src/tests/common.rs"]
|
||||||
mod common;
|
mod common;
|
||||||
|
|
Loading…
Reference in New Issue