Skip to content

Commit a350311

Browse files
committed
Release float parsing guards before error callbacks
Retain generic buffer exports through representation while allowing callback mutation after native parsing finishes. Assisted-by: OpenAI Codex:model version not exposed
1 parent a97dc96 commit a350311

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

‎crates/vm/src/builtins/float.rs‎

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -290,26 +290,32 @@ impl Constructor for PyFloat {
290290
}
291291

292292
pub fn float_from_string(val: &PyObject, vm: &VirtualMachine) -> PyResult<f64> {
293-
let (bytearray, buffer, buffer_lock, mapped_string);
294-
let b = if let Some(s) = val.downcast_ref::<PyStr>() {
295-
mapped_string = crate::protocol::numeric_literal_from_str(s);
296-
mapped_string.as_bytes()
297-
} else if let Some(bytes) = val.downcast_ref::<PyBytes>() {
298-
bytes.as_bytes()
299-
} else if let Some(buf) = val.downcast_ref::<PyByteArray>() {
300-
bytearray = buf.borrow_buf();
301-
&*bytearray
302-
} else if let Ok(b) = ArgBytesLike::try_from_borrowed_object(vm, val) {
303-
buffer = b;
304-
buffer_lock = buffer.borrow_buf();
305-
&*buffer_lock
306-
} else {
307-
return Err(vm.new_type_error(format!(
308-
"float() argument must be a string or a real number, not '{}'",
309-
val.class().slot_name()
310-
)));
293+
// Keep the buffer export alive through repr, but release data guards first
294+
// so repr can mutate the original object.
295+
let buffer;
296+
let parsed = {
297+
let (bytearray, buffer_lock, mapped_string);
298+
let b = if let Some(s) = val.downcast_ref::<PyStr>() {
299+
mapped_string = crate::protocol::numeric_literal_from_str(s);
300+
mapped_string.as_bytes()
301+
} else if let Some(bytes) = val.downcast_ref::<PyBytes>() {
302+
bytes.as_bytes()
303+
} else if let Some(buf) = val.downcast_ref::<PyByteArray>() {
304+
bytearray = buf.borrow_buf();
305+
&*bytearray
306+
} else if let Ok(b) = ArgBytesLike::try_from_borrowed_object(vm, val) {
307+
buffer = b;
308+
buffer_lock = buffer.borrow_buf();
309+
&*buffer_lock
310+
} else {
311+
return Err(vm.new_type_error(format!(
312+
"float() argument must be a string or a real number, not '{}'",
313+
val.class().slot_name()
314+
)));
315+
};
316+
crate::literal::float::parse_bytes(b)
311317
};
312-
crate::literal::float::parse_bytes(b).ok_or_else(|| invalid_float_literal_error(val, vm))
318+
parsed.ok_or_else(|| invalid_float_literal_error(val, vm))
313319
}
314320

315321
/// Build the existing float-conversion error after native parsing has failed.

0 commit comments

Comments
 (0)