From 166959db41e732d5df07cca76f95f60e8bc29fb3 Mon Sep 17 00:00:00 2001 From: Steve Shi Date: Wed, 1 Mar 2023 22:56:34 +0200 Subject: [PATCH] Fix sys.getsizeof (#4604) --- Lib/test/test_ioctl.py | 2 -- Lib/test/test_ordered_dict.py | 2 -- vm/src/stdlib/sys.rs | 23 ++++++++++++++++++----- vm/src/vm/context.rs | 1 + 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py index a25d7e0ef..40f37970f 100644 --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -66,8 +66,6 @@ class IoctlTests(unittest.TestCase): # Test with a larger buffer, just for the record. self._check_ioctl_mutate_len(2048) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_ioctl_signed_unsigned_code_param(self): if not pty: raise unittest.SkipTest('pty module required') diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index 70ecbc119..1d09387fb 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -437,8 +437,6 @@ class OrderedDictTests: od.move_to_end('c') self.assertEqual(list(od), list('bac')) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_sizeof(self): OrderedDict = self.OrderedDict # Wimpy test: Just verify the reported size is larger than a regular dict diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index 86d6f44fc..e202958b5 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -17,12 +17,12 @@ mod sys { types::PyStructSequence, version, vm::{Settings, VirtualMachine}, - AsObject, PyObjectRef, PyRef, PyRefExact, PyResult, + AsObject, PyObject, PyObjectRef, PyRef, PyRefExact, PyResult, }; use num_traits::ToPrimitive; use std::{ env::{self, VarError}, - mem, path, + path, sync::atomic::Ordering, }; @@ -419,10 +419,23 @@ mod sys { vm.recursion_limit.get() } + #[derive(FromArgs)] + struct GetsizeofArgs { + obj: PyObjectRef, + #[pyarg(any, optional)] + default: Option, + } + #[pyfunction] - fn getsizeof(obj: PyObjectRef) -> usize { - // TODO: implement default optional argument. - mem::size_of_val(&obj) + fn getsizeof(args: GetsizeofArgs, vm: &VirtualMachine) -> PyResult { + let sizeof = || -> PyResult { + let res = vm.call_special_method(args.obj, identifier!(vm, __sizeof__), ())?; + let res = res.try_index(vm)?.try_to_primitive::(vm)?; + Ok(res + std::mem::size_of::()) + }; + sizeof() + .map(|x| vm.ctx.new_int(x).into()) + .or_else(|err| args.default.ok_or(err)) } #[pyfunction] diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index 1f1850db3..9db628f76 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -202,6 +202,7 @@ declare_const_name! { __str__, __sub__, __subclasscheck__, + __sizeof__, __truediv__, __trunc__, __xor__,