-
Notifications
You must be signed in to change notification settings - Fork 784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: