mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Implement bool.__or__, __and__ and __xor__
This commit is contained in:
1 parent
26306b528f
commit
ea347dfdec
3 files changed
+54
-3
No files matched your search
@@ -51,3 +51,15 @@ assert True > 0
|
||||
assert int(True) == 1
|
||||
assert True.conjugate() == 1
|
||||
assert isinstance(True.conjugate(), int)
|
||||
|
||||
# Boolean operations on pairs of Bools should return Bools, not ints
|
||||
assert (False | True) is True
|
||||
assert (False & True) is False
|
||||
assert (False ^ True) is True
|
||||
# But only if both are Bools
|
||||
assert (False | 1) is not True
|
||||
assert (0 | True) is not True
|
||||
assert (False & 1) is not False
|
||||
assert (0 & True) is not False
|
||||
assert (False ^ 1) is not True
|
||||
assert (0 ^ True) is not True
|
||||
@@ -42,6 +42,9 @@ The class bool is a subclass of the class int, and cannot be subclassed.";
|
||||
extend_class!(context, bool_type, {
|
||||
"__new__" => context.new_rustfunc(bool_new),
|
||||
"__repr__" => context.new_rustfunc(bool_repr),
|
||||
"__or__" => context.new_rustfunc(bool_or),
|
||||
"__and__" => context.new_rustfunc(bool_and),
|
||||
"__xor__" => context.new_rustfunc(bool_xor),
|
||||
"__doc__" => context.new_str(bool_doc.to_string())
|
||||
});
|
||||
}
|
||||
@@ -71,6 +74,42 @@ fn bool_repr(vm: &VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObj
|
||||
Ok(vm.new_str(s))
|
||||
}
|
||||
|
||||
fn bool_or(vm: &VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
|
||||
arg_check!(vm, args, required = [(lhs, None), (rhs, None)]);
|
||||
|
||||
if objtype::isinstance(lhs, &vm.ctx.bool_type()) && objtype::isinstance(rhs, &vm.ctx.bool_type()) {
|
||||
let lhs = get_value(lhs);
|
||||
let rhs = get_value(rhs);
|
||||
(lhs || rhs).into_pyobject(vm)
|
||||
} else {
|
||||
Ok(lhs.payload::<PyInt>().unwrap().or(rhs.clone(), vm))
|
||||
}
|
||||
}
|
||||
|
||||
fn bool_and(vm: &VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
|
||||
arg_check!(vm, args, required = [(lhs, None), (rhs, None)]);
|
||||
|
||||
if objtype::isinstance(lhs, &vm.ctx.bool_type()) && objtype::isinstance(rhs, &vm.ctx.bool_type()) {
|
||||
let lhs = get_value(lhs);
|
||||
let rhs = get_value(rhs);
|
||||
(lhs && rhs).into_pyobject(vm)
|
||||
} else {
|
||||
Ok(lhs.payload::<PyInt>().unwrap().and(rhs.clone(), vm))
|
||||
}
|
||||
}
|
||||
|
||||
fn bool_xor(vm: &VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
|
||||
arg_check!(vm, args, required = [(lhs, None), (rhs, None)]);
|
||||
|
||||
if objtype::isinstance(lhs, &vm.ctx.bool_type()) && objtype::isinstance(rhs, &vm.ctx.bool_type()) {
|
||||
let lhs = get_value(lhs);
|
||||
let rhs = get_value(rhs);
|
||||
(lhs ^ rhs).into_pyobject(vm)
|
||||
} else {
|
||||
Ok(lhs.payload::<PyInt>().unwrap().xor(rhs.clone(), vm))
|
||||
}
|
||||
}
|
||||
|
||||
fn bool_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
|
||||
@@ -286,7 +286,7 @@ impl PyInt {
|
||||
}
|
||||
|
||||
#[pymethod(name = "__xor__")]
|
||||
fn xor(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
pub fn xor(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if objtype::isinstance(&other, &vm.ctx.int_type()) {
|
||||
vm.ctx.new_int((&self.value) ^ get_value(&other))
|
||||
} else {
|
||||
@@ -300,7 +300,7 @@ impl PyInt {
|
||||
}
|
||||
|
||||
#[pymethod(name = "__or__")]
|
||||
fn or(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
pub fn or(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if objtype::isinstance(&other, &vm.ctx.int_type()) {
|
||||
vm.ctx.new_int((&self.value) | get_value(&other))
|
||||
} else {
|
||||
@@ -309,7 +309,7 @@ impl PyInt {
|
||||
}
|
||||
|
||||
#[pymethod(name = "__and__")]
|
||||
fn and(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
pub fn and(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
if objtype::isinstance(&other, &vm.ctx.int_type()) {
|
||||
let v2 = get_value(&other);
|
||||
vm.ctx.new_int((&self.value) & v2)
|
||||
|
||||
Reference in new issue
Block a user