Skip to content

Commit 87b84a8

Browse files
committed
Fix TextIOWrapper.reconfigure coder
1 parent aa5eba9 commit 87b84a8

File tree

1 file changed

+46
-27
lines changed

1 file changed

+46
-27
lines changed

vm/src/stdlib/io.rs

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,32 +2229,7 @@ mod _io {
22292229
let has_read1 = vm.get_attribute_opt(buffer.clone(), "read1")?.is_some();
22302230
let seekable = vm.call_method(&buffer, "seekable", ())?.try_to_bool(vm)?;
22312231

2232-
let codec = vm.state.codec_registry.lookup(encoding.as_str(), vm)?;
2233-
2234-
let encoder = if vm.call_method(&buffer, "writable", ())?.try_to_bool(vm)? {
2235-
let incremental_encoder =
2236-
codec.get_incremental_encoder(Some(errors.clone()), vm)?;
2237-
let encoding_name = vm.get_attribute_opt(incremental_encoder.clone(), "name")?;
2238-
let encodefunc = encoding_name.and_then(|name| {
2239-
let name = name.payload::<PyStr>()?;
2240-
match name.as_str() {
2241-
"utf-8" => Some(textio_encode_utf8 as EncodeFunc),
2242-
_ => None,
2243-
}
2244-
});
2245-
Some((incremental_encoder, encodefunc))
2246-
} else {
2247-
None
2248-
};
2249-
2250-
let decoder = if vm.call_method(&buffer, "readable", ())?.try_to_bool(vm)? {
2251-
let incremental_decoder =
2252-
codec.get_incremental_decoder(Some(errors.clone()), vm)?;
2253-
// TODO: wrap in IncrementalNewlineDecoder if newlines == Universal | Passthrough
2254-
Some(incremental_decoder)
2255-
} else {
2256-
None
2257-
};
2232+
let (encoder, decoder) = Self::find_coder(&buffer, encoding.as_str(), &errors, vm)?;
22582233

22592234
*data = Some(TextIOData {
22602235
buffer,
@@ -2296,16 +2271,59 @@ mod _io {
22962271
PyThreadMutexGuard::try_map(lock, |x| x.as_mut())
22972272
.map_err(|_| vm.new_value_error("I/O operation on uninitialized object".to_owned()))
22982273
}
2274+
2275+
#[allow(clippy::type_complexity)]
2276+
fn find_coder(
2277+
buffer: &PyObject,
2278+
encoding: &str,
2279+
errors: &Py<PyStr>,
2280+
vm: &VirtualMachine,
2281+
) -> PyResult<(
2282+
Option<(PyObjectRef, Option<EncodeFunc>)>,
2283+
Option<PyObjectRef>,
2284+
)> {
2285+
let codec = vm.state.codec_registry.lookup(encoding, vm)?;
2286+
2287+
let encoder = if vm.call_method(buffer, "writable", ())?.try_to_bool(vm)? {
2288+
let incremental_encoder =
2289+
codec.get_incremental_encoder(Some(errors.to_owned()), vm)?;
2290+
let encoding_name = vm.get_attribute_opt(incremental_encoder.clone(), "name")?;
2291+
let encodefunc = encoding_name.and_then(|name| {
2292+
let name = name.payload::<PyStr>()?;
2293+
match name.as_str() {
2294+
"utf-8" => Some(textio_encode_utf8 as EncodeFunc),
2295+
_ => None,
2296+
}
2297+
});
2298+
Some((incremental_encoder, encodefunc))
2299+
} else {
2300+
None
2301+
};
2302+
2303+
let decoder = if vm.call_method(buffer, "readable", ())?.try_to_bool(vm)? {
2304+
let incremental_decoder =
2305+
codec.get_incremental_decoder(Some(errors.to_owned()), vm)?;
2306+
// TODO: wrap in IncrementalNewlineDecoder if newlines == Universal | Passthrough
2307+
Some(incremental_decoder)
2308+
} else {
2309+
None
2310+
};
2311+
Ok((encoder, decoder))
2312+
}
22992313
}
23002314

23012315
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
23022316
impl TextIOWrapper {
23032317
#[pymethod]
2304-
fn reconfigure(&self, args: TextIOWrapperArgs) {
2318+
fn reconfigure(&self, args: TextIOWrapperArgs, vm: &VirtualMachine) -> PyResult<()> {
23052319
let mut data = self.data.lock().unwrap();
23062320
if let Some(data) = data.as_mut() {
23072321
if let Some(encoding) = args.encoding {
2322+
let (encoder, decoder) =
2323+
Self::find_coder(&data.buffer, encoding.as_str(), &data.errors, vm)?;
23082324
data.encoding = encoding;
2325+
data.encoder = encoder;
2326+
data.decoder = decoder;
23092327
}
23102328
if let Some(errors) = args.errors {
23112329
data.errors = errors;
@@ -2320,6 +2338,7 @@ mod _io {
23202338
data.write_through = write_through;
23212339
}
23222340
}
2341+
Ok(())
23232342
}
23242343
#[pymethod]
23252344
fn seekable(&self, vm: &VirtualMachine) -> PyResult {

0 commit comments

Comments
 (0)