Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
remove len
  • Loading branch information
youknowone committed Jan 1, 2026
commit bb18d0c184b6eb9b4dc80a3b25481d03e1c926b2
28 changes: 7 additions & 21 deletions crates/vm/src/builtins/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::{
types::{AsNumber, Constructor, Representable},
};
use core::fmt::{Debug, Formatter};
use malachite_bigint::Sign;
use num_traits::Zero;

impl ToPyObject for bool {
Expand Down Expand Up @@ -50,29 +49,16 @@ impl PyObjectRef {
return nb_bool(self.as_object().number(), vm);
}

// 2. Try sq_length slot
if let Some(sq_length) = slots.as_sequence.length.load() {
let len = sq_length(self.as_object().sequence_unchecked(), vm)?;
// 2. Try mp_length slot (mapping protocol)
if let Some(mp_length) = slots.as_mapping.length.load() {
let len = mp_length(self.as_object().mapping_unchecked(), vm)?;
return Ok(len != 0);
}

// 3. Fallback for types not yet using slots
// TODO: Remove this block when all types implement AsSequence
if let Some(method_or_err) = vm.get_method(self, identifier!(vm, __len__)) {
let method = method_or_err?;
let len_obj = method.call((), vm)?;
let int_obj = len_obj.downcast_ref::<PyInt>().ok_or_else(|| {
vm.new_type_error(format!(
"'{}' object cannot be interpreted as an integer",
len_obj.class().name()
))
})?;

let len_val = int_obj.as_bigint();
if len_val.sign() == Sign::Minus {
return Err(vm.new_value_error("__len__() should return >= 0"));
}
return Ok(!len_val.is_zero());
// 3. Try sq_length slot (sequence protocol)
if let Some(sq_length) = slots.as_sequence.length.load() {
let len = sq_length(self.as_object().sequence_unchecked(), vm)?;
return Ok(len != 0);
}

// 4. Default: objects without __bool__ or __len__ are truthy
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/builtins/bytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ impl PyByteArray {
self.inner().capacity()
}

#[pymethod]
fn __len__(&self) -> usize {
self.borrow_buf().len()
}
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/builtins/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ impl PyRef<PyBytes> {
)]
impl PyBytes {
#[inline]
#[pymethod]
pub const fn __len__(&self) -> usize {
self.inner.len()
}
Expand Down
2 changes: 0 additions & 2 deletions crates/vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ impl PyDict {
}
}

#[pymethod]
pub fn __len__(&self) -> usize {
self.entries.len()
}
Expand Down Expand Up @@ -764,7 +763,6 @@ trait DictView: PyPayload + PyClassDef + Iterable + Representable {
fn dict(&self) -> &Py<PyDict>;
fn item(vm: &VirtualMachine, key: PyObjectRef, value: PyObjectRef) -> PyObjectRef;

#[pymethod]
fn __len__(&self) -> usize {
self.dict().__len__()
}
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/builtins/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ impl PyList {
}

#[allow(clippy::len_without_is_empty)]
#[pymethod]
pub fn __len__(&self) -> usize {
self.borrow_vec().len()
}
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/mappingproxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ impl PyMappingProxy {
PyGenericAlias::from_args(cls, args, vm)
}

#[pymethod]
fn __len__(&self, vm: &VirtualMachine) -> PyResult<usize> {
let obj = self.to_object(vm)?;
obj.length(vm)
Expand Down Expand Up @@ -235,6 +234,7 @@ impl AsMapping for PyMappingProxy {
impl AsSequence for PyMappingProxy {
fn as_sequence() -> &'static PySequenceMethods {
static AS_SEQUENCE: LazyLock<PySequenceMethods> = LazyLock::new(|| PySequenceMethods {
length: atomic_func!(|seq, vm| PyMappingProxy::sequence_downcast(seq).__len__(vm)),
contains: atomic_func!(
|seq, target, vm| PyMappingProxy::sequence_downcast(seq)._contains(target, vm)
),
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/builtins/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,6 @@ impl PyMemoryView {
Err(vm.new_type_error("cannot delete memory"))
}

#[pymethod]
fn __len__(&self, vm: &VirtualMachine) -> PyResult<usize> {
self.try_not_released(vm)?;
if self.desc.ndim() == 0 {
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/builtins/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ impl PyTuple {
}

#[inline]
#[pymethod]
pub const fn __len__(&self) -> usize {
self.elements.len()
}
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/stdlib/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ mod _collections {
Ok(zelf)
}

#[pymethod]
fn __len__(&self) -> usize {
self.borrow_deque().len()
}
Expand Down
1 change: 0 additions & 1 deletion crates/vm/src/stdlib/ctypes/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,6 @@ impl PyCArray {
Ok(())
}

#[pymethod]
fn __len__(zelf: &Py<Self>, _vm: &VirtualMachine) -> usize {
zelf.class().stg_info_opt().map_or(0, |i| i.length)
}
Expand Down
Loading