Skip to content

Commit 99f103a

Browse files
committed
PyBool
1 parent 7cdaba7 commit 99f103a

File tree

2 files changed

+92
-91
lines changed

2 files changed

+92
-91
lines changed

tests/snippets/bools.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def __bool__(self):
9494
assert bool([1]) is True
9595
assert bool(set([1,2])) is True
9696

97+
assert repr(True) == "True"
9798

9899
# Check __len__ work
99100
class TestMagicMethodLenZero:

vm/src/obj/objbool.rs

Lines changed: 91 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use num_traits::Zero;
33

44
use crate::function::PyFuncArgs;
55
use crate::pyobject::{
6-
IdProtocol, IntoPyObject, PyContext, PyObjectRef, PyResult, TryFromObject, TypeProtocol,
6+
IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyResult, TryFromObject,
7+
TypeProtocol,
78
};
89
use crate::vm::VirtualMachine;
910

@@ -78,114 +79,113 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
7879
Ok(rs_bool)
7980
}
8081

81-
pub fn init(context: &PyContext) {
82-
let bool_doc = "bool(x) -> bool
83-
84-
Returns True when the argument x is true, False otherwise.
85-
The builtins True and False are the only two instances of the class bool.
86-
The class bool is a subclass of the class int, and cannot be subclassed.";
87-
88-
let bool_type = &context.types.bool_type;
89-
extend_class!(context, bool_type, {
90-
(slot new) => bool_new,
91-
"__repr__" => context.new_method(bool_repr),
92-
"__format__" => context.new_method(bool_format),
93-
"__or__" => context.new_method(bool_or),
94-
"__ror__" => context.new_method(bool_or),
95-
"__and__" => context.new_method(bool_and),
96-
"__rand__" => context.new_method(bool_and),
97-
"__xor__" => context.new_method(bool_xor),
98-
"__rxor__" => context.new_method(bool_xor),
99-
"__doc__" => context.new_str(bool_doc.to_string()),
100-
});
101-
}
82+
/// bool(x) -> bool
83+
///
84+
/// Returns True when the argument x is true, False otherwise.
85+
/// The builtins True and False are the only two instances of the class bool.
86+
/// The class bool is a subclass of the class int, and cannot be subclassed.
87+
#[pyclass]
88+
struct PyBool;
10289

103-
pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<bool> {
104-
if objtype::isinstance(obj, &vm.ctx.bool_type()) {
105-
let value = get_value(obj);
106-
Ok(!value)
107-
} else {
108-
Err(vm.new_type_error(format!("Can only invert a bool, on {:?}", obj)))
90+
#[pyimpl]
91+
impl PyBool {
92+
#[pymethod(magic)]
93+
fn repr(zelf: bool) -> String {
94+
if zelf { "True" } else { "False" }.to_owned()
10995
}
110-
}
11196

112-
// Retrieve inner int value:
113-
pub fn get_value(obj: &PyObjectRef) -> bool {
114-
!obj.payload::<PyInt>().unwrap().as_bigint().is_zero()
115-
}
97+
#[pymethod(magic)]
98+
fn format(
99+
obj: PyObjectRef,
100+
format_spec: PyStringRef,
101+
vm: &VirtualMachine,
102+
) -> PyResult<PyStringRef> {
103+
if format_spec.as_str().is_empty() {
104+
vm.to_str(&obj)
105+
} else {
106+
Err(vm
107+
.new_type_error("unsupported format string passed to bool.__format__".to_string()))
108+
}
109+
}
116110

117-
pub fn get_py_int(obj: &PyObjectRef) -> &PyInt {
118-
&obj.payload::<PyInt>().unwrap()
119-
}
111+
#[pymethod(name = "__ror__")]
112+
#[pymethod(magic)]
113+
fn or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
114+
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
115+
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
116+
{
117+
let lhs = get_value(&lhs);
118+
let rhs = get_value(&rhs);
119+
(lhs || rhs).into_pyobject(vm)
120+
} else {
121+
get_py_int(&lhs).or(rhs.clone(), vm).into_pyobject(vm)
122+
}
123+
}
120124

121-
fn bool_repr(obj: bool, _vm: &VirtualMachine) -> String {
122-
if obj {
123-
"True".to_string()
124-
} else {
125-
"False".to_string()
125+
#[pymethod(name = "__rand__")]
126+
#[pymethod(magic)]
127+
fn and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
128+
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
129+
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
130+
{
131+
let lhs = get_value(&lhs);
132+
let rhs = get_value(&rhs);
133+
(lhs && rhs).into_pyobject(vm)
134+
} else {
135+
get_py_int(&lhs).and(rhs.clone(), vm).into_pyobject(vm)
136+
}
126137
}
127-
}
128138

129-
fn bool_format(
130-
obj: PyObjectRef,
131-
format_spec: PyStringRef,
132-
vm: &VirtualMachine,
133-
) -> PyResult<PyStringRef> {
134-
if format_spec.as_str().is_empty() {
135-
vm.to_str(&obj)
136-
} else {
137-
Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_string()))
139+
#[pymethod(name = "__rxor__")]
140+
#[pymethod(magic)]
141+
fn xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
142+
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
143+
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
144+
{
145+
let lhs = get_value(&lhs);
146+
let rhs = get_value(&rhs);
147+
(lhs ^ rhs).into_pyobject(vm)
148+
} else {
149+
get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm)
150+
}
138151
}
139-
}
140152

141-
fn bool_or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
142-
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
143-
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
144-
{
145-
let lhs = get_value(&lhs);
146-
let rhs = get_value(&rhs);
147-
(lhs || rhs).into_pyobject(vm)
148-
} else {
149-
get_py_int(&lhs).or(rhs.clone(), vm).into_pyobject(vm)
153+
#[pyslot]
154+
fn tp_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
155+
arg_check!(
156+
vm,
157+
args,
158+
required = [(_zelf, Some(vm.ctx.type_type()))],
159+
optional = [(val, None)]
160+
);
161+
let value = match val {
162+
Some(val) => boolval(vm, val.clone())?,
163+
None => false,
164+
};
165+
Ok(vm.new_bool(value))
150166
}
151167
}
152168

153-
fn bool_and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
154-
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
155-
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
156-
{
157-
let lhs = get_value(&lhs);
158-
let rhs = get_value(&rhs);
159-
(lhs && rhs).into_pyobject(vm)
160-
} else {
161-
get_py_int(&lhs).and(rhs.clone(), vm).into_pyobject(vm)
162-
}
169+
pub(crate) fn init(context: &PyContext) {
170+
PyBool::extend_class(context, &context.types.bool_type);
163171
}
164172

165-
fn bool_xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
166-
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
167-
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
168-
{
169-
let lhs = get_value(&lhs);
170-
let rhs = get_value(&rhs);
171-
(lhs ^ rhs).into_pyobject(vm)
173+
pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<bool> {
174+
if objtype::isinstance(obj, &vm.ctx.bool_type()) {
175+
let value = get_value(obj);
176+
Ok(!value)
172177
} else {
173-
get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm)
178+
Err(vm.new_type_error(format!("Can only invert a bool, on {:?}", obj)))
174179
}
175180
}
176181

177-
fn bool_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
178-
arg_check!(
179-
vm,
180-
args,
181-
required = [(_zelf, Some(vm.ctx.type_type()))],
182-
optional = [(val, None)]
183-
);
184-
let value = match val {
185-
Some(val) => boolval(vm, val.clone())?,
186-
None => false,
187-
};
188-
Ok(vm.new_bool(value))
182+
// Retrieve inner int value:
183+
pub fn get_value(obj: &PyObjectRef) -> bool {
184+
!obj.payload::<PyInt>().unwrap().as_bigint().is_zero()
185+
}
186+
187+
pub fn get_py_int(obj: &PyObjectRef) -> &PyInt {
188+
&obj.payload::<PyInt>().unwrap()
189189
}
190190

191191
#[derive(Debug, Copy, Clone, PartialEq)]

0 commit comments

Comments
 (0)