Repository: RustPython/RustPython
File: crates/vm/src/builtins/bool.rs (Rust)

Code before:
        vm.ctx.new_bool(self).into()
    }
}

impl<'a> TryFromBorrowedObject<'a> for bool {
    fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
        if obj.fast_isinstance(vm.ctx.types.int_type) {
            Ok(get_value(obj))
        } else {
            Err(vm.new_type_error(format!("Expected type bool, not {}", obj.class().name())))
        }
    }
}

impl PyObjectRef {
    /// Convert Python bool into Rust bool.
    pub fn try_to_bool(self, vm: &VirtualMachine) -> PyResult<bool> {
        if self.is(&vm.ctx.true_value) {
            return Ok(true);
        }
        if self.is(&vm.ctx.false_value) {
            return Ok(false);
        }
        let rs_bool = if let Some(nb_bool) = self.class().slots.as_number.boolean.load() {
            nb_bool(self.as_object().to_number(), vm)?
        } else {
            match vm.get_method(self.clone(), identifier!(vm, __bool__)) {
                Some(method_or_err) => {
                    // If descriptor returns Error, propagate it further
                    let method = method_or_err?;
                    let bool_obj = method.call((), vm)?;
                    if !bool_obj.fast_isinstance(vm.ctx.types.bool_type) {
                        return Err(vm.new_type_error(format!(
                            "__bool__ should return bool, returned type {}",
                            bool_obj.class().name()
                        )));
                    }

                    get_value(&bool_obj)
                }
                None => match vm.get_method(self, identifier!(vm, __len__)) {
                    Some(method_or_err) => {
                        let method = method_or_err?;
                        let bool_obj = method.call((), vm)?;
                        let int_obj = bool_obj.downcast_ref::<PyInt>().ok_or_else(|| {
                            vm.new_type_error(format!(
                                "'{}' object cannot be interpreted as an integer",
                                bool_obj.class().name()
                            ))
                        })?;


Review comment (refactor):
```suggestion
        } else {
            // TODO: Fully implement AsNumber and remove this block
```

Code after:
        vm.ctx.new_bool(self).into()
    }
}

impl<'a> TryFromBorrowedObject<'a> for bool {
    fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
        if obj.fast_isinstance(vm.ctx.types.int_type) {
            Ok(get_value(obj))
        } else {
            Err(vm.new_type_error(format!("Expected type bool, not {}", obj.class().name())))
        }
    }
}

impl PyObjectRef {
    /// Convert Python bool into Rust bool.
    pub fn try_to_bool(self, vm: &VirtualMachine) -> PyResult<bool> {
        if self.is(&vm.ctx.true_value) {
            return Ok(true);
        }
        if self.is(&vm.ctx.false_value) {
            return Ok(false);
        }
        let rs_bool = if let Some(nb_bool) = self.class().slots.as_number.boolean.load() {
            nb_bool(self.as_object().to_number(), vm)?
        } else {
            // TODO: Fully implement AsNumber and remove this block
            match vm.get_method(self.clone(), identifier!(vm, __bool__)) {
                Some(method_or_err) => {
                    // If descriptor returns Error, propagate it further
                    let method = method_or_err?;
                    let bool_obj = method.call((), vm)?;
                    if !bool_obj.fast_isinstance(vm.ctx.types.bool_type) {
                        return Err(vm.new_type_error(format!(
                            "__bool__ should return bool, returned type {}",
                            bool_obj.class().name()
                        )));
                    }

                    get_value(&bool_obj)
                }
                None => match vm.get_method(self, identifier!(vm, __len__)) {
                    Some(method_or_err) => {
                        let method = method_or_err?;
                        let bool_obj = method.call((), vm)?;
                        let int_obj = bool_obj.downcast_ref::<PyInt>().ok_or_else(|| {
                            vm.new_type_error(format!(
                                "'{}' object cannot be interpreted as an integer",
                                bool_obj.class().name()
                            ))
                        })?;