Mercurial > public > mercurial-scm > hg
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 |