Skip to content

Commit f588f58

Browse files
Merge pull request RustPython#503 from janczer/add_pop_bytearray
Add pop to bytearray
2 parents 3bb00fa + 24176f7 commit f588f58

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

tests/snippets/bytearray.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,22 @@
3333
a = bytearray(b'abcd')
3434
a.clear()
3535
assert len(a) == 0
36+
37+
b = bytearray(b'test')
38+
assert len(b) == 4
39+
b.pop()
40+
assert len(b) == 3
41+
42+
c = bytearray([123, 255, 111])
43+
assert len(c) == 3
44+
c.pop()
45+
assert len(c) == 2
46+
c.pop()
47+
c.pop()
48+
49+
try:
50+
c.pop()
51+
except IndexError:
52+
pass
53+
else:
54+
assert False

vm/src/obj/objbytearray.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::super::pyobject::{
77
use super::objint;
88

99
use super::super::vm::VirtualMachine;
10+
use super::objbytes::get_mut_value;
1011
use super::objbytes::get_value;
1112
use super::objtype;
1213
use num_traits::ToPrimitive;
@@ -100,6 +101,7 @@ pub fn init(context: &PyContext) {
100101
"clear",
101102
context.new_rustfunc(bytearray_clear),
102103
);
104+
context.set_attr(&bytearray_type, "pop", context.new_rustfunc(bytearray_pop));
103105
}
104106

105107
fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -278,3 +280,14 @@ fn bytearray_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
278280
_ => panic!("Bytearray has incorrect payload."),
279281
}
280282
}
283+
284+
fn bytearray_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
285+
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytearray_type()))]);
286+
let mut value = get_mut_value(obj);
287+
288+
if let Some(i) = value.pop() {
289+
Ok(vm.ctx.new_int(i))
290+
} else {
291+
Err(vm.new_index_error("pop from empty bytearray".to_string()))
292+
}
293+
}

vm/src/obj/objbytes.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use super::objint;
66
use super::objtype;
77
use num_traits::ToPrimitive;
88
use std::cell::Ref;
9+
use std::cell::RefMut;
910
use std::hash::{Hash, Hasher};
1011
use std::ops::Deref;
12+
use std::ops::DerefMut;
1113

1214
// Binary data support
1315

@@ -183,7 +185,17 @@ pub fn get_value<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<u8>> + 'a
183185
if let PyObjectPayload::Bytes { ref value } = py_obj.payload {
184186
value
185187
} else {
186-
panic!("Inner error getting int {:?}", obj);
188+
panic!("Inner error getting bytearray {:?}", obj);
189+
}
190+
})
191+
}
192+
193+
pub fn get_mut_value<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<u8>> + 'a {
194+
RefMut::map(obj.borrow_mut(), |py_obj| {
195+
if let PyObjectPayload::Bytes { ref mut value } = py_obj.payload {
196+
value
197+
} else {
198+
panic!("Inner error getting bytearray {:?}", obj);
187199
}
188200
})
189201
}

0 commit comments

Comments
 (0)