Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions crates/vm/src/stdlib/_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3206,19 +3206,27 @@ mod _io {
}

#[pygetset(setter, name = "_CHUNK_SIZE")]
fn set_chunksize(
&self,
chunk_size: PySetterValue<usize>,
vm: &VirtualMachine,
) -> PyResult<()> {
let mut textio = self.lock(vm)?;
match chunk_size {
PySetterValue::Assign(chunk_size) => textio.chunk_size = chunk_size,
fn set_chunksize(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let chunk_size: isize = match value {
PySetterValue::Assign(object_value) => {
let integer = object_value.try_index(vm)?;

integer.try_to_primitive::<isize>(vm).map_err(|_| {
vm.new_value_error("cannot fit 'int' into an index-sized integer")
})?
}
PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute"))?,
};
// TODO: RUSTPYTHON
// Change chunk_size type, validate it manually and throws ValueError if invalid.
// https://github.com/python/cpython/blob/2e9da8e3522764d09f1d6054a2be567e91a30812/Modules/_io/textio.c#L3124-L3143

if chunk_size <= 0 {
return Err(vm.new_value_error("a strictly positive integer is required"));
}

let chunk_size = usize::try_from(chunk_size)
.map_err(|_| vm.new_value_error("a strictly positive integer is required"))?;

let mut textio = self.lock(vm)?;
textio.chunk_size = chunk_size;
Ok(())
}

Expand Down
27 changes: 27 additions & 0 deletions extra_tests/snippets/stdlib_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,30 @@ def write(self, data):
raw.textio = textio
with assert_raises(AttributeError):
textio.writelines(["x"])

textio = TextIOWrapper(BytesIO())

for invalid_chunk_size in (0, -1, 2**100):
try:
textio._CHUNK_SIZE = invalid_chunk_size
except ValueError:
pass
else:
assert False, f"expected ValueError for {invalid_chunk_size!r}"

for invalid_chunk_size in (1.5, "4"):
try:
textio._CHUNK_SIZE = invalid_chunk_size
except TypeError:
pass
else:
assert False, f"expected TypeError for {invalid_chunk_size!r}"
Comment thread
shAn-kor marked this conversation as resolved.


class ChunkSize:
def __index__(self):
return 16


textio._CHUNK_SIZE = ChunkSize()
assert textio._CHUNK_SIZE == 16
Loading