Skip to content

Commit 81302ce

Browse files
RobertBerglundyouknowone
authored andcommitted
impl __sizeof__ for bytearray, int, list, str, dict and set (RustPython#1426)
1 parent 9f6ccf1 commit 81302ce

File tree

7 files changed

+50
-0
lines changed

7 files changed

+50
-0
lines changed

vm/src/dictdatatype.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use num_bigint::ToBigInt;
99
/// And: http://code.activestate.com/recipes/578375/
1010
use std::collections::{hash_map::DefaultHasher, HashMap};
1111
use std::hash::{Hash, Hasher};
12+
use std::mem::size_of;
1213

1314
/// hash value of an object returned by __hash__
1415
type HashValue = pyhash::PyHash;
@@ -269,6 +270,10 @@ impl<T: Clone> Dict<T> {
269270
None => None,
270271
}
271272
}
273+
274+
pub fn sizeof(&self) -> usize {
275+
size_of::<Self>() + self.size * size_of::<DictEntry<T>>()
276+
}
272277
}
273278

274279
enum LookupResult {

vm/src/obj/objbytearray.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::pyobject::{
2121
TryFromObject,
2222
};
2323
use crate::vm::VirtualMachine;
24+
use std::mem::size_of;
2425

2526
/// "bytearray(iterable_of_ints) -> bytearray\n\
2627
/// bytearray(string, encoding[, errors]) -> bytearray\n\
@@ -109,6 +110,11 @@ impl PyByteArrayRef {
109110
self.inner.borrow().len()
110111
}
111112

113+
#[pymethod(name = "__sizeof__")]
114+
fn sizeof(self, _vm: &VirtualMachine) -> usize {
115+
size_of::<Self>() + self.inner.borrow().len() * size_of::<u8>()
116+
}
117+
112118
#[pymethod(name = "__eq__")]
113119
fn eq(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
114120
self.inner.borrow().eq(other, vm)

vm/src/obj/objdict.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::pyobject::{
1212
};
1313
use crate::vm::{ReprGuard, VirtualMachine};
1414

15+
use std::mem::size_of;
16+
1517
pub type DictContentType = dictdatatype::Dict;
1618

1719
#[derive(Default)]
@@ -154,6 +156,10 @@ impl PyDictRef {
154156
self.entries.borrow().len()
155157
}
156158

159+
fn sizeof(self, _vm: &VirtualMachine) -> usize {
160+
size_of::<Self>() + self.entries.borrow().sizeof()
161+
}
162+
157163
fn repr(self, vm: &VirtualMachine) -> PyResult<String> {
158164
let s = if let Some(_guard) = ReprGuard::enter(self.as_object()) {
159165
let mut str_parts = vec![];
@@ -576,6 +582,7 @@ pub fn init(context: &PyContext) {
576582
extend_class!(context, &context.types.dict_type, {
577583
"__bool__" => context.new_rustfunc(PyDictRef::bool),
578584
"__len__" => context.new_rustfunc(PyDictRef::len),
585+
"__sizeof__" => context.new_rustfunc(PyDictRef::sizeof),
579586
"__contains__" => context.new_rustfunc(PyDictRef::contains),
580587
"__delitem__" => context.new_rustfunc(PyDictRef::inner_delitem),
581588
"__eq__" => context.new_rustfunc(PyDictRef::eq),

vm/src/obj/objint.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt;
2+
use std::mem::size_of;
23
use std::str;
34

45
use num_bigint::{BigInt, Sign};
@@ -573,6 +574,11 @@ impl PyInt {
573574
!self.value.is_zero()
574575
}
575576

577+
#[pymethod(name = "__sizeof__")]
578+
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
579+
size_of::<Self>()
580+
}
581+
576582
#[pymethod]
577583
fn bit_length(&self, _vm: &VirtualMachine) -> usize {
578584
self.value.bits()

vm/src/obj/objlist.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::cell::{Cell, RefCell};
22
use std::fmt;
3+
use std::mem::size_of;
34
use std::ops::Range;
45

56
use num_bigint::{BigInt, ToBigInt};
@@ -191,6 +192,10 @@ impl PyListRef {
191192
self.elements.borrow().len()
192193
}
193194

195+
fn sizeof(self, _vm: &VirtualMachine) -> usize {
196+
size_of::<Self>() + self.elements.borrow().capacity() * size_of::<PyObjectRef>()
197+
}
198+
194199
fn reverse(self, _vm: &VirtualMachine) {
195200
self.elements.borrow_mut().reverse();
196201
}
@@ -879,6 +884,7 @@ pub fn init(context: &PyContext) {
879884
The argument must be an iterable if specified.";
880885

881886
extend_class!(context, list_type, {
887+
"__sizeof__" => context.new_rustfunc(PyListRef::sizeof),
882888
"__add__" => context.new_rustfunc(PyListRef::add),
883889
"__iadd__" => context.new_rustfunc(PyListRef::iadd),
884890
"__bool__" => context.new_rustfunc(PyListRef::bool),

vm/src/obj/objset.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ impl PySetInner {
9191
self.content.len()
9292
}
9393

94+
fn sizeof(&self) -> usize {
95+
self.content.sizeof()
96+
}
97+
9498
fn copy(&self) -> PySetInner {
9599
PySetInner {
96100
content: self.content.clone(),
@@ -343,6 +347,11 @@ impl PySet {
343347
self.inner.borrow().len()
344348
}
345349

350+
#[pymethod(name = "__sizeof__")]
351+
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
352+
std::mem::size_of::<Self>() + self.inner.borrow().sizeof()
353+
}
354+
346355
#[pymethod]
347356
fn copy(&self, _vm: &VirtualMachine) -> Self {
348357
Self {
@@ -594,6 +603,11 @@ impl PyFrozenSet {
594603
self.inner.len()
595604
}
596605

606+
#[pymethod(name = "__sizeof__")]
607+
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
608+
std::mem::size_of::<Self>() + self.inner.sizeof()
609+
}
610+
597611
#[pymethod]
598612
fn copy(&self, _vm: &VirtualMachine) -> Self {
599613
Self {

vm/src/obj/objstr.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extern crate unicode_xid;
44
use std::cell::Cell;
55
use std::char;
66
use std::fmt;
7+
use std::mem::size_of;
78
use std::ops::Range;
89
use std::str::FromStr;
910
use std::string::ToString;
@@ -285,6 +286,11 @@ impl PyString {
285286
self.value.chars().count()
286287
}
287288

289+
#[pymethod(name = "__sizeof__")]
290+
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
291+
size_of::<Self>() + self.value.capacity() * size_of::<u8>()
292+
}
293+
288294
#[pymethod(name = "__mul__")]
289295
fn mul(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
290296
if !objtype::isinstance(&val, &vm.ctx.int_type()) {

0 commit comments

Comments
 (0)