diff --git a/newsfragments/5121.added.md b/newsfragments/5121.added.md new file mode 100644 index 00000000000..fd79e5a8ea7 --- /dev/null +++ b/newsfragments/5121.added.md @@ -0,0 +1 @@ +Add `PyBytes_AS_STRING` diff --git a/newsfragments/5121.changed.md b/newsfragments/5121.changed.md new file mode 100644 index 00000000000..49b317cb96b --- /dev/null +++ b/newsfragments/5121.changed.md @@ -0,0 +1,2 @@ +Enable vectorcall methods on GraalPy +Call Py_Is function on GraalPy diff --git a/pyo3-ffi/src/abstract_.rs b/pyo3-ffi/src/abstract_.rs index 84fb98a1b4e..59639d14de8 100644 --- a/pyo3-ffi/src/abstract_.rs +++ b/pyo3-ffi/src/abstract_.rs @@ -25,7 +25,6 @@ pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_ extern "C" { #[cfg(all( not(PyPy), - not(GraalPy), any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10 ))] #[cfg_attr(PyPy, link_name = "PyPyObject_CallNoArgs")] @@ -94,7 +93,7 @@ extern "C" { kwnames: *mut PyObject, ) -> *mut PyObject; - #[cfg(any(Py_3_12, all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy)))))] + #[cfg(any(Py_3_12, all(Py_3_9, not(any(Py_LIMITED_API, PyPy)))))] pub fn PyObject_VectorcallMethod( name: *mut PyObject, args: *const *mut PyObject, diff --git a/pyo3-ffi/src/compat/py_3_9.rs b/pyo3-ffi/src/compat/py_3_9.rs index 285f2b2ae7e..6b3521cc167 100644 --- a/pyo3-ffi/src/compat/py_3_9.rs +++ b/pyo3-ffi/src/compat/py_3_9.rs @@ -1,7 +1,6 @@ compat_function!( originally_defined_for(all( not(PyPy), - not(GraalPy), any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10 )); @@ -12,7 +11,7 @@ compat_function!( ); compat_function!( - originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy)))); + originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy)))); #[inline] pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { diff --git a/pyo3-ffi/src/cpython/abstract_.rs b/pyo3-ffi/src/cpython/abstract_.rs index 6ada1a754ef..b9d9dd47dc9 100644 --- a/pyo3-ffi/src/cpython/abstract_.rs +++ b/pyo3-ffi/src/cpython/abstract_.rs @@ -1,12 +1,12 @@ use crate::{PyObject, Py_ssize_t}; -#[cfg(any(all(Py_3_8, not(any(PyPy, GraalPy))), not(Py_3_11)))] +#[cfg(any(all(Py_3_8, not(PyPy)), not(Py_3_11)))] use std::os::raw::c_char; use std::os::raw::c_int; #[cfg(not(Py_3_11))] use crate::Py_buffer; -#[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] +#[cfg(all(Py_3_8, not(PyPy)))] use crate::{ vectorcallfunc, PyCallable_Check, PyThreadState, PyThreadState_GET, PyTuple_Check, PyType_HasFeature, Py_TPFLAGS_HAVE_VECTORCALL, @@ -23,7 +23,7 @@ extern "C" { const _PY_FASTCALL_SMALL_STACK: size_t = 5; extern "C" { - #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] + #[cfg(all(Py_3_8, not(PyPy)))] pub fn _Py_CheckFunctionResult( tstate: *mut PyThreadState, callable: *mut PyObject, @@ -31,7 +31,7 @@ extern "C" { where_: *const c_char, ) -> *mut PyObject; - #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] + #[cfg(all(Py_3_8, not(PyPy)))] pub fn _PyObject_MakeTpCall( tstate: *mut PyThreadState, callable: *mut PyObject, @@ -52,7 +52,7 @@ pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t { n.try_into().expect("cannot fail due to mask") } -#[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] +#[cfg(all(Py_3_8, not(PyPy)))] #[inline(always)] pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option { assert!(!callable.is_null()); @@ -67,7 +67,7 @@ pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option *mut PyObject { _PyObject_VectorcallTstate( @@ -166,7 +166,7 @@ extern "C" { pub fn _PyObject_CallNoArg(func: *mut PyObject) -> *mut PyObject; } -#[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] +#[cfg(all(Py_3_8, not(PyPy)))] #[inline(always)] pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { assert!(!arg.is_null()); @@ -177,7 +177,7 @@ pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *m _PyObject_VectorcallTstate(tstate, func, args, nargsf, std::ptr::null_mut()) } -#[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] +#[cfg(all(Py_3_9, not(PyPy)))] #[inline(always)] pub unsafe fn PyObject_CallMethodNoArgs( self_: *mut PyObject, @@ -191,7 +191,7 @@ pub unsafe fn PyObject_CallMethodNoArgs( ) } -#[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] +#[cfg(all(Py_3_9, not(PyPy)))] #[inline(always)] pub unsafe fn PyObject_CallMethodOneArg( self_: *mut PyObject, @@ -219,7 +219,7 @@ extern "C" { pub fn PyObject_LengthHint(o: *mut PyObject, arg1: Py_ssize_t) -> Py_ssize_t; #[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11 - #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] + #[cfg(all(Py_3_9, not(PyPy)))] pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int; } diff --git a/pyo3-ffi/src/cpython/bytesobject.rs b/pyo3-ffi/src/cpython/bytesobject.rs index dd78e646a12..9e233311ac1 100644 --- a/pyo3-ffi/src/cpython/bytesobject.rs +++ b/pyo3-ffi/src/cpython/bytesobject.rs @@ -1,6 +1,6 @@ use crate::object::*; use crate::Py_ssize_t; -#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] +#[cfg(not(Py_LIMITED_API))] use std::os::raw::c_char; use std::os::raw::c_int; @@ -23,3 +23,12 @@ extern "C" { #[cfg_attr(PyPy, link_name = "_PyPyBytes_Resize")] pub fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int; } + +#[cfg(not(Py_LIMITED_API))] +#[inline] +pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char { + #[cfg(not(any(PyPy, GraalPy)))] + return &(*op.cast::()).ob_sval as *const c_char; + #[cfg(any(PyPy, GraalPy))] + return crate::PyBytes_AsString(op); +} diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index 5fbf45db617..c4c5abc361c 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -147,13 +147,13 @@ pub struct PyVarObject { // skipped private _PyVarObject_CAST #[inline] -#[cfg(not(all(PyPy, Py_3_10)))] +#[cfg(not(any(GraalPy, all(PyPy, Py_3_10))))] #[cfg_attr(docsrs, doc(cfg(all())))] pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int { (x == y).into() } -#[cfg(all(PyPy, Py_3_10))] +#[cfg(any(GraalPy, all(PyPy, Py_3_10)))] #[cfg_attr(docsrs, doc(cfg(all())))] extern "C" { #[cfg_attr(PyPy, link_name = "PyPy_Is")] diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 4e2ce9c96e7..16e0c42f8b1 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -365,4 +365,19 @@ mod tests { assert_eq!(*b, py_string); }) } + + #[test] + #[cfg(not(Py_LIMITED_API))] + fn test_as_string() { + Python::with_gil(|py| { + let b = b"hello, world".as_slice(); + let py_bytes = PyBytes::new(py, b); + unsafe { + assert_eq!( + ffi::PyBytes_AsString(py_bytes.as_ptr()) as *const std::os::raw::c_char, + ffi::PyBytes_AS_STRING(py_bytes.as_ptr()) as *const std::os::raw::c_char + ); + } + }) + } }