diff --git a/tests/snippets/ints.py b/tests/snippets/ints.py index baa145bff..1bbecc3a7 100644 --- a/tests/snippets/ints.py +++ b/tests/snippets/ints.py @@ -170,9 +170,20 @@ assert int.from_bytes(b'\xfc\x00', byteorder='big', signed=False) == 64512 assert int.from_bytes(bytes=b'\xfc\x00', byteorder='big', signed=True) == -1024 assert int.from_bytes(bytes=b'\xfc\x00', byteorder='big', signed=False) == 64512 +assert int.from_bytes([255, 0, 0], 'big') == 16711680 +assert int.from_bytes([255, 0, 0], 'little') == 255 +assert int.from_bytes([255, 0, 0], 'big', signed=False) == 16711680 +assert int.from_bytes([255, 0, 0], 'big', signed=True) == -65536 + with assert_raises(ValueError): int.from_bytes(b'\x00\x10', 'something') +with assert_raises(ValueError): + int.from_bytes([256, 0, 0], 'big') + +with assert_raises(TypeError): + int.from_bytes(['something', 0, 0], 'big') + assert (1024).to_bytes(4, 'big') == b'\x00\x00\x04\x00' assert (1024).to_bytes(2, 'little') == b'\x00\x04' assert (1024).to_bytes(4, byteorder='big') == b'\x00\x00\x04\x00' diff --git a/vm/src/obj/objbyteinner.rs b/vm/src/obj/objbyteinner.rs index fe69b4420..e402bed31 100644 --- a/vm/src/obj/objbyteinner.rs +++ b/vm/src/obj/objbyteinner.rs @@ -26,6 +26,7 @@ use num_traits::ToPrimitive; use super::objbytearray::PyByteArray; use super::objbytes::PyBytes; +use super::objlist::PyList; use super::objmemory::PyMemoryView; use super::objsequence; @@ -47,6 +48,7 @@ impl TryFromObject for PyByteInner { k @ PyMemoryView => Ok(PyByteInner { elements: k.get_obj_value().unwrap() }), + l @ PyList => l.get_byte_inner(vm), obj => Err(vm.new_type_error(format!( "a bytes-like object is required, not {}", obj.class() diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index 62c33366a..612d5254a 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -9,12 +9,13 @@ use num_traits::{One, Signed, ToPrimitive, Zero}; use crate::function::OptionalArg; use crate::pyobject::{ IdProtocol, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, - TryFromObject, + TryFromObject, TypeProtocol, }; use crate::vm::{ReprGuard, VirtualMachine}; use super::objbool; -//use super::objint; +use super::objbyteinner; +use super::objint::PyIntRef; use super::objiter; use super::objsequence::{ get_elements_list, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, SequenceIndex, @@ -96,6 +97,29 @@ impl PyList { start..stop } + + pub fn get_byte_inner(&self, vm: &VirtualMachine) -> PyResult { + let mut elements = Vec::::with_capacity(self.get_len()); + for elem in self.elements.borrow().iter() { + match PyIntRef::try_from_object(vm, elem.clone()) { + Ok(result) => match result.as_bigint().to_u8() { + Some(result) => elements.push(result), + None => { + return Err( + vm.new_value_error("bytes must be in range (0, 256)".to_string()) + ) + } + }, + _ => { + return Err(vm.new_type_error(format!( + "'{}' object cannot be interpreted as an integer", + elem.class().name + ))) + } + } + } + Ok(objbyteinner::PyByteInner { elements }) + } } #[derive(FromArgs)]