Rev 161: Merge __sizeof__ changes. in http://bazaar.launchpad.net/~jameinel/meliae/mem-object-collection
John Arbash Meinel
john at arbash-meinel.com
Wed Dec 30 16:30:27 GMT 2009
At http://bazaar.launchpad.net/~jameinel/meliae/mem-object-collection
------------------------------------------------------------
revno: 161 [merge]
revision-id: john at arbash-meinel.com-20091230163000-on1qyna8ersp2aqm
parent: john at arbash-meinel.com-20091229230145-21afbw9bgd75e08m
parent: john at arbash-meinel.com-20091230162703-zkngtx5395r3vz6h
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: mem-object-collection
timestamp: Wed 2009-12-30 10:30:00 -0600
message:
Merge __sizeof__ changes.
modified:
meliae/_scanner.pyx _scanner.pyx-20090401185718-094vrprmymne09r1-2
meliae/_scanner_core.c _scanner_core.c-20090402012435-66bb6fp08v4begco-1
meliae/_scanner_core.h _scanner_core.h-20090402012435-66bb6fp08v4begco-2
meliae/tests/test__scanner.py test__scanner.py-20090401185718-094vrprmymne09r1-3
-------------- next part --------------
=== modified file 'meliae/_scanner.pyx'
--- a/meliae/_scanner.pyx 2009-10-07 21:39:53 +0000
+++ b/meliae/_scanner.pyx 2009-12-30 16:25:15 +0000
@@ -1,14 +1,14 @@
# Copyright (C) 2009 Canonical Ltd
-#
+#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
-#
+#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
=== modified file 'meliae/_scanner_core.c'
--- a/meliae/_scanner_core.c 2009-10-18 18:35:04 +0000
+++ b/meliae/_scanner_core.c 2009-12-30 16:25:15 +0000
@@ -1,14 +1,14 @@
/* Copyright (C) 2009 Canonical Ltd
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -99,6 +99,40 @@
+ num_entries * c_obj->ob_type->tp_itemsize;
}
+Py_ssize_t
+_size_of_from__sizeof__(PyObject *c_obj)
+{
+ PyObject *size_obj = NULL;
+ Py_ssize_t size = -1;
+
+ if (PyType_CheckExact(c_obj)) {
+ // Types themselves may have a __sizeof__ attribute, but it is the
+ // unbound method, which takes an instance
+ return -1;
+ }
+ size_obj = PyObject_CallMethod(c_obj, "__sizeof__", NULL);
+ if (size_obj == NULL) {
+ // Not sure what happened, but this won't work, it could be a simple
+ // attribute error, or it could be something else.
+ PyErr_Clear();
+ return -1;
+ }
+ size = PyInt_AsSsize_t(size_obj);
+ if (size == -1) {
+ // Probably an error occurred, we don't know for sure, but we might as
+ // well just claim that we don't know the size. We *could* check
+ // PyErr_Occurred(), but if we are just clearing it anyway...
+ PyErr_Clear();
+ return -1;
+ }
+ // There is one trick left. Namely, __sizeof__ doesn't seem to include the
+ // GC overhead, so let's add that back in
+ if (PyType_HasFeature(c_obj->ob_type, Py_TPFLAGS_HAVE_GC)) {
+ size += sizeof(PyGC_Head);
+ }
+ return size;
+}
+
Py_ssize_t
_size_of_list(PyListObject *c_obj)
@@ -147,6 +181,8 @@
Py_ssize_t
_size_of(PyObject *c_obj)
{
+ Py_ssize_t size;
+
if PyList_Check(c_obj) {
return _size_of_list((PyListObject *)c_obj);
} else if PyAnySet_Check(c_obj) {
@@ -157,6 +193,11 @@
return _size_of_unicode((PyUnicodeObject *)c_obj);
}
+ size = _size_of_from__sizeof__(c_obj);
+ if (size != -1) {
+ return size;
+ }
+
if (c_obj->ob_type->tp_itemsize != 0) {
// Variable length object with inline storage
// total size is tp_itemsize * ob_size
=== modified file 'meliae/_scanner_core.h'
--- a/meliae/_scanner_core.h 2009-10-07 21:39:53 +0000
+++ b/meliae/_scanner_core.h 2009-12-30 16:25:15 +0000
@@ -1,15 +1,15 @@
/* Copyright (C) 2009 Canonical Ltd
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
=== modified file 'meliae/tests/test__scanner.py'
--- a/meliae/tests/test__scanner.py 2009-10-18 18:35:04 +0000
+++ b/meliae/tests/test__scanner.py 2009-12-30 16:25:15 +0000
@@ -154,6 +154,19 @@
def test_None(self):
self.assertSizeOf(2, None, has_gc=False)
+ def test__sizeof__instance(self):
+ # __sizeof__ appears to have been introduced in python 2.6, and
+ # is meant to return the number of bytes allocated to this
+ # object. It does not include GC overhead, that seems to be added back
+ # in as part of sys.getsizeof(). So meliae does the same in size_of()
+ class CustomSize(object):
+ def __init__(self, size):
+ self.size = size
+ def __sizeof__(self):
+ return self.size
+ self.assertSizeOf(0, CustomSize(10), 10, has_gc=True)
+ self.assertSizeOf(0, CustomSize(20), 20, has_gc=True)
+
def _string_to_json(s):
out = ['"']
More information about the bazaar-commits
mailing list