Skip to content

Commit 99beb1a

Browse files
committed
fix: use PyBytes to reference bytes in future_into_py
- credits to kevin reid
1 parent bb08d0e commit 99beb1a

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

py-gxhash/src/lib.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
use pyo3::prelude::*;
1+
use pyo3::prelude::pyclass;
2+
use pyo3::prelude::pymethods;
3+
use pyo3::prelude::Bound;
4+
use pyo3::prelude::Py;
5+
use pyo3::prelude::PyAny;
6+
use pyo3::prelude::PyErr;
7+
use pyo3::prelude::PyObject;
8+
use pyo3::prelude::PyResult;
9+
use pyo3::prelude::Python;
10+
use pyo3::types::PyBytes;
11+
use pyo3::types::PyModuleMethods;
212
use pyo3_async_runtimes::tokio::future_into_py;
313
use std::os::fd::FromRawFd;
414

@@ -11,7 +21,13 @@ fn gxhash<T>(hasher: fn(&[u8], i64) -> T, bytes: &[u8], seed: i64) -> PyResult<T
1121
}
1222

1323
fn gxhash_file<T>(hasher: fn(&[u8], i64) -> T, file_descriptor: i32, seed: i64) -> PyResult<T> {
14-
let mmap = unsafe { memmap2::Mmap::map(&std::fs::File::from_raw_fd(libc::dup(file_descriptor)))? };
24+
let duplicated_file_descriptor = unsafe { libc::dup(file_descriptor) };
25+
26+
if duplicated_file_descriptor == -1 {
27+
return Err(PyErr::new::<pyo3::exceptions::PyOSError, _>("Failed to duplicate file descriptor"));
28+
}
29+
30+
let mmap = unsafe { memmap2::Mmap::map(&std::fs::File::from_raw_fd(duplicated_file_descriptor))? };
1531
Ok(hasher(&mmap, seed))
1632
}
1733

@@ -47,12 +63,11 @@ impl GxHash32 {
4763
gxhash(self.hasher, bytes, self.seed)
4864
}
4965

50-
fn hash_async<'a>(&self, py: Python<'a>, bytes: &'a [u8]) -> PyResult<Bound<'a, PyAny>> {
66+
fn hash_async<'a>(&self, py: Python<'a>, bytes: Py<PyBytes>) -> PyResult<Bound<'a, PyAny>> {
5167
let seed = self.seed;
5268
let hasher = self.hasher;
53-
let bytes_static = unsafe { std::mem::transmute::<&'a [u8], &'static [u8]>(bytes) };
5469

55-
future_into_py(py, async move { gxhash(hasher, bytes_static, seed) })
70+
future_into_py(py, async move { gxhash(hasher, Python::with_gil(|py| bytes.as_bytes(py)), seed) })
5671
}
5772

5873
fn hash_file(&self, py: Python, file: PyObject) -> PyResult<u32> {
@@ -82,12 +97,11 @@ impl GxHash64 {
8297
gxhash(self.hasher, bytes, self.seed)
8398
}
8499

85-
fn hash_async<'a>(&self, py: Python<'a>, bytes: &'a [u8]) -> PyResult<Bound<'a, PyAny>> {
100+
fn hash_async<'a>(&self, py: Python<'a>, bytes: Py<PyBytes>) -> PyResult<Bound<'a, PyAny>> {
86101
let seed = self.seed;
87102
let hasher = self.hasher;
88-
let bytes_static = unsafe { std::mem::transmute::<&'a [u8], &'static [u8]>(bytes) };
89103

90-
future_into_py(py, async move { gxhash(hasher, bytes_static, seed) })
104+
future_into_py(py, async move { gxhash(hasher, Python::with_gil(|py| bytes.as_bytes(py)), seed) })
91105
}
92106

93107
fn hash_file(&self, py: Python, file: PyObject) -> PyResult<u64> {
@@ -117,12 +131,11 @@ impl GxHash128 {
117131
gxhash(self.hasher, bytes, self.seed)
118132
}
119133

120-
fn hash_async<'a>(&self, py: Python<'a>, bytes: &'a [u8]) -> PyResult<Bound<'a, PyAny>> {
134+
fn hash_async<'a>(&self, py: Python<'a>, bytes: Py<PyBytes>) -> PyResult<Bound<'a, PyAny>> {
121135
let seed = self.seed;
122136
let hasher = self.hasher;
123-
let bytes_static = unsafe { std::mem::transmute::<&'a [u8], &'static [u8]>(bytes) };
124137

125-
future_into_py(py, async move { gxhash(hasher, bytes_static, seed) })
138+
future_into_py(py, async move { gxhash(hasher, Python::with_gil(|py| bytes.as_bytes(py)), seed) })
126139
}
127140

128141
fn hash_file(&self, py: Python, file: PyObject) -> PyResult<u128> {
@@ -138,8 +151,8 @@ impl GxHash128 {
138151
}
139152
}
140153

141-
#[pymodule(name = "gxhash")]
142-
fn pygxhash(m: &Bound<'_, PyModule>) -> PyResult<()> {
154+
#[pyo3::prelude::pymodule(name = "gxhash")]
155+
fn pygxhash(m: &Bound<'_, pyo3::prelude::PyModule>) -> PyResult<()> {
143156
m.add_class::<GxHash32>()?;
144157
m.add_class::<GxHash64>()?;
145158
m.add_class::<GxHash128>()?;

0 commit comments

Comments
 (0)