Skip to content

Commit d345c31

Browse files
committed
PyObject::try_float
1 parent d5c48c2 commit d345c31

File tree

5 files changed

+37
-26
lines changed

5 files changed

+37
-26
lines changed

stdlib/src/math.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ mod math {
454454
fn ceil(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
455455
let result_or_err = try_magic_method(identifier!(vm, __ceil__), vm, &x);
456456
if result_or_err.is_err() {
457-
if let Ok(Some(v)) = x.to_number().float_opt(vm) {
457+
if let Ok(Some(v)) = x.try_float_opt(vm) {
458458
let v = try_f64_to_bigint(v.to_f64().ceil(), vm)?;
459459
return Ok(vm.ctx.new_int(v).into());
460460
}
@@ -466,7 +466,7 @@ mod math {
466466
fn floor(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
467467
let result_or_err = try_magic_method(identifier!(vm, __floor__), vm, &x);
468468
if result_or_err.is_err() {
469-
if let Ok(Some(v)) = x.to_number().float_opt(vm) {
469+
if let Ok(Some(v)) = x.try_float_opt(vm) {
470470
let v = try_f64_to_bigint(v.to_f64().floor(), vm)?;
471471
return Ok(vm.ctx.new_int(v).into());
472472
}

vm/src/builtins/complex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl PyObjectRef {
6767
if let Some(complex) = self.payload_if_subclass::<PyComplex>(vm) {
6868
return Ok(Some((complex.value, true)));
6969
}
70-
if let Some(float) = self.to_number().float_opt(vm)? {
70+
if let Some(float) = self.try_float_opt(vm)? {
7171
return Ok(Some((Complex64::new(float.to_f64(), 0.0), false)));
7272
}
7373
Ok(None)

vm/src/builtins/float.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl Constructor for PyFloat {
142142
let float_val = match arg {
143143
OptionalArg::Missing => 0.0,
144144
OptionalArg::Present(val) => {
145-
if let Some(f) = val.to_number().float_opt(vm)? {
145+
if let Some(f) = val.try_float_opt(vm)? {
146146
f.value
147147
} else {
148148
float_from_string(val, vm)?

vm/src/function/number.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Deref for ArgIntoFloat {
8282
impl TryFromObject for ArgIntoFloat {
8383
// Equivalent to PyFloat_AsDouble.
8484
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
85-
let value = obj.to_number().float(vm)?.to_f64();
85+
let value = obj.try_float(vm)?.to_f64();
8686
Ok(ArgIntoFloat { value })
8787
}
8888
}

vm/src/protocol/number.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,31 @@ impl PyObject {
9494
}
9595
}
9696
}
97+
98+
pub fn try_float_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
99+
Ok(
100+
if let Some(float) = self.downcast_ref_if_exact::<PyFloat>(vm) {
101+
Some(float.to_owned())
102+
} else {
103+
let number = self.to_number();
104+
if let Some(f) = number.float(vm)? {
105+
Some(f)
106+
} else if let Some(i) = self.try_index_opt(vm) {
107+
let value = int::try_to_float(i?.as_bigint(), vm)?;
108+
Some(vm.ctx.new_float(value))
109+
} else if let Some(value) = self.downcast_ref::<PyFloat>() {
110+
Some(vm.ctx.new_float(value.to_f64()))
111+
} else {
112+
None
113+
}
114+
},
115+
)
116+
}
117+
118+
pub fn try_float(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>> {
119+
self.try_float_opt(vm)?
120+
.ok_or_else(|| vm.new_type_error(format!("must be real number, not {}", self.class())))
121+
}
97122
}
98123

99124
#[derive(Default)]
@@ -280,12 +305,10 @@ impl PyNumber<'_> {
280305
}
281306
}
282307

283-
pub fn float_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
284-
if let Some(float) = self.obj.downcast_ref_if_exact::<PyFloat>(vm) {
285-
Ok(Some(float.to_owned()))
286-
} else if let Some(f) = self.methods().float.load() {
308+
pub fn float(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
309+
Ok(if let Some(f) = self.methods().float.load() {
287310
let ret = f(self, vm)?;
288-
if !ret.class().is(PyFloat::class(vm)) {
311+
Some(if !ret.class().is(PyFloat::class(vm)) {
289312
warnings::warn(
290313
vm.ctx.exceptions.deprecation_warning,
291314
format!(
@@ -297,24 +320,12 @@ impl PyNumber<'_> {
297320
1,
298321
vm,
299322
)?;
300-
Ok(Some(vm.ctx.new_float(ret.to_f64())))
323+
vm.ctx.new_float(ret.to_f64())
301324
} else {
302-
Ok(Some(ret))
303-
}
304-
} else if self.methods().index.load().is_some() {
305-
let i = self.obj.try_index(vm)?;
306-
let value = int::try_to_float(i.as_bigint(), vm)?;
307-
Ok(Some(vm.ctx.new_float(value)))
308-
} else if let Some(value) = self.obj.downcast_ref::<PyFloat>() {
309-
Ok(Some(vm.ctx.new_float(value.to_f64())))
325+
ret
326+
})
310327
} else {
311-
Ok(None)
312-
}
313-
}
314-
315-
pub fn float(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>> {
316-
self.float_opt(vm)?.ok_or_else(|| {
317-
vm.new_type_error(format!("must be real number, not {}", self.obj.class()))
328+
None
318329
})
319330
}
320331
}

0 commit comments

Comments
 (0)