Skip to content

Commit ad91a45

Browse files
bschoenmaeckersnewcomertv
authored andcommitted
add Py_HashBuffer to pyo3-ffi (PyO3#5086)
* add `Py_HashBuffer` to `pyo3-ffi` * Add `Py_HashBuffer` binding when 3.14+ * Move to `cpython/pyhash.rs` * Update changelog * Enable`Py_HashBuffer` compat on 3.14 abi3
1 parent 9a0b5df commit ad91a45

File tree

6 files changed

+63
-25
lines changed

6 files changed

+63
-25
lines changed

newsfragments/5086.added.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- add `Py_HashBuffer` to `pyo3-ffi`
2+
- add `Py_HashPointer` to `pyo3-ffi`
3+
- add `PyObject_GenericHash` to `pyo3-ffi`

pyo3-ffi/src/compat/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ macro_rules! compat_function {
5252

5353
mod py_3_10;
5454
mod py_3_13;
55+
mod py_3_14;
5556
mod py_3_9;
5657

5758
pub use self::py_3_10::*;
5859
pub use self::py_3_13::*;
60+
pub use self::py_3_14::*;
5961
pub use self::py_3_9::*;

pyo3-ffi/src/compat/py_3_14.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
compat_function!(
2+
originally_defined_for(all(Py_3_14, not(Py_LIMITED_API)));
3+
4+
#[inline]
5+
pub unsafe fn Py_HashBuffer(
6+
ptr: *const std::ffi::c_void,
7+
len: crate::Py_ssize_t,
8+
) -> crate::Py_hash_t {
9+
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
10+
{
11+
crate::_Py_HashBytes(ptr, len)
12+
}
13+
14+
#[cfg(any(Py_LIMITED_API, PyPy))]
15+
{
16+
let bytes = crate::PyBytes_FromStringAndSize(ptr as *const std::os::raw::c_char, len);
17+
if bytes.is_null() {
18+
-1
19+
} else {
20+
let result = crate::PyObject_Hash(bytes);
21+
crate::Py_DECREF(bytes);
22+
result
23+
}
24+
}
25+
}
26+
);

pyo3-ffi/src/cpython/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub(crate) mod pythonrun;
3838
// skipped sysmodule.h
3939
pub(crate) mod floatobject;
4040
pub(crate) mod pyframe;
41+
pub(crate) mod pyhash;
4142
pub(crate) mod tupleobject;
4243
pub(crate) mod unicodeobject;
4344
pub(crate) mod weakrefobject;
@@ -73,6 +74,7 @@ pub use self::pydebug::*;
7374
pub use self::pyerrors::*;
7475
#[cfg(all(Py_3_11, not(PyPy)))]
7576
pub use self::pyframe::*;
77+
pub use self::pyhash::*;
7678
#[cfg(all(Py_3_8, not(PyPy)))]
7779
pub use self::pylifecycle::*;
7880
pub use self::pymem::*;

pyo3-ffi/src/cpython/pyhash.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#[cfg(Py_3_13)]
2+
use crate::PyObject;
3+
use crate::{Py_hash_t, Py_ssize_t};
4+
use std::os::raw::{c_char, c_int, c_void};
5+
6+
#[repr(C)]
7+
#[derive(Copy, Clone)]
8+
pub struct PyHash_FuncDef {
9+
pub hash: Option<extern "C" fn(arg1: *const c_void, arg2: Py_ssize_t) -> Py_hash_t>,
10+
pub name: *const c_char,
11+
pub hash_bits: c_int,
12+
pub seed_bits: c_int,
13+
}
14+
15+
impl Default for PyHash_FuncDef {
16+
#[inline]
17+
fn default() -> Self {
18+
unsafe { std::mem::zeroed() }
19+
}
20+
}
21+
22+
extern "C" {
23+
pub fn PyHash_GetFuncDef() -> *mut PyHash_FuncDef;
24+
#[cfg(Py_3_13)]
25+
pub fn Py_HashPointer(ptr: *const c_void) -> Py_hash_t;
26+
#[cfg(Py_3_13)]
27+
pub fn PyObject_GenericHash(obj: *mut PyObject) -> Py_hash_t;
28+
#[cfg(Py_3_14)]
29+
pub fn Py_HashBuffer(ptr: *const c_void, len: Py_ssize_t) -> Py_hash_t;
30+
}

pyo3-ffi/src/pyhash.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
22
use crate::pyport::{Py_hash_t, Py_ssize_t};
3-
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
4-
use std::os::raw::c_char;
53
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
64
use std::os::raw::c_void;
75

@@ -22,29 +20,6 @@ pub const _PyHASH_MULTIPLIER: c_ulong = 1000003;
2220

2321
// skipped non-limited _Py_HashSecret_t
2422

25-
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
26-
#[repr(C)]
27-
#[derive(Copy, Clone)]
28-
pub struct PyHash_FuncDef {
29-
pub hash: Option<extern "C" fn(arg1: *const c_void, arg2: Py_ssize_t) -> Py_hash_t>,
30-
pub name: *const c_char,
31-
pub hash_bits: c_int,
32-
pub seed_bits: c_int,
33-
}
34-
35-
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
36-
impl Default for PyHash_FuncDef {
37-
#[inline]
38-
fn default() -> Self {
39-
unsafe { std::mem::zeroed() }
40-
}
41-
}
42-
43-
extern "C" {
44-
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
45-
pub fn PyHash_GetFuncDef() -> *mut PyHash_FuncDef;
46-
}
47-
4823
// skipped Py_HASH_CUTOFF
4924

5025
pub const Py_HASH_EXTERNAL: c_int = 0;

0 commit comments

Comments
 (0)