forked from Rust-related/RustPython
Merge pull request #1424 from dralley/fix-float
Allow float() to be called without an argument
This commit is contained in:
@@ -86,6 +86,8 @@ assert math.isinf(float('Inf'))
|
||||
assert math.isinf(float('+Inf'))
|
||||
assert math.isinf(float('-Inf'))
|
||||
|
||||
assert float() == 0
|
||||
|
||||
assert float('+Inf') > 0
|
||||
assert float('-Inf') < 0
|
||||
|
||||
|
||||
@@ -157,6 +157,19 @@ fn inner_gt_int(value: f64, other_int: &BigInt) -> bool {
|
||||
#[pyimpl]
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
impl PyFloat {
|
||||
#[pymethod(name = "__new__")]
|
||||
fn float_new(
|
||||
cls: PyClassRef,
|
||||
arg: OptionalArg<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyFloatRef> {
|
||||
let float_val = match arg {
|
||||
OptionalArg::Present(val) => to_float(vm, &val),
|
||||
OptionalArg::Missing => Ok(0f64),
|
||||
};
|
||||
PyFloat::from(float_val?).into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__eq__")]
|
||||
fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let value = self.value;
|
||||
@@ -316,40 +329,6 @@ impl PyFloat {
|
||||
)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__new__")]
|
||||
fn float_new(cls: PyClassRef, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyFloatRef> {
|
||||
let value = if objtype::isinstance(&arg, &vm.ctx.float_type()) {
|
||||
get_value(&arg)
|
||||
} else if objtype::isinstance(&arg, &vm.ctx.int_type()) {
|
||||
objint::get_float_value(&arg, vm)?
|
||||
} else if objtype::isinstance(&arg, &vm.ctx.str_type()) {
|
||||
match lexical::try_parse(objstr::get_value(&arg).trim()) {
|
||||
Ok(f) => f,
|
||||
Err(_) => {
|
||||
let arg_repr = vm.to_pystr(&arg)?;
|
||||
return Err(vm.new_value_error(format!(
|
||||
"could not convert string to float: '{}'",
|
||||
arg_repr
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else if objtype::isinstance(&arg, &vm.ctx.bytes_type()) {
|
||||
match lexical::try_parse(objbytes::get_value(&arg).as_slice()) {
|
||||
Ok(f) => f,
|
||||
Err(_) => {
|
||||
let arg_repr = vm.to_pystr(&arg)?;
|
||||
return Err(vm.new_value_error(format!(
|
||||
"could not convert string to float: '{}'",
|
||||
arg_repr
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!("can't convert {} to float", arg.class().name)));
|
||||
};
|
||||
PyFloat { value }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__mod__")]
|
||||
fn mod_(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
try_float(&other, vm)?.map_or_else(
|
||||
@@ -574,6 +553,39 @@ impl PyFloat {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_float(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<f64> {
|
||||
let value = if objtype::isinstance(&obj, &vm.ctx.float_type()) {
|
||||
get_value(&obj)
|
||||
} else if objtype::isinstance(&obj, &vm.ctx.int_type()) {
|
||||
objint::get_float_value(&obj, vm)?
|
||||
} else if objtype::isinstance(&obj, &vm.ctx.str_type()) {
|
||||
match lexical::try_parse(objstr::get_value(&obj).trim()) {
|
||||
Ok(f) => f,
|
||||
Err(_) => {
|
||||
let arg_repr = vm.to_pystr(obj)?;
|
||||
return Err(vm.new_value_error(format!(
|
||||
"could not convert string to float: '{}'",
|
||||
arg_repr
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else if objtype::isinstance(&obj, &vm.ctx.bytes_type()) {
|
||||
match lexical::try_parse(objbytes::get_value(&obj).as_slice()) {
|
||||
Ok(f) => f,
|
||||
Err(_) => {
|
||||
let arg_repr = vm.to_pystr(obj)?;
|
||||
return Err(vm.new_value_error(format!(
|
||||
"could not convert string to float: '{}'",
|
||||
arg_repr
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!("can't convert {} to float", obj.class().name)));
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn to_hex(value: f64) -> String {
|
||||
let (mantissa, exponent, sign) = value.integer_decode();
|
||||
let sign_fmt = if sign < 0 { "-" } else { "" };
|
||||
|
||||
Reference in New Issue
Block a user