diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 09bc50e17..53f454d18 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -287,7 +287,6 @@ class GeneralFloatCases(unittest.TestCase): self.assertEqual(actual, expected_value) self.assertIs(type(actual), expected_type) - @unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'float' has no attribute 'from_number' def test_from_number(self, cls=float): def eq(actual, expected): self.assertEqual(actual, expected) @@ -312,7 +311,6 @@ class GeneralFloatCases(unittest.TestCase): self.assertRaises(TypeError, cls.from_number, {}) self.assertRaises(TypeError, cls.from_number) - @unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'FloatSubclass' has no attribute 'from_number' def test_from_number_subclass(self): self.test_from_number(FloatSubclass) diff --git a/crates/vm/src/builtins/float.rs b/crates/vm/src/builtins/float.rs index 230d288b7..89e42ec0f 100644 --- a/crates/vm/src/builtins/float.rs +++ b/crates/vm/src/builtins/float.rs @@ -324,6 +324,21 @@ impl PyFloat { }) } + #[pyclassmethod] + fn from_number(cls: PyTypeRef, number: PyObjectRef, vm: &VirtualMachine) -> PyResult { + if number.class().is(vm.ctx.types.float_type) && cls.is(vm.ctx.types.float_type) { + return Ok(number); + } + + let value = number.try_float(vm)?.to_f64(); + let result = vm.ctx.new_float(value); + if cls.is(vm.ctx.types.float_type) { + Ok(result.into()) + } else { + PyType::call(&cls, vec![result.into()].into(), vm) + } + } + #[pyclassmethod] fn fromhex(cls: PyTypeRef, string: PyStrRef, vm: &VirtualMachine) -> PyResult { let result = crate::literal::float::from_hex(string.as_str().trim())