r63761 - in python/branches/okkoto-sizeof: Lib/test/test_sys.py Objects/typeobject.c Python/sysmodule.c
Author: robert.schuppenies Date: Wed May 28 17:52:55 2008 New Revision: 63761 Log: going for the less-than-ideal solution: special case handling in sys.getsizeof() and type.__sizeof__() as CLASS_METH Modified: python/branches/okkoto-sizeof/Lib/test/test_sys.py python/branches/okkoto-sizeof/Objects/typeobject.c python/branches/okkoto-sizeof/Python/sysmodule.c Modified: python/branches/okkoto-sizeof/Lib/test/test_sys.py ============================================================================== --- python/branches/okkoto-sizeof/Lib/test/test_sys.py (original) +++ python/branches/okkoto-sizeof/Lib/test/test_sys.py Wed May 28 17:52:55 2008 @@ -406,12 +406,9 @@ def check_sizeof(self, o, size, ): size += self.headersize - if not inspect.isclass(o): - result = sys.getsizeof(o) - else: - result = o.__sizeof__(o) - msg = 'wrong size for ' + str(type(o)) + ': '+\ - str(result) + ' != ' + str(size) + result = sys.getsizeof(o) + msg = 'wrong size for ' + str(type(o)) + ': got '+\ + str(result) + ', expected ' + str(size) self.assertEqual(result, size, msg) def align(self, value): @@ -448,15 +445,15 @@ return x return inner self.check_sizeof(get_cell().func_closure[0], p) - # class - class clazz(): + # old-style class + class class_oldstyle(): def method(): pass - # self.check_sizeof(clazz, 6*p) + self.check_sizeof(class_oldstyle, 6*p) # instance -# self.check_sizeof(clazz(), 3*p) + self.check_sizeof(class_oldstyle(), 3*p) # method - self.check_sizeof(clazz().method, 4*p) + self.check_sizeof(class_oldstyle().method, 4*p) # code self.check_sizeof(get_cell().func_code, self.align(4*i) + 8*p +\ self.align(i) + 2*p) @@ -504,6 +501,15 @@ l = self.l p = self.p self.headersize += l + # new-style class + class class_newstyle(object): + def method(): + pass + # type (PyTypeObject + PyNumberMethods + PyMappingMethods + + # PySequenceMethods + PyBufferProcs) + len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p + self.check_sizeof(class_newstyle, \ + len_typeobject + 42*p + 10*p + 3*p + 6*p) # string self.check_sizeof('', l + self.align(i + 1)) self.check_sizeof('abc', l + self.align(i + 1) + 3) Modified: python/branches/okkoto-sizeof/Objects/typeobject.c ============================================================================== --- python/branches/okkoto-sizeof/Objects/typeobject.c (original) +++ python/branches/okkoto-sizeof/Objects/typeobject.c Wed May 28 17:52:55 2008 @@ -2620,7 +2620,7 @@ PyDoc_STR("mro() -> list\nreturn a type's method resolution order")}, {"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS, PyDoc_STR("__subclasses__() -> list of immediate subclasses")}, - {"__sizeof__", type_sizeof, METH_NOARGS, + {"__sizeof__", type_sizeof, METH_NOARGS | METH_CLASS, PyDoc_STR("default sizeof implementation for type")}, {0} }; Modified: python/branches/okkoto-sizeof/Python/sysmodule.c ============================================================================== --- python/branches/okkoto-sizeof/Python/sysmodule.c (original) +++ python/branches/okkoto-sizeof/Python/sysmodule.c Wed May 28 17:52:55 2008 @@ -642,7 +642,18 @@ static PyObject * sys_getsizeof(PyObject *self, PyObject *args) { - return PyObject_CallMethod(args, "__sizeof__", NULL); + /* work-around to deal with objects which inherit from type */ + if (args->ob_type == &PyType_Type) { + return PyObject_CallMethod((PyObject *)(args->ob_type), "__sizeof__", NULL); + } + else if (args->ob_type == &PyClass_Type) { + return PyInt_FromSsize_t(PyClass_Type.tp_basicsize); + } + else if (args->ob_type == &PyInstance_Type) { + return PyInt_FromSsize_t(PyInstance_Type.tp_basicsize); + } + else + return PyObject_CallMethod(args, "__sizeof__", NULL); } PyDoc_STRVAR(getsizeof_doc,
robert.schuppenies wrote:
Author: robert.schuppenies Date: Wed May 28 17:52:55 2008 New Revision: 63761
Log: going for the less-than-ideal solution: special case handling in sys.getsizeof() and type.__sizeof__() as CLASS_METH
What you're encountering here is known as 'metaclass confusion' - you *always* want to run the __sizeof__ implementation from the object's actual type, but the normal attribute lookup process doesn't work that way for instances of type. The way to avoid this confusion is to invoke type(obj).__sizeof__(obj) rather than attempting to invoke obj.__sizeof__() directly. I'd suggest seeing how you go with changing __sizeof__ back to a normal method and implementing the C equivalent of type(obj).__sizeof__(obj) to actually make the method call in sys_getsizeof (see PyObject_Format in Objects/abstract.c for an example of how to do this). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Nick Coghlan wrote:
The way to avoid this confusion is to invoke type(obj).__sizeof__(obj) rather than attempting to invoke obj.__sizeof__() directly.
I'd suggest seeing how you go with changing __sizeof__ back to a normal method and implementing the C equivalent of type(obj).__sizeof__(obj) to actually make the method call in sys_getsizeof (see PyObject_Format in Objects/abstract.c for an example of how to do this).
Works like a charm, thanks for the hint. Also for pointing me to this list, I wasn't aware that somebody is watching my moves. I'll try to adapt my submit policy to this fact. thanks, robert
Robert Schuppenies schrieb:
Nick Coghlan wrote:
The way to avoid this confusion is to invoke type(obj).__sizeof__(obj) rather than attempting to invoke obj.__sizeof__() directly.
I'd suggest seeing how you go with changing __sizeof__ back to a normal method and implementing the C equivalent of type(obj).__sizeof__(obj) to actually make the method call in sys_getsizeof (see PyObject_Format in Objects/abstract.c for an example of how to do this).
Works like a charm, thanks for the hint.
And I'd like to apologize for the wrong hints I gave you, I should have thought better about it before.
Also for pointing me to this list, I wasn't aware that somebody is watching my moves. I'll try to adapt my submit policy to this fact.
It's like builtin code review. Great, isn't it? :) Georg
Georg Brandl wrote:
Robert Schuppenies schrieb:
Also for pointing me to this list, I wasn't aware that somebody is watching my moves. I'll try to adapt my submit policy to this fact.
It's like builtin code review. Great, isn't it? :)
I'm not writing much actual code at the moment, so I nitpick on checkins to try to make up for it ;) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
participants (4)
-
Georg Brandl -
Nick Coghlan -
Robert Schuppenies -
robert.schuppenies