-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
bytes should translate to &[u8] #373
Comments
I think the second example was meant to contain a different snippet |
@konstin Oops, sorry about that, fixed. |
Would be a nice feature :-). Right now, the workaround I've is the following: pub fn foo(bytes: &PyAny) -> PyResult<bool> {
match <PyBytes as PyTryFrom>::try_from(bytes) {
Ok(bytes) => /* do something */,
_ => Ok(false)
}
} |
If someone wants to implement this, Lines 50 to 61 in fdeef7d
|
You can use a |
Indeed, only |
@konstin @ExpHP I am not sure I agree with this, can you clarify exactly what the objection is? In both cases you get an immutable view into a memory array, so it's the difference between fn some_func(y: &[u8]) {
println!("{:?}", y);
}
fn main() {
let mut x : [u8; 4] = [0, 0x55, 0x10, 0xff];
some_func(&mut x);
} So it makes sense to allow conversion from |
@pganssle Rust can and will assume that memory referenced by
is now problematic, for example because the compiler might decide to do the read from |
@birkenfeld I suppose it's a fair point, though it depends heavily on how the implementation works. If it's indeed just passing a reference to some memory that Python can modify while Rust holds a reference to it, then it's a soundness problem. If it's copying the memory into some intermediate representation managed by Rust, it's not a problem. I haven't looked enough into the implementation of |
Here is proof that even the existing extern crate pyo3;
use pyo3::prelude::{PyResult, Python};
use pyo3::types::{PyDict, PyByteArray};
fn main() -> Result<(), ()> {
let gil = Python::acquire_gil();
show_ub(gil.python()).map_err(|e| {
eprintln!("error! :{:?}", e);
e.print_and_set_sys_last_vars(gil.python());
})
}
// a function that behaves differently in dev and release builds
fn show_ub(py: Python<'_>) -> PyResult<()> {
let dict = PyDict::new(py);
let array = PyByteArray::new(py, &[2]);
dict.set_item("b", array)?;
let bytes: &[u8] = array.data();
lol(&bytes[0], &|| py.run("b[0] = 3", None, Some(&dict)).unwrap());
// we should never make it here, because 2 != 3
unreachable!("uh oh, how did we get here!?");
}
#[inline(never)]
fn lol(x: &u8, func: &dyn Fn()) {
let old = *x;
func();
let new = *x;
assert_eq!(old, new);
} Results on debug:
Results on release: The
|
Yep, #342 should fix that. On looking at #342 again I've realized that @athre0z had already pointed that out over there. I'm sorry for missing that, I initially ignored the comments because I thought they were only more evidence for the |
Per a discussion in the gitter chat, it seems that currently the proper traits are not implemented to allow for Python's
bytes
objects to be automatically translated into&[u8]
parameters. Right now, in order to write a function that takesbytes
, you need to use&PyBytes
:If you instead use
&[u8]
directly, there's an error at compile time because thepyo3::PyTypeInfo
trait is not implemented for[u8]
. I think it should be possible to pass both abytes
andbytearray
object into a Rust function that takes&[u8]
.I am using version 0.6.0-alpha.4, and with this code:
I get this error message:
CC @thedrow
The text was updated successfully, but these errors were encountered: