Merge #3209
3209: Remove the conditional compilation flags which are made redundant by the MSRV bump r=davidhewitt a=adamreichold Co-authored-by: Adam Reichold <adam.reichold@t-online.de>
This commit is contained in:
commit
e1f028f3e5
|
@ -44,7 +44,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
toolchain: 1.56.0
|
toolchain: 1.56.0
|
||||||
targets: x86_64-unknown-linux-gnu
|
targets: x86_64-unknown-linux-gnu
|
||||||
components: clippy,rust-src
|
components: rust-src
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
architecture: "x64"
|
architecture: "x64"
|
||||||
|
|
|
@ -48,9 +48,7 @@ chrono = { version = "0.4" }
|
||||||
criterion = "0.3.5"
|
criterion = "0.3.5"
|
||||||
# Required for "and $N others" normalization
|
# Required for "and $N others" normalization
|
||||||
trybuild = ">=1.0.70"
|
trybuild = ">=1.0.70"
|
||||||
rustversion = "1.0"
|
proptest = { version = "1.0", default-features = false, features = ["std"] }
|
||||||
# 1.0.0 requires Rust 1.50
|
|
||||||
proptest = { version = "0.10.1", default-features = false, features = ["std"] }
|
|
||||||
send_wrapper = "0.6"
|
send_wrapper = "0.6"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0.61"
|
serde_json = "1.0.61"
|
||||||
|
|
2
build.rs
2
build.rs
|
@ -46,7 +46,7 @@ fn configure_pyo3() -> Result<()> {
|
||||||
|
|
||||||
ensure_auto_initialize_ok(interpreter_config)?;
|
ensure_auto_initialize_ok(interpreter_config)?;
|
||||||
|
|
||||||
// Emit cfgs like `addr_of` and `min_const_generics`
|
// Emit cfgs like `thread_local_const_init`
|
||||||
print_feature_cfgs();
|
print_feature_cfgs();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -435,6 +435,7 @@ def set_minimal_package_versions(session: nox.Session):
|
||||||
"rayon": "1.6.1",
|
"rayon": "1.6.1",
|
||||||
"rayon-core": "1.10.2",
|
"rayon-core": "1.10.2",
|
||||||
"regex": "1.7.3",
|
"regex": "1.7.3",
|
||||||
|
"proptest": "1.0.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
# run cargo update first to ensure that everything is at highest
|
# run cargo update first to ensure that everything is at highest
|
||||||
|
|
|
@ -142,30 +142,10 @@ 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 generics on Rust 1.51 and greater
|
|
||||||
if rustc_minor_version >= 51 {
|
|
||||||
println!("cargo:rustc-cfg=min_const_generics");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable use of std::ptr::addr_of! on Rust 1.51 and greater
|
|
||||||
if rustc_minor_version >= 51 {
|
|
||||||
println!("cargo:rustc-cfg=addr_of");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable use of Option::insert on Rust 1.53 and greater
|
|
||||||
if rustc_minor_version >= 53 {
|
|
||||||
println!("cargo:rustc-cfg=option_insert");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable use of const initializer for thread_local! on Rust 1.59 and greater
|
// Enable use of const initializer for thread_local! on Rust 1.59 and greater
|
||||||
if rustc_minor_version >= 59 {
|
if rustc_minor_version >= 59 {
|
||||||
println!("cargo:rustc-cfg=thread_local_const_init");
|
println!("cargo:rustc-cfg=thread_local_const_init");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable use of `#[cfg(panic = "...")]` on Rust 1.60 and greater
|
|
||||||
if rustc_minor_version >= 60 {
|
|
||||||
println!("cargo:rustc-cfg=panic_unwind");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Private exports used in PyO3's build.rs
|
/// Private exports used in PyO3's build.rs
|
||||||
|
|
|
@ -100,7 +100,7 @@ fn configure_pyo3() -> Result<()> {
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit cfgs like `addr_of` and `min_const_generics`
|
// Emit cfgs like `thread_local_const_init`
|
||||||
print_feature_cfgs();
|
print_feature_cfgs();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::longobject::PyLongObject;
|
use crate::longobject::PyLongObject;
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::{c_int, c_long};
|
use std::os::raw::{c_int, c_long};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -10,7 +11,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyBool_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyBool_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
|
@ -23,12 +24,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn Py_False() -> *mut PyObject {
|
pub unsafe fn Py_False() -> *mut PyObject {
|
||||||
addr_of_mut_shim!(_Py_FalseStruct) as *mut PyLongObject as *mut PyObject
|
addr_of_mut!(_Py_FalseStruct) as *mut PyLongObject as *mut PyObject
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn Py_True() -> *mut PyObject {
|
pub unsafe fn Py_True() -> *mut PyObject {
|
||||||
addr_of_mut_shim!(_Py_TrueStruct) as *mut PyLongObject as *mut PyObject
|
addr_of_mut!(_Py_TrueStruct) as *mut PyLongObject as *mut PyObject
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(not(any(PyPy, Py_LIMITED_API)))]
|
#[cfg(not(any(PyPy, Py_LIMITED_API)))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -29,12 +30,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyByteArray_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyByteArray_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyByteArray_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyByteArray_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -16,7 +17,7 @@ pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyBytes_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyBytes_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::{c_double, c_int};
|
use std::os::raw::{c_double, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -40,12 +41,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyComplex_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyComplex_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyComplex_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyComplex_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::{PyObject, PyTypeObject, Py_TYPE};
|
use crate::object::{PyObject, PyTypeObject, Py_TYPE};
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub static mut PyContext_Type: PyTypeObject;
|
pub static mut PyContext_Type: PyTypeObject;
|
||||||
|
@ -12,17 +13,17 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyContext_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyContext_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyContextVar_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyContextVar_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyContextToken_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyContextToken_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -3,6 +3,8 @@ use crate::pyport::Py_ssize_t;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::os::raw::{c_char, c_int, c_uchar, c_void};
|
use std::os::raw::{c_char, c_int, c_uchar, c_void};
|
||||||
|
#[cfg(not(PyPy))]
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
// skipped _Py_CODEUNIT
|
// skipped _Py_CODEUNIT
|
||||||
// skipped _Py_OPCODE
|
// skipped _Py_OPCODE
|
||||||
|
@ -159,7 +161,7 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyCode_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::pystate::PyThreadState;
|
||||||
#[cfg(not(any(PyPy, Py_3_11)))]
|
#[cfg(not(any(PyPy, Py_3_11)))]
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(not(any(PyPy, Py_3_11)))]
|
#[cfg(not(any(PyPy, Py_3_11)))]
|
||||||
pub type PyFrameState = c_char;
|
pub type PyFrameState = c_char;
|
||||||
|
@ -64,7 +65,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyFrame_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyFrame_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
#[cfg(not(all(PyPy, not(Py_3_8))))]
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
use crate::PyObject;
|
use crate::PyObject;
|
||||||
|
|
||||||
|
@ -61,7 +63,7 @@ extern "C" {
|
||||||
#[cfg(not(all(PyPy, not(Py_3_8))))]
|
#[cfg(not(all(PyPy, not(Py_3_8))))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int {
|
||||||
(crate::Py_TYPE(op) == addr_of_mut_shim!(PyFunction_Type)) as c_int
|
(crate::Py_TYPE(op) == addr_of_mut!(PyFunction_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::_PyErr_StackItem;
|
||||||
#[cfg(Py_3_11)]
|
#[cfg(Py_3_11)]
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -41,12 +42,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyGen_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyGen_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyGen_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyGen_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -71,7 +72,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCoro_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyCoro_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipped _PyCoro_GetAwaitableIter
|
// skipped _PyCoro_GetAwaitableIter
|
||||||
|
@ -91,7 +92,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyAsyncGen_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyAsyncGen_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipped _PyAsyncGenValueWrapperNew
|
// skipped _PyAsyncGenValueWrapperNew
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC};
|
use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
pub struct PyCMethodObject {
|
pub struct PyCMethodObject {
|
||||||
pub func: PyCFunctionObject,
|
pub func: PyCFunctionObject,
|
||||||
|
@ -14,12 +15,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyCMethod_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyCMethod_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCMethod_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyCMethod_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -15,7 +16,7 @@ pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyDict_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyDict_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -76,17 +77,17 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyDictKeys_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyDictKeys_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyDictValues_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyDictValues_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyDictItems_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyDictItems_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::{c_double, c_int};
|
use std::os::raw::{c_double, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(Py_LIMITED_API)]
|
#[cfg(Py_LIMITED_API)]
|
||||||
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
|
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
|
||||||
|
@ -20,12 +21,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyFloat_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyFloat_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyFloat_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyFloat_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipped Py_RETURN_NAN
|
// skipped Py_RETURN_NAN
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -9,7 +10,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PySeqIter_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PySeqIter_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -19,7 +20,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyCallIter_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyCallIter_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -258,19 +258,6 @@ macro_rules! opaque_struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! addr_of_mut_shim {
|
|
||||||
($place:expr) => {{
|
|
||||||
#[cfg(addr_of)]
|
|
||||||
{
|
|
||||||
::std::ptr::addr_of_mut!($place)
|
|
||||||
}
|
|
||||||
#[cfg(not(addr_of))]
|
|
||||||
{
|
|
||||||
&mut $place as *mut _
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use self::abstract_::*;
|
pub use self::abstract_::*;
|
||||||
pub use self::bltinmodule::*;
|
pub use self::bltinmodule::*;
|
||||||
pub use self::boolobject::*;
|
pub use self::boolobject::*;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -17,7 +18,7 @@ pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyList_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyList_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use libc::size_t;
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
use std::os::raw::c_uchar;
|
use std::os::raw::c_uchar;
|
||||||
use std::os::raw::{c_char, c_double, c_int, c_long, c_longlong, c_ulong, c_ulonglong, c_void};
|
use std::os::raw::{c_char, c_double, c_int, c_long, c_longlong, c_ulong, c_ulonglong, c_void};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
opaque_struct!(PyLongObject);
|
opaque_struct!(PyLongObject);
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyLong_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyLong_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -13,7 +14,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyMemoryView_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyMemoryView_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipped non-limited PyMemoryView_GET_BUFFER
|
// skipped non-limited PyMemoryView_GET_BUFFER
|
||||||
|
|
|
@ -24,19 +24,19 @@ extern "C" {
|
||||||
#[cfg(Py_3_9)]
|
#[cfg(Py_3_9)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyCFunction_Type)) as c_int
|
(Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(Py_3_9)]
|
#[cfg(Py_3_9)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCFunction_Type))
|
PyObject_TypeCheck(op, ptr::addr_of_mut!(PyCFunction_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(Py_3_9))]
|
#[cfg(not(Py_3_9))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyCFunction_Type)) as c_int
|
(Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PyCFunction =
|
pub type PyCFunction =
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::methodobject::PyMethodDef;
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::{c_char, c_int, c_void};
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -11,12 +12,12 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(PyModule_Type))
|
PyObject_TypeCheck(op, addr_of_mut!(PyModule_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyModule_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyModule_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -488,7 +488,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn Py_None() -> *mut PyObject {
|
pub unsafe fn Py_None() -> *mut PyObject {
|
||||||
addr_of_mut_shim!(_Py_NoneStruct)
|
ptr::addr_of_mut!(_Py_NoneStruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -506,7 +506,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn Py_NotImplemented() -> *mut PyObject {
|
pub unsafe fn Py_NotImplemented() -> *mut PyObject {
|
||||||
addr_of_mut_shim!(_Py_NotImplementedStruct)
|
ptr::addr_of_mut!(_Py_NotImplementedStruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipped Py_RETURN_NOTIMPLEMENTED
|
// skipped Py_RETURN_NOTIMPLEMENTED
|
||||||
|
@ -554,5 +554,5 @@ pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyType_Type)) as c_int
|
(Py_TYPE(op) == ptr::addr_of_mut!(PyType_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::{c_char, c_int, c_void};
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -11,7 +12,7 @@ pub type PyCapsule_Destructor = unsafe extern "C" fn(o: *mut PyObject);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(ob) == addr_of_mut_shim!(PyCapsule_Type)) as c_int
|
(Py_TYPE(ob) == addr_of_mut!(PyCapsule_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -11,5 +12,5 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyRange_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyRange_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyRange_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyRange_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::object::*;
|
||||||
use crate::pyport::Py_hash_t;
|
use crate::pyport::Py_hash_t;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
pub const PySet_MINSIZE: usize = 8;
|
pub const PySet_MINSIZE: usize = 8;
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(ob) == addr_of_mut_shim!(PyFrozenSet_Type)) as c_int
|
(Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -105,8 +106,8 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(ob) == addr_of_mut_shim!(PyFrozenSet_Type)
|
(Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)
|
||||||
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut_shim!(PyFrozenSet_Type)) != 0) as c_int
|
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -118,21 +119,21 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(ob) == addr_of_mut_shim!(PySet_Type)
|
(Py_TYPE(ob) == addr_of_mut!(PySet_Type) || Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type))
|
||||||
|| Py_TYPE(ob) == addr_of_mut_shim!(PyFrozenSet_Type)) as c_int
|
as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int {
|
||||||
(PyAnySet_CheckExact(ob) != 0
|
(PyAnySet_CheckExact(ob) != 0
|
||||||
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut_shim!(PySet_Type)) != 0
|
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0
|
||||||
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut_shim!(PyFrozenSet_Type)) != 0) as c_int
|
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(Py_3_10)]
|
#[cfg(Py_3_10)]
|
||||||
pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
crate::Py_IS_TYPE(op, addr_of_mut_shim!(PySet_Type))
|
crate::Py_IS_TYPE(op, addr_of_mut!(PySet_Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -144,6 +145,6 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int {
|
pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(ob) == addr_of_mut_shim!(PySet_Type)
|
(Py_TYPE(ob) == addr_of_mut!(PySet_Type)
|
||||||
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut_shim!(PySet_Type)) != 0) as c_int
|
|| PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0) as c_int
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -10,7 +11,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn Py_Ellipsis() -> *mut PyObject {
|
pub unsafe fn Py_Ellipsis() -> *mut PyObject {
|
||||||
addr_of_mut_shim!(_Py_EllipsisObject)
|
addr_of_mut!(_Py_EllipsisObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
@ -31,7 +32,7 @@ extern "C" {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PySlice_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PySlice_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
#[cfg(not(PyPy))]
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Here")]
|
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Here")]
|
||||||
|
@ -21,5 +23,5 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyTraceBack_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyTraceBack_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -16,7 +17,7 @@ pub unsafe fn PyTuple_Check(op: *mut PyObject) -> c_int {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyTuple_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyTuple_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -2,6 +2,8 @@ use crate::object::*;
|
||||||
use crate::pyport::Py_ssize_t;
|
use crate::pyport::Py_ssize_t;
|
||||||
use libc::wchar_t;
|
use libc::wchar_t;
|
||||||
use std::os::raw::{c_char, c_int, c_void};
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
|
#[cfg(not(PyPy))]
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
pub type Py_UNICODE = wchar_t;
|
pub type Py_UNICODE = wchar_t;
|
||||||
|
@ -34,7 +36,7 @@ pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(PyUnicode_Type)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(PyUnicode_Type)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD;
|
pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::object::*;
|
use crate::object::*;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
#[cfg(not(PyPy))]
|
||||||
|
use std::ptr::addr_of_mut;
|
||||||
|
|
||||||
#[cfg(all(not(PyPy), Py_LIMITED_API))]
|
#[cfg(all(not(PyPy), Py_LIMITED_API))]
|
||||||
opaque_struct!(PyWeakReference);
|
opaque_struct!(PyWeakReference);
|
||||||
|
@ -29,20 +31,20 @@ extern "C" {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, addr_of_mut_shim!(_PyWeakref_RefType))
|
PyObject_TypeCheck(op, addr_of_mut!(_PyWeakref_RefType))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int {
|
||||||
(Py_TYPE(op) == addr_of_mut_shim!(_PyWeakref_RefType)) as c_int
|
(Py_TYPE(op) == addr_of_mut!(_PyWeakref_RefType)) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int {
|
||||||
((Py_TYPE(op) == addr_of_mut_shim!(_PyWeakref_ProxyType))
|
((Py_TYPE(op) == addr_of_mut!(_PyWeakref_ProxyType))
|
||||||
|| (Py_TYPE(op) == addr_of_mut_shim!(_PyWeakref_CallableProxyType))) as c_int
|
|| (Py_TYPE(op) == addr_of_mut!(_PyWeakref_CallableProxyType))) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,308 +1,118 @@
|
||||||
|
use crate::conversion::{AsPyPointer, IntoPyPointer};
|
||||||
|
use crate::types::PySequence;
|
||||||
use crate::{exceptions, PyErr};
|
use crate::{exceptions, PyErr};
|
||||||
|
use crate::{
|
||||||
|
ffi, FromPyObject, IntoPy, Py, PyAny, PyDowncastError, PyObject, PyResult, Python, ToPyObject,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(min_const_generics)]
|
impl<T, const N: usize> IntoPy<PyObject> for [T; N]
|
||||||
mod min_const_generics {
|
where
|
||||||
use super::invalid_sequence_length;
|
T: IntoPy<PyObject>,
|
||||||
use crate::conversion::{AsPyPointer, IntoPyPointer};
|
{
|
||||||
use crate::types::PySequence;
|
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||||
use crate::{
|
|
||||||
ffi, FromPyObject, IntoPy, Py, PyAny, PyDowncastError, PyObject, PyResult, Python,
|
|
||||||
ToPyObject,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<T, const N: usize> IntoPy<PyObject> for [T; N]
|
|
||||||
where
|
|
||||||
T: IntoPy<PyObject>,
|
|
||||||
{
|
|
||||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
|
||||||
unsafe {
|
|
||||||
#[allow(deprecated)] // we're not on edition 2021 yet
|
|
||||||
let elements = std::array::IntoIter::new(self);
|
|
||||||
let len = N as ffi::Py_ssize_t;
|
|
||||||
|
|
||||||
let ptr = ffi::PyList_New(len);
|
|
||||||
|
|
||||||
// We create the `Py` pointer here for two reasons:
|
|
||||||
// - panics if the ptr is null
|
|
||||||
// - its Drop cleans up the list if user code panics.
|
|
||||||
let list: Py<PyAny> = Py::from_owned_ptr(py, ptr);
|
|
||||||
|
|
||||||
for (i, obj) in (0..len).zip(elements) {
|
|
||||||
let obj = obj.into_py(py).into_ptr();
|
|
||||||
|
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
|
||||||
ffi::PyList_SET_ITEM(ptr, i, obj);
|
|
||||||
#[cfg(Py_LIMITED_API)]
|
|
||||||
ffi::PyList_SetItem(ptr, i, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, const N: usize> ToPyObject for [T; N]
|
|
||||||
where
|
|
||||||
T: ToPyObject,
|
|
||||||
{
|
|
||||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
|
||||||
self.as_ref().to_object(py)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, const N: usize> FromPyObject<'a> for [T; N]
|
|
||||||
where
|
|
||||||
T: FromPyObject<'a>,
|
|
||||||
{
|
|
||||||
fn extract(obj: &'a PyAny) -> PyResult<Self> {
|
|
||||||
create_array_from_obj(obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_array_from_obj<'s, T, const N: usize>(obj: &'s PyAny) -> PyResult<[T; N]>
|
|
||||||
where
|
|
||||||
T: FromPyObject<'s>,
|
|
||||||
{
|
|
||||||
// Types that pass `PySequence_Check` usually implement enough of the sequence protocol
|
|
||||||
// to support this function and if not, we will only fail extraction safely.
|
|
||||||
let seq: &PySequence = unsafe {
|
|
||||||
if ffi::PySequence_Check(obj.as_ptr()) != 0 {
|
|
||||||
obj.downcast_unchecked()
|
|
||||||
} else {
|
|
||||||
return Err(PyDowncastError::new(obj, "Sequence").into());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let seq_len = seq.len()?;
|
|
||||||
if seq_len != N {
|
|
||||||
return Err(invalid_sequence_length(N, seq_len));
|
|
||||||
}
|
|
||||||
array_try_from_fn(|idx| seq.get_item(idx).and_then(PyAny::extract))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO use std::array::try_from_fn, if that stabilises:
|
|
||||||
// (https://github.com/rust-lang/rust/pull/75644)
|
|
||||||
fn array_try_from_fn<E, F, T, const N: usize>(mut cb: F) -> Result<[T; N], E>
|
|
||||||
where
|
|
||||||
F: FnMut(usize) -> Result<T, E>,
|
|
||||||
{
|
|
||||||
// Helper to safely create arrays since the standard library doesn't
|
|
||||||
// provide one yet. Shouldn't be necessary in the future.
|
|
||||||
struct ArrayGuard<T, const N: usize> {
|
|
||||||
dst: *mut T,
|
|
||||||
initialized: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, const N: usize> Drop for ArrayGuard<T, N> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
debug_assert!(self.initialized <= N);
|
|
||||||
let initialized_part =
|
|
||||||
core::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
|
|
||||||
unsafe {
|
|
||||||
core::ptr::drop_in_place(initialized_part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// [MaybeUninit<T>; N] would be "nicer" but is actually difficult to create - there are nightly
|
|
||||||
// APIs which would make this easier.
|
|
||||||
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
|
|
||||||
let mut guard: ArrayGuard<T, N> = ArrayGuard {
|
|
||||||
dst: array.as_mut_ptr() as _,
|
|
||||||
initialized: 0,
|
|
||||||
};
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut value_ptr = array.as_mut_ptr() as *mut T;
|
#[allow(deprecated)] // we're not on edition 2021 yet
|
||||||
for i in 0..N {
|
let elements = std::array::IntoIter::new(self);
|
||||||
core::ptr::write(value_ptr, cb(i)?);
|
let len = N as ffi::Py_ssize_t;
|
||||||
value_ptr = value_ptr.offset(1);
|
|
||||||
guard.initialized += 1;
|
let ptr = ffi::PyList_New(len);
|
||||||
|
|
||||||
|
// We create the `Py` pointer here for two reasons:
|
||||||
|
// - panics if the ptr is null
|
||||||
|
// - its Drop cleans up the list if user code panics.
|
||||||
|
let list: Py<PyAny> = Py::from_owned_ptr(py, ptr);
|
||||||
|
|
||||||
|
for (i, obj) in (0..len).zip(elements) {
|
||||||
|
let obj = obj.into_py(py).into_ptr();
|
||||||
|
|
||||||
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
ffi::PyList_SET_ITEM(ptr, i, obj);
|
||||||
|
#[cfg(Py_LIMITED_API)]
|
||||||
|
ffi::PyList_SetItem(ptr, i, obj);
|
||||||
}
|
}
|
||||||
core::mem::forget(guard);
|
|
||||||
Ok(array.assume_init())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
list
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::{
|
|
||||||
panic,
|
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn array_try_from_fn() {
|
|
||||||
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
|
||||||
struct CountDrop;
|
|
||||||
impl Drop for CountDrop {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _ = catch_unwind_silent(move || {
|
|
||||||
let _: Result<[CountDrop; 4], ()> = super::array_try_from_fn(|idx| {
|
|
||||||
#[allow(clippy::manual_assert)]
|
|
||||||
if idx == 2 {
|
|
||||||
panic!("peek a boo");
|
|
||||||
}
|
|
||||||
Ok(CountDrop)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_extract_bytearray_to_array() {
|
|
||||||
Python::with_gil(|py| {
|
|
||||||
let v: [u8; 33] = py
|
|
||||||
.eval(
|
|
||||||
"bytearray(b'abcabcabcabcabcabcabcabcabcabcabc')",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.extract()
|
|
||||||
.unwrap();
|
|
||||||
assert!(&v == b"abcabcabcabcabcabcabcabcabcabcabc");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/59211505
|
|
||||||
fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
|
|
||||||
where
|
|
||||||
F: FnOnce() -> R + panic::UnwindSafe,
|
|
||||||
{
|
|
||||||
let prev_hook = panic::take_hook();
|
|
||||||
panic::set_hook(Box::new(|_| {}));
|
|
||||||
let result = panic::catch_unwind(f);
|
|
||||||
panic::set_hook(prev_hook);
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(min_const_generics))]
|
impl<T, const N: usize> ToPyObject for [T; N]
|
||||||
mod array_impls {
|
where
|
||||||
use super::invalid_sequence_length;
|
T: ToPyObject,
|
||||||
use crate::conversion::{AsPyPointer, IntoPyPointer};
|
{
|
||||||
use crate::types::PySequence;
|
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||||
use crate::{
|
self.as_ref().to_object(py)
|
||||||
ffi, FromPyObject, IntoPy, Py, PyAny, PyDowncastError, PyObject, PyResult, Python,
|
}
|
||||||
ToPyObject,
|
}
|
||||||
|
|
||||||
|
impl<'a, T, const N: usize> FromPyObject<'a> for [T; N]
|
||||||
|
where
|
||||||
|
T: FromPyObject<'a>,
|
||||||
|
{
|
||||||
|
fn extract(obj: &'a PyAny) -> PyResult<Self> {
|
||||||
|
create_array_from_obj(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_array_from_obj<'s, T, const N: usize>(obj: &'s PyAny) -> PyResult<[T; N]>
|
||||||
|
where
|
||||||
|
T: FromPyObject<'s>,
|
||||||
|
{
|
||||||
|
// Types that pass `PySequence_Check` usually implement enough of the sequence protocol
|
||||||
|
// to support this function and if not, we will only fail extraction safely.
|
||||||
|
let seq: &PySequence = unsafe {
|
||||||
|
if ffi::PySequence_Check(obj.as_ptr()) != 0 {
|
||||||
|
obj.downcast_unchecked()
|
||||||
|
} else {
|
||||||
|
return Err(PyDowncastError::new(obj, "Sequence").into());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
use std::mem::{transmute_copy, ManuallyDrop};
|
let seq_len = seq.len()?;
|
||||||
|
if seq_len != N {
|
||||||
|
return Err(invalid_sequence_length(N, seq_len));
|
||||||
|
}
|
||||||
|
array_try_from_fn(|idx| seq.get_item(idx).and_then(PyAny::extract))
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! array_impls {
|
// TODO use std::array::try_from_fn, if that stabilises:
|
||||||
($($N:expr),+) => {
|
// (https://github.com/rust-lang/rust/pull/75644)
|
||||||
$(
|
fn array_try_from_fn<E, F, T, const N: usize>(mut cb: F) -> Result<[T; N], E>
|
||||||
impl<T> IntoPy<PyObject> for [T; $N]
|
where
|
||||||
where
|
F: FnMut(usize) -> Result<T, E>,
|
||||||
T: IntoPy<PyObject>
|
{
|
||||||
{
|
// Helper to safely create arrays since the standard library doesn't
|
||||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
// provide one yet. Shouldn't be necessary in the future.
|
||||||
|
struct ArrayGuard<T, const N: usize> {
|
||||||
|
dst: *mut T,
|
||||||
|
initialized: usize,
|
||||||
|
}
|
||||||
|
|
||||||
struct ArrayGuard<T> {
|
impl<T, const N: usize> Drop for ArrayGuard<T, N> {
|
||||||
elements: [ManuallyDrop<T>; $N],
|
fn drop(&mut self) {
|
||||||
start: usize,
|
debug_assert!(self.initialized <= N);
|
||||||
}
|
let initialized_part = core::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
|
||||||
|
unsafe {
|
||||||
impl<T> Drop for ArrayGuard<T> {
|
core::ptr::drop_in_place(initialized_part);
|
||||||
fn drop(&mut self) {
|
}
|
||||||
unsafe {
|
|
||||||
let needs_drop = self.elements.get_mut(self.start..).unwrap();
|
|
||||||
for item in needs_drop {
|
|
||||||
ManuallyDrop::drop(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let ptr = ffi::PyList_New($N as ffi::Py_ssize_t);
|
|
||||||
|
|
||||||
// We create the `Py` pointer here for two reasons:
|
|
||||||
// - panics if the ptr is null
|
|
||||||
// - its Drop cleans up the list if user code panics.
|
|
||||||
let list: Py<PyAny> = Py::from_owned_ptr(py, ptr);
|
|
||||||
|
|
||||||
let slf = ManuallyDrop::new(self);
|
|
||||||
|
|
||||||
let mut guard = ArrayGuard {
|
|
||||||
// the transmute size check is _very_ dumb around generics
|
|
||||||
elements: transmute_copy(&slf),
|
|
||||||
start: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 0..$N {
|
|
||||||
let obj: T = ManuallyDrop::take(&mut guard.elements[i]);
|
|
||||||
guard.start += 1;
|
|
||||||
|
|
||||||
let obj = obj.into_py(py).into_ptr();
|
|
||||||
|
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
|
||||||
ffi::PyList_SET_ITEM(ptr, i as ffi::Py_ssize_t, obj);
|
|
||||||
#[cfg(Py_LIMITED_API)]
|
|
||||||
ffi::PyList_SetItem(ptr, i as ffi::Py_ssize_t, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::mem::forget(guard);
|
|
||||||
|
|
||||||
list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ToPyObject for [T; $N]
|
|
||||||
where
|
|
||||||
T: ToPyObject,
|
|
||||||
{
|
|
||||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
|
||||||
self.as_ref().to_object(py)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> FromPyObject<'a> for [T; $N]
|
|
||||||
where
|
|
||||||
T: Copy + Default + FromPyObject<'a>,
|
|
||||||
{
|
|
||||||
fn extract(obj: &'a PyAny) -> PyResult<Self> {
|
|
||||||
let mut array = [T::default(); $N];
|
|
||||||
extract_sequence_into_slice(obj, &mut array)?;
|
|
||||||
Ok(array)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(min_const_generics))]
|
// [MaybeUninit<T>; N] would be "nicer" but is actually difficult to create - there are nightly
|
||||||
array_impls!(
|
// APIs which would make this easier.
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
|
||||||
25, 26, 27, 28, 29, 30, 31, 32
|
let mut guard: ArrayGuard<T, N> = ArrayGuard {
|
||||||
);
|
dst: array.as_mut_ptr() as _,
|
||||||
|
initialized: 0,
|
||||||
#[cfg(not(min_const_generics))]
|
};
|
||||||
fn extract_sequence_into_slice<'s, T>(obj: &'s PyAny, slice: &mut [T]) -> PyResult<()>
|
unsafe {
|
||||||
where
|
let mut value_ptr = array.as_mut_ptr() as *mut T;
|
||||||
T: FromPyObject<'s>,
|
for i in 0..N {
|
||||||
{
|
core::ptr::write(value_ptr, cb(i)?);
|
||||||
// Types that pass `PySequence_Check` usually implement enough of the sequence protocol
|
value_ptr = value_ptr.offset(1);
|
||||||
// to support this function and if not, we will only fail extraction safely.
|
guard.initialized += 1;
|
||||||
let seq: &PySequence = unsafe {
|
|
||||||
if ffi::PySequence_Check(obj.as_ptr()) != 0 {
|
|
||||||
obj.downcast_unchecked()
|
|
||||||
} else {
|
|
||||||
return Err(PyDowncastError::new(obj, "Sequence").into());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let seq_len = seq.len()?;
|
|
||||||
if seq_len != slice.len() {
|
|
||||||
return Err(invalid_sequence_length(slice.len(), seq_len));
|
|
||||||
}
|
}
|
||||||
for (value, item) in slice.iter_mut().zip(seq.iter()?) {
|
core::mem::forget(guard);
|
||||||
*value = item?.extract::<T>()?;
|
Ok(array.assume_init())
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,8 +125,50 @@ fn invalid_sequence_length(expected: usize, actual: usize) -> PyErr {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
panic,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{types::PyList, IntoPy, PyResult, Python, ToPyObject};
|
use crate::{types::PyList, IntoPy, PyResult, Python, ToPyObject};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_try_from_fn() {
|
||||||
|
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
struct CountDrop;
|
||||||
|
impl Drop for CountDrop {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = catch_unwind_silent(move || {
|
||||||
|
let _: Result<[CountDrop; 4], ()> = super::array_try_from_fn(|idx| {
|
||||||
|
#[allow(clippy::manual_assert)]
|
||||||
|
if idx == 2 {
|
||||||
|
panic!("peek a boo");
|
||||||
|
}
|
||||||
|
Ok(CountDrop)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extract_bytearray_to_array() {
|
||||||
|
Python::with_gil(|py| {
|
||||||
|
let v: [u8; 33] = py
|
||||||
|
.eval(
|
||||||
|
"bytearray(b'abcabcabcabcabcabcabcabcabcabcabc')",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.extract()
|
||||||
|
.unwrap();
|
||||||
|
assert!(&v == b"abcabcabcabcabcabcabcabcabcabcabc");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extract_small_bytearray_to_array() {
|
fn test_extract_small_bytearray_to_array() {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
|
@ -390,4 +242,16 @@ mod tests {
|
||||||
let _cell: &crate::PyCell<Foo> = list.get_item(4).unwrap().extract().unwrap();
|
let _cell: &crate::PyCell<Foo> = list.get_item(4).unwrap().extract().unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/59211505
|
||||||
|
fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> R + panic::UnwindSafe,
|
||||||
|
{
|
||||||
|
let prev_hook = panic::take_hook();
|
||||||
|
panic::set_hook(Box::new(|_| {}));
|
||||||
|
let result = panic::catch_unwind(f);
|
||||||
|
panic::set_hook(prev_hook);
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,6 @@ pub fn extract_pyclass_ref<'a, 'py: 'a, T: PyClass>(
|
||||||
obj: &'py PyAny,
|
obj: &'py PyAny,
|
||||||
holder: &'a mut Option<PyRef<'py, T>>,
|
holder: &'a mut Option<PyRef<'py, T>>,
|
||||||
) -> PyResult<&'a T> {
|
) -> PyResult<&'a T> {
|
||||||
#[cfg(not(option_insert))]
|
|
||||||
{
|
|
||||||
*holder = Some(obj.extract()?);
|
|
||||||
return Ok(holder.as_deref().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(option_insert)]
|
|
||||||
Ok(&*holder.insert(obj.extract()?))
|
Ok(&*holder.insert(obj.extract()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,13 +58,6 @@ pub fn extract_pyclass_ref_mut<'a, 'py: 'a, T: PyClass<Frozen = False>>(
|
||||||
obj: &'py PyAny,
|
obj: &'py PyAny,
|
||||||
holder: &'a mut Option<PyRefMut<'py, T>>,
|
holder: &'a mut Option<PyRefMut<'py, T>>,
|
||||||
) -> PyResult<&'a mut T> {
|
) -> PyResult<&'a mut T> {
|
||||||
#[cfg(not(option_insert))]
|
|
||||||
{
|
|
||||||
*holder = Some(obj.extract()?);
|
|
||||||
return Ok(holder.as_deref_mut().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(option_insert)]
|
|
||||||
Ok(&mut *holder.insert(obj.extract()?))
|
Ok(&mut *holder.insert(obj.extract()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,6 @@ fn recursive_class_attributes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(cfg_panic, cfg(panic = "unwind"))]
|
|
||||||
fn test_fallible_class_attribute() {
|
fn test_fallible_class_attribute() {
|
||||||
use pyo3::{exceptions::PyValueError, types::PyString};
|
use pyo3::{exceptions::PyValueError, types::PyString};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
#![cfg(feature = "macros")]
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use pyo3::types::IntoPyDict;
|
use pyo3::types::IntoPyDict;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[path = "../common.rs"]
|
#[path = "common.rs"]
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
|
@ -1,11 +0,0 @@
|
||||||
#![cfg(feature = "macros")]
|
|
||||||
|
|
||||||
//! Functionality which is not only not supported on MSRV,
|
|
||||||
//! but can't even be cfg-ed out on MSRV because the compiler doesn't support
|
|
||||||
//! the syntax.
|
|
||||||
|
|
||||||
#[rustversion::since(1.54)]
|
|
||||||
mod requires_1_54 {
|
|
||||||
|
|
||||||
include!("not_msrv/requires_1_54.rs");
|
|
||||||
}
|
|
|
@ -11,6 +11,5 @@ name = "xtask"
|
||||||
anyhow = "1.0.51"
|
anyhow = "1.0.51"
|
||||||
|
|
||||||
# Clap 3 requires MSRV 1.54
|
# Clap 3 requires MSRV 1.54
|
||||||
rustversion = "1.0"
|
|
||||||
structopt = { version = "0.3", default-features = false }
|
structopt = { version = "0.3", default-features = false }
|
||||||
clap = { version = "2" }
|
clap = { version = "2" }
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl Subcommand {
|
||||||
|
|
||||||
/// Run a command as a child process, inheriting stdin, stdout and stderr.
|
/// Run a command as a child process, inheriting stdin, stdout and stderr.
|
||||||
pub fn run(command: &mut Command) -> Result<()> {
|
pub fn run(command: &mut Command) -> Result<()> {
|
||||||
let command_str = format_command(command);
|
let command_str = format!("{:?}", command);
|
||||||
let github_actions = std::env::var_os("GITHUB_ACTIONS").is_some();
|
let github_actions = std::env::var_os("GITHUB_ACTIONS").is_some();
|
||||||
if github_actions {
|
if github_actions {
|
||||||
println!("::group::Running: {}", command_str);
|
println!("::group::Running: {}", command_str);
|
||||||
|
@ -135,7 +135,7 @@ pub fn run(command: &mut Command) -> Result<()> {
|
||||||
|
|
||||||
/// Like `run`, but does not inherit stdin, stdout and stderr.
|
/// Like `run`, but does not inherit stdin, stdout and stderr.
|
||||||
pub fn run_with_output(command: &mut Command) -> Result<Output> {
|
pub fn run_with_output(command: &mut Command) -> Result<Output> {
|
||||||
let command_str = format_command(command);
|
let command_str = format!("{:?}", command);
|
||||||
|
|
||||||
println!("Running: {}", command_str);
|
println!("Running: {}", command_str);
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,16 @@
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
// Replacement for str.split_once() on Rust older than 1.52
|
|
||||||
#[rustversion::before(1.52)]
|
|
||||||
pub fn split_once(s: &str, pat: char) -> Option<(&str, &str)> {
|
|
||||||
let mut iter = s.splitn(2, pat);
|
|
||||||
Some((iter.next()?, iter.next()?))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustversion::since(1.52)]
|
|
||||||
pub fn split_once(s: &str, pat: char) -> Option<(&str, &str)> {
|
|
||||||
s.split_once(pat)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustversion::since(1.57)]
|
|
||||||
pub fn format_command(command: &Command) -> String {
|
|
||||||
let mut buf = String::new();
|
|
||||||
buf.push('`');
|
|
||||||
buf.push_str(&command.get_program().to_string_lossy());
|
|
||||||
for arg in command.get_args() {
|
|
||||||
buf.push(' ');
|
|
||||||
buf.push_str(&arg.to_string_lossy());
|
|
||||||
}
|
|
||||||
buf.push('`');
|
|
||||||
buf
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustversion::before(1.57)]
|
|
||||||
pub fn format_command(command: &Command) -> String {
|
|
||||||
// Debug impl isn't as nice as the above, but will do on < 1.57
|
|
||||||
format!("{:?}", command)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_output(command: &mut Command) -> anyhow::Result<std::process::Output> {
|
pub fn get_output(command: &mut Command) -> anyhow::Result<std::process::Output> {
|
||||||
let output = command.output()?;
|
let output = command.output()?;
|
||||||
ensure! {
|
ensure! {
|
||||||
output.status.success(),
|
output.status.success(),
|
||||||
"process did not run successfully ({exit}): {command}",
|
"process did not run successfully ({exit}): {command:?}",
|
||||||
exit = match output.status.code() {
|
exit = match output.status.code() {
|
||||||
Some(code) => format!("exit code {}", code),
|
Some(code) => format!("exit code {}", code),
|
||||||
None => "terminated by signal".into(),
|
None => "terminated by signal".into(),
|
||||||
},
|
},
|
||||||
command = format_command(command),
|
command = command,
|
||||||
};
|
};
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue