Skip to content

Commit a798467

Browse files
committed
migrate __bool__
1 parent 1f2ba99 commit a798467

File tree

9 files changed

+115
-80
lines changed

9 files changed

+115
-80
lines changed

crates/vm/src/builtins/range.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use crate::{
88
class::PyClassImpl,
99
common::hash::PyHash,
1010
function::{ArgIndex, FuncArgs, OptionalArg, PyComparisonValue},
11-
protocol::{PyIterReturn, PyMappingMethods, PySequenceMethods},
11+
protocol::{PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
1212
types::{
13-
AsMapping, AsSequence, Comparable, Hashable, IterNext, Iterable, PyComparisonOp,
13+
AsMapping, AsNumber, AsSequence, Comparable, Hashable, IterNext, Iterable, PyComparisonOp,
1414
Representable, SelfIter,
1515
},
1616
};
@@ -176,6 +176,7 @@ pub fn init(context: &Context) {
176176
with(
177177
Py,
178178
AsMapping,
179+
AsNumber,
179180
AsSequence,
180181
Hashable,
181182
Comparable,
@@ -269,11 +270,6 @@ impl PyRange {
269270
self.compute_length()
270271
}
271272

272-
#[pymethod]
273-
fn __bool__(&self) -> bool {
274-
!self.is_empty()
275-
}
276-
277273
#[pymethod]
278274
fn __reduce__(&self, vm: &VirtualMachine) -> (PyTypeRef, PyTupleRef) {
279275
let range_parameters: Vec<PyObjectRef> = [&self.start, &self.stop, &self.step]
@@ -426,6 +422,19 @@ impl AsSequence for PyRange {
426422
}
427423
}
428424

425+
impl AsNumber for PyRange {
426+
fn as_number() -> &'static PyNumberMethods {
427+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
428+
boolean: Some(|number, _vm| {
429+
let zelf = number.obj.downcast_ref::<PyRange>().unwrap();
430+
Ok(!zelf.is_empty())
431+
}),
432+
..PyNumberMethods::NOT_IMPLEMENTED
433+
};
434+
&AS_NUMBER
435+
}
436+
}
437+
429438
impl Hashable for PyRange {
430439
fn hash(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
431440
let length = zelf.compute_length();

crates/vm/src/builtins/singletons.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,7 @@ impl Constructor for PyNone {
5050
}
5151

5252
#[pyclass(with(Constructor, AsNumber, Representable))]
53-
impl PyNone {
54-
#[pymethod]
55-
const fn __bool__(&self) -> bool {
56-
false
57-
}
58-
}
53+
impl PyNone {}
5954

6055
impl Representable for PyNone {
6156
#[inline]
@@ -103,22 +98,27 @@ impl Constructor for PyNotImplemented {
10398
}
10499
}
105100

106-
#[pyclass(with(Constructor))]
101+
#[pyclass(with(Constructor, AsNumber, Representable))]
107102
impl PyNotImplemented {
108-
// TODO: As per https://bugs.python.org/issue35712, using NotImplemented
109-
// in boolean contexts will need to raise a DeprecationWarning in 3.9
110-
// and, eventually, a TypeError.
111-
#[pymethod]
112-
const fn __bool__(&self) -> bool {
113-
true
114-
}
115-
116103
#[pymethod]
117104
fn __reduce__(&self, vm: &VirtualMachine) -> PyStrRef {
118105
vm.ctx.names.NotImplemented.to_owned()
119106
}
120107
}
121108

109+
impl AsNumber for PyNotImplemented {
110+
fn as_number() -> &'static PyNumberMethods {
111+
// TODO: As per https://bugs.python.org/issue35712, using NotImplemented
112+
// in boolean contexts will need to raise a DeprecationWarning in 3.9
113+
// and, eventually, a TypeError.
114+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
115+
boolean: Some(|_number, _vm| Ok(true)),
116+
..PyNumberMethods::NOT_IMPLEMENTED
117+
};
118+
&AS_NUMBER
119+
}
120+
}
121+
122122
impl Representable for PyNotImplemented {
123123
#[inline]
124124
fn repr(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {

crates/vm/src/builtins/tuple.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ use crate::{
1010
convert::{ToPyObject, TransmuteFromObject},
1111
function::{ArgSize, FuncArgs, OptionalArg, PyArithmeticValue, PyComparisonValue},
1212
iter::PyExactSizeIterator,
13-
protocol::{PyIterReturn, PyMappingMethods, PySequenceMethods},
13+
protocol::{PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
1414
recursion::ReprGuard,
1515
sequence::{OptionalRangeArgs, SequenceExt},
1616
sliceable::{SequenceIndex, SliceableSequenceOp},
1717
types::{
18-
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, Iterable,
18+
AsMapping, AsNumber, AsSequence, Comparable, Constructor, Hashable, IterNext, Iterable,
1919
PyComparisonOp, Representable, SelfIter,
2020
},
2121
utils::collection_repr,
@@ -260,7 +260,7 @@ impl<T> PyTuple<PyRef<T>> {
260260
#[pyclass(
261261
itemsize = core::mem::size_of::<crate::PyObjectRef>(),
262262
flags(BASETYPE, SEQUENCE, _MATCH_SELF),
263-
with(AsMapping, AsSequence, Hashable, Comparable, Iterable, Constructor, Representable)
263+
with(AsMapping, AsNumber, AsSequence, Hashable, Comparable, Iterable, Constructor, Representable)
264264
)]
265265
impl PyTuple {
266266
#[pymethod]
@@ -286,11 +286,6 @@ impl PyTuple {
286286
PyArithmeticValue::from_option(added.ok())
287287
}
288288

289-
#[pymethod]
290-
const fn __bool__(&self) -> bool {
291-
!self.elements.is_empty()
292-
}
293-
294289
#[pymethod]
295290
fn count(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
296291
let mut count: usize = 0;
@@ -423,6 +418,19 @@ impl AsSequence for PyTuple {
423418
}
424419
}
425420

421+
impl AsNumber for PyTuple {
422+
fn as_number() -> &'static PyNumberMethods {
423+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
424+
boolean: Some(|number, _vm| {
425+
let zelf = number.obj.downcast_ref::<PyTuple>().unwrap();
426+
Ok(!zelf.elements.is_empty())
427+
}),
428+
..PyNumberMethods::NOT_IMPLEMENTED
429+
};
430+
&AS_NUMBER
431+
}
432+
}
433+
426434
impl Hashable for PyTuple {
427435
#[inline]
428436
fn hash(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {

crates/vm/src/builtins/weakproxy.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use crate::{
44
class::PyClassImpl,
55
common::hash::PyHash,
66
function::{OptionalArg, PyComparisonValue, PySetterValue},
7-
protocol::{PyIter, PyIterReturn, PyMappingMethods, PySequenceMethods},
7+
protocol::{PyIter, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
88
stdlib::builtins::reversed,
99
types::{
10-
AsMapping, AsSequence, Comparable, Constructor, GetAttr, Hashable, IterNext, Iterable,
11-
PyComparisonOp, Representable, SetAttr,
10+
AsMapping, AsNumber, AsSequence, Comparable, Constructor, GetAttr, Hashable, IterNext,
11+
Iterable, PyComparisonOp, Representable, SetAttr,
1212
},
1313
};
1414
use std::sync::LazyLock;
@@ -68,6 +68,7 @@ crate::common::static_cell! {
6868
SetAttr,
6969
Constructor,
7070
Comparable,
71+
AsNumber,
7172
AsSequence,
7273
AsMapping,
7374
Representable,
@@ -87,11 +88,6 @@ impl PyWeakProxy {
8788
self.try_upgrade(vm)?.length(vm)
8889
}
8990

90-
#[pymethod]
91-
fn __bool__(&self, vm: &VirtualMachine) -> PyResult<bool> {
92-
self.try_upgrade(vm)?.is_true(vm)
93-
}
94-
9591
#[pymethod]
9692
fn __bytes__(&self, vm: &VirtualMachine) -> PyResult {
9793
self.try_upgrade(vm)?.bytes(vm)
@@ -171,6 +167,19 @@ impl SetAttr for PyWeakProxy {
171167
}
172168
}
173169

170+
impl AsNumber for PyWeakProxy {
171+
fn as_number() -> &'static PyNumberMethods {
172+
static AS_NUMBER: LazyLock<PyNumberMethods> = LazyLock::new(|| PyNumberMethods {
173+
boolean: Some(|number, vm| {
174+
let zelf = number.obj.downcast_ref::<PyWeakProxy>().unwrap();
175+
zelf.try_upgrade(vm)?.is_true(vm)
176+
}),
177+
..PyNumberMethods::NOT_IMPLEMENTED
178+
});
179+
&AS_NUMBER
180+
}
181+
}
182+
174183
impl Comparable for PyWeakProxy {
175184
fn cmp(
176185
zelf: &Py<Self>,

crates/vm/src/stdlib/collections.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ mod _collections {
1212
common::lock::{PyMutex, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard},
1313
function::{KwArgs, OptionalArg, PyComparisonValue},
1414
iter::PyExactSizeIterator,
15-
protocol::{PyIterReturn, PySequenceMethods},
15+
protocol::{PyIterReturn, PyNumberMethods, PySequenceMethods},
1616
recursion::ReprGuard,
1717
sequence::{MutObjectSequenceOp, OptionalRangeArgs},
1818
sliceable::SequenceIndexOp,
1919
types::{
20-
AsSequence, Comparable, Constructor, DefaultConstructor, Initializer, IterNext,
21-
Iterable, PyComparisonOp, Representable, SelfIter,
20+
AsNumber, AsSequence, Comparable, Constructor, DefaultConstructor, Initializer,
21+
IterNext, Iterable, PyComparisonOp, Representable, SelfIter,
2222
},
2323
utils::collection_repr,
2424
};
@@ -60,6 +60,7 @@ mod _collections {
6060
with(
6161
Constructor,
6262
Initializer,
63+
AsNumber,
6364
AsSequence,
6465
Comparable,
6566
Iterable,
@@ -354,11 +355,6 @@ mod _collections {
354355
self.borrow_deque().len()
355356
}
356357

357-
#[pymethod]
358-
fn __bool__(&self) -> bool {
359-
!self.borrow_deque().is_empty()
360-
}
361-
362358
#[pymethod]
363359
fn __add__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
364360
self.concat(&other, vm)
@@ -496,6 +492,19 @@ mod _collections {
496492
}
497493
}
498494

495+
impl AsNumber for PyDeque {
496+
fn as_number() -> &'static PyNumberMethods {
497+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
498+
boolean: Some(|number, _vm| {
499+
let zelf = number.obj.downcast_ref::<PyDeque>().unwrap();
500+
Ok(!zelf.borrow_deque().is_empty())
501+
}),
502+
..PyNumberMethods::NOT_IMPLEMENTED
503+
};
504+
&AS_NUMBER
505+
}
506+
}
507+
499508
impl AsSequence for PyDeque {
500509
fn as_sequence() -> &'static PySequenceMethods {
501510
static AS_SEQUENCE: PySequenceMethods = PySequenceMethods {

crates/vm/src/stdlib/ctypes/function.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::{
1212
builtins::{PyBytes, PyDict, PyNone, PyStr, PyTuple, PyType, PyTypeRef},
1313
class::StaticType,
1414
function::FuncArgs,
15-
protocol::{BufferDescriptor, PyBuffer},
16-
types::{AsBuffer, Callable, Constructor, Initializer, Representable},
15+
protocol::{BufferDescriptor, PyBuffer, PyNumberMethods},
16+
types::{AsBuffer, AsNumber, Callable, Constructor, Initializer, Representable},
1717
vm::thread::with_current_vm,
1818
};
1919
use alloc::borrow::Cow;
@@ -1772,7 +1772,10 @@ impl AsBuffer for PyCFuncPtr {
17721772
}
17731773
}
17741774

1775-
#[pyclass(flags(BASETYPE), with(Callable, Constructor, Representable, AsBuffer))]
1775+
#[pyclass(
1776+
flags(BASETYPE),
1777+
with(Callable, Constructor, AsNumber, Representable, AsBuffer)
1778+
)]
17761779
impl PyCFuncPtr {
17771780
// restype getter/setter
17781781
#[pygetset]
@@ -1848,11 +1851,18 @@ impl PyCFuncPtr {
18481851
.map(|stg| stg.flags.bits())
18491852
.unwrap_or(StgInfoFlags::empty().bits())
18501853
}
1854+
}
18511855

1852-
// bool conversion - check if function pointer is set
1853-
#[pymethod]
1854-
fn __bool__(&self) -> bool {
1855-
self.get_func_ptr() != 0
1856+
impl AsNumber for PyCFuncPtr {
1857+
fn as_number() -> &'static PyNumberMethods {
1858+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
1859+
boolean: Some(|number, _vm| {
1860+
let zelf = number.obj.downcast_ref::<PyCFuncPtr>().unwrap();
1861+
Ok(zelf.get_func_ptr() != 0)
1862+
}),
1863+
..PyNumberMethods::NOT_IMPLEMENTED
1864+
};
1865+
&AS_NUMBER
18561866
}
18571867
}
18581868

crates/vm/src/stdlib/ctypes/pointer.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ impl Initializer for PyCPointer {
261261

262262
#[pyclass(
263263
flags(BASETYPE, IMMUTABLETYPE),
264-
with(Constructor, Initializer, AsBuffer)
264+
with(Constructor, Initializer, AsNumber, AsBuffer)
265265
)]
266266
impl PyCPointer {
267267
/// Get the pointer value stored in buffer as usize
@@ -279,12 +279,6 @@ impl PyCPointer {
279279
}
280280
}
281281

282-
/// Pointer_bool: returns True if pointer is not NULL
283-
#[pymethod]
284-
fn __bool__(&self) -> bool {
285-
self.get_ptr_value() != 0
286-
}
287-
288282
/// contents getter - reads address from b_ptr and creates an instance of the pointed-to type
289283
#[pygetset]
290284
fn contents(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
@@ -779,6 +773,19 @@ impl PyCPointer {
779773
}
780774
}
781775

776+
impl AsNumber for PyCPointer {
777+
fn as_number() -> &'static PyNumberMethods {
778+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
779+
boolean: Some(|number, _vm| {
780+
let zelf = number.obj.downcast_ref::<PyCPointer>().unwrap();
781+
Ok(zelf.get_ptr_value() != 0)
782+
}),
783+
..PyNumberMethods::NOT_IMPLEMENTED
784+
};
785+
&AS_NUMBER
786+
}
787+
}
788+
782789
impl AsBuffer for PyCPointer {
783790
fn as_buffer(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<PyBuffer> {
784791
let stg_info = zelf

crates/vm/src/stdlib/ctypes/simple.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,14 +1133,6 @@ impl PyCSimple {
11331133
self.0.base.read().clone()
11341134
}
11351135

1136-
/// return True if any byte in buffer is non-zero
1137-
#[pymethod]
1138-
fn __bool__(&self) -> bool {
1139-
let buffer = self.0.buffer.read();
1140-
// Simple_bool: memcmp(self->b_ptr, zeros, self->b_size)
1141-
buffer.iter().any(|&b| b != 0)
1142-
}
1143-
11441136
#[pygetset]
11451137
pub fn value(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
11461138
let zelf: &Py<Self> = instance

0 commit comments

Comments
 (0)