Skip to content

Commit c064118

Browse files
authored
Impl array.fromfile (RustPython#3065)
1 parent b723bbf commit c064118

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

Lib/test/test_array.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,6 @@ def test_tofromfile(self):
398398
f.close()
399399
support.unlink(support.TESTFN)
400400

401-
# TODO: RUSTPYTHON
402-
@unittest.expectedFailure
403401
def test_fromfile_ioerror(self):
404402
# Issue #5395: Check if fromfile raises a proper OSError
405403
# instead of EOFError.
@@ -411,8 +409,6 @@ def test_fromfile_ioerror(self):
411409
f.close()
412410
support.unlink(support.TESTFN)
413411

414-
# TODO: RUSTPYTHON
415-
@unittest.expectedFailure
416412
def test_filewrite(self):
417413
a = array.array(self.typecode, 2*self.example)
418414
f = open(support.TESTFN, 'wb')

vm/src/stdlib/array.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -804,21 +804,53 @@ mod array {
804804
}
805805
}
806806

807-
#[pymethod]
808-
fn frombytes(zelf: PyRef<Self>, b: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
809-
let b = b.borrow_buf();
810-
let itemsize = zelf.read().itemsize();
807+
fn _from_bytes(&self, b: &[u8], itemsize: usize, vm: &VirtualMachine) -> PyResult<()> {
811808
if b.len() % itemsize != 0 {
812809
return Err(
813810
vm.new_value_error("bytes length not a multiple of item size".to_owned())
814811
);
815812
}
816813
if b.len() / itemsize > 0 {
817-
zelf.try_resizable(vm)?.frombytes(&b);
814+
self.try_resizable(vm)?.frombytes(b);
818815
}
819816
Ok(())
820817
}
821818

819+
#[pymethod]
820+
fn frombytes(&self, b: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
821+
let b = b.borrow_buf();
822+
let itemsize = self.read().itemsize();
823+
self._from_bytes(&b, itemsize, vm)
824+
}
825+
826+
#[pymethod]
827+
fn fromfile(&self, f: PyObjectRef, n: isize, vm: &VirtualMachine) -> PyResult<()> {
828+
let itemsize = self.itemsize();
829+
if n < 0 {
830+
return Err(vm.new_value_error("negative count".to_owned()));
831+
}
832+
let n = vm.check_repeat_or_memory_error(itemsize, n)?;
833+
let nbytes = n * itemsize;
834+
835+
let b = vm.call_method(&f, "read", (nbytes,))?;
836+
let b = b
837+
.downcast::<PyBytes>()
838+
.map_err(|_| vm.new_type_error("read() didn't return bytes".to_owned()))?;
839+
840+
let not_enough_bytes = b.len() != nbytes;
841+
842+
self._from_bytes(b.as_bytes(), itemsize, vm)?;
843+
844+
if not_enough_bytes {
845+
Err(vm.new_exception_msg(
846+
vm.ctx.exceptions.eof_error.clone(),
847+
"read() didn't return enough bytes".to_owned(),
848+
))
849+
} else {
850+
Ok(())
851+
}
852+
}
853+
822854
#[pymethod]
823855
fn byteswap(&self) {
824856
self.write().byteswap();

0 commit comments

Comments
 (0)