comparison rust/hg-cpython/src/pybytes_deref.rs @ 52851:d9d6ae9b9722

rust-pyo3-dirstate: making bytes slices in core Sync For the purposes of providing PyO3 bindings, the data fields that will be exposed to Python have to be `Sync`, hence that is the case of `OwningDirstateMap` and its `owner` field. We had to do something similar for the PyO3 bindings of `revlog`. In this case, it forces us to adapt the `Deref` wrapper of `PyBytes` used in `hg-cpython`, because it must itself now be `Sync` and raw pointers are not. This looks even uglier than it used to, but it does not matter much, because our ultimate goal is to remove the rust-cpython bindings altogether.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 29 Jan 2025 12:37:06 +0100
parents 7346f93be7a4
children
comparison
equal deleted inserted replaced
52850:ffda57aa98fa 52851:d9d6ae9b9722
16 #[allow(unused)] 16 #[allow(unused)]
17 keep_alive: PyBytes, 17 keep_alive: PyBytes,
18 18
19 /// Borrows the buffer inside `self.keep_alive`, 19 /// Borrows the buffer inside `self.keep_alive`,
20 /// but the borrow-checker cannot express self-referential structs. 20 /// but the borrow-checker cannot express self-referential structs.
21 data: *const [u8], 21 data: &'static [u8],
22 } 22 }
23 23
24 impl PyBytesDeref { 24 impl PyBytesDeref {
25 pub fn new(py: Python, bytes: PyBytes) -> Self { 25 pub fn new(py: Python, bytes: PyBytes) -> Self {
26 let as_raw: *const [u8] = bytes.data(py);
26 Self { 27 Self {
27 data: bytes.data(py), 28 // Safety: the raw pointer is valid as long as the PyBytes is still
29 // alive, and the objecs owns it.
30 data: unsafe { &*as_raw },
28 keep_alive: bytes, 31 keep_alive: bytes,
29 } 32 }
30 } 33 }
31 34
32 pub fn unwrap(self) -> PyBytes { 35 pub fn unwrap(self) -> PyBytes {
36 39
37 impl std::ops::Deref for PyBytesDeref { 40 impl std::ops::Deref for PyBytesDeref {
38 type Target = [u8]; 41 type Target = [u8];
39 42
40 fn deref(&self) -> &[u8] { 43 fn deref(&self) -> &[u8] {
41 // Safety: the raw pointer is valid as long as the PyBytes is still 44 self.data
42 // alive, and the returned slice borrows `self`.
43 unsafe { &*self.data }
44 } 45 }
45 } 46 }
46 47
47 unsafe impl StableDeref for PyBytesDeref {} 48 unsafe impl StableDeref for PyBytesDeref {}
48 49