Skip to content

Commit 8d7be94

Browse files
committed
PyBool
1 parent 438dcec commit 8d7be94

File tree

2 files changed

+91
-91
lines changed

2 files changed

+91
-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: 90 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,112 @@ 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_owned()),
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.new_type_error("unsupported format string passed to bool.__format__".to_owned()))
107+
}
108+
}
116109

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

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

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_owned()))
138+
#[pymethod(name = "__rxor__")]
139+
#[pymethod(magic)]
140+
fn xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
141+
if objtype::isinstance(&lhs, &vm.ctx.bool_type())
142+
&& objtype::isinstance(&rhs, &vm.ctx.bool_type())
143+
{
144+
let lhs = get_value(&lhs);
145+
let rhs = get_value(&rhs);
146+
(lhs ^ rhs).into_pyobject(vm)
147+
} else {
148+
get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm)
149+
}
138150
}
139-
}
140151

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)
152+
#[pyslot]
153+
fn tp_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
154+
arg_check!(
155+
vm,
156+
args,
157+
required = [(_zelf, Some(vm.ctx.type_type()))],
158+
optional = [(val, None)]
159+
);
160+
let value = match val {
161+
Some(val) => boolval(vm, val.clone())?,
162+
None => false,
163+
};
164+
Ok(vm.new_bool(value))
150165
}
151166
}
152167

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-
}
168+
pub(crate) fn init(context: &PyContext) {
169+
PyBool::extend_class(context, &context.types.bool_type);
163170
}
164171

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)
172+
pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<bool> {
173+
if objtype::isinstance(obj, &vm.ctx.bool_type()) {
174+
let value = get_value(obj);
175+
Ok(!value)
172176
} else {
173-
get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm)
177+
Err(vm.new_type_error(format!("Can only invert a bool, on {:?}", obj)))
174178
}
175179
}
176180

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))
181+
// Retrieve inner int value:
182+
pub fn get_value(obj: &PyObjectRef) -> bool {
183+
!obj.payload::<PyInt>().unwrap().as_bigint().is_zero()
184+
}
185+
186+
pub fn get_py_int(obj: &PyObjectRef) -> &PyInt {
187+
&obj.payload::<PyInt>().unwrap()
189188
}
190189

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

0 commit comments

Comments
 (0)