Skip to content

Commit ae4b68f

Browse files
authored
Merge pull request #1438 from lntuition/fix-byte-like-object
Add logic to check array.array byte like object
2 parents 09871c0 + c1d7723 commit ae4b68f

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

tests/snippets/ints.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,20 @@
170170
assert int.from_bytes(bytes=b'\xfc\x00', byteorder='big', signed=True) == -1024
171171
assert int.from_bytes(bytes=b'\xfc\x00', byteorder='big', signed=False) == 64512
172172

173+
assert int.from_bytes([255, 0, 0], 'big') == 16711680
174+
assert int.from_bytes([255, 0, 0], 'little') == 255
175+
assert int.from_bytes([255, 0, 0], 'big', signed=False) == 16711680
176+
assert int.from_bytes([255, 0, 0], 'big', signed=True) == -65536
177+
173178
with assert_raises(ValueError):
174179
int.from_bytes(b'\x00\x10', 'something')
175180

181+
with assert_raises(ValueError):
182+
int.from_bytes([256, 0, 0], 'big')
183+
184+
with assert_raises(TypeError):
185+
int.from_bytes(['something', 0, 0], 'big')
186+
176187
assert (1024).to_bytes(4, 'big') == b'\x00\x00\x04\x00'
177188
assert (1024).to_bytes(2, 'little') == b'\x00\x04'
178189
assert (1024).to_bytes(4, byteorder='big') == b'\x00\x00\x04\x00'

vm/src/obj/objbyteinner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use num_traits::ToPrimitive;
2626

2727
use super::objbytearray::PyByteArray;
2828
use super::objbytes::PyBytes;
29+
use super::objlist::PyList;
2930
use super::objmemory::PyMemoryView;
3031

3132
use super::objsequence;
@@ -47,6 +48,7 @@ impl TryFromObject for PyByteInner {
4748
k @ PyMemoryView => Ok(PyByteInner {
4849
elements: k.get_obj_value().unwrap()
4950
}),
51+
l @ PyList => l.get_byte_inner(vm),
5052
obj => Err(vm.new_type_error(format!(
5153
"a bytes-like object is required, not {}",
5254
obj.class()

vm/src/obj/objlist.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use num_traits::{One, Signed, ToPrimitive, Zero};
99
use crate::function::OptionalArg;
1010
use crate::pyobject::{
1111
IdProtocol, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
12-
TryFromObject,
12+
TryFromObject, TypeProtocol,
1313
};
1414
use crate::vm::{ReprGuard, VirtualMachine};
1515

1616
use super::objbool;
17-
//use super::objint;
17+
use super::objbyteinner;
18+
use super::objint::PyIntRef;
1819
use super::objiter;
1920
use super::objsequence::{
2021
get_elements_list, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, SequenceIndex,
@@ -96,6 +97,29 @@ impl PyList {
9697

9798
start..stop
9899
}
100+
101+
pub fn get_byte_inner(&self, vm: &VirtualMachine) -> PyResult<objbyteinner::PyByteInner> {
102+
let mut elements = Vec::<u8>::with_capacity(self.get_len());
103+
for elem in self.elements.borrow().iter() {
104+
match PyIntRef::try_from_object(vm, elem.clone()) {
105+
Ok(result) => match result.as_bigint().to_u8() {
106+
Some(result) => elements.push(result),
107+
None => {
108+
return Err(
109+
vm.new_value_error("bytes must be in range (0, 256)".to_string())
110+
)
111+
}
112+
},
113+
_ => {
114+
return Err(vm.new_type_error(format!(
115+
"'{}' object cannot be interpreted as an integer",
116+
elem.class().name
117+
)))
118+
}
119+
}
120+
}
121+
Ok(objbyteinner::PyByteInner { elements })
122+
}
99123
}
100124

101125
#[derive(FromArgs)]

0 commit comments

Comments
 (0)