Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (revision 64556) +++ Python/sysmodule.c (working copy) @@ -643,6 +643,7 @@ sys_getsizeof(PyObject *self, PyObject *args) { static PyObject * str__sizeof__ = NULL; + PyObject *res = NULL; /* Initialize static variable needed by _PyType_Lookup */ if (str__sizeof__ == NULL) { @@ -651,26 +652,25 @@ return NULL; } - /* Type objects */ - if (PyType_Check(args)){ - PyObject *method = _PyType_Lookup(Py_TYPE(args), - str__sizeof__); - if (method == NULL) { + /* Make sure the type is initialized. float gets initialized late */ + if (PyType_Ready(Py_TYPE(args)) < 0) + return NULL; + + /* non-type objects */ + if (!PyType_Check(args)) + res = PyObject_CallMethod(args, "__sizeof__", NULL); + /* type objects, and objects which do not have the __sizeof__ attribute */ + if (PyType_Check(args) || + (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))) { + PyObject *method = _PyType_Lookup(Py_TYPE(args), str__sizeof__); + if (method == NULL) PyErr_Format(PyExc_TypeError, "Type %.100s doesn't define __sizeof__", Py_TYPE(args)->tp_name); - return NULL; - } - return PyObject_CallFunctionObjArgs(method, args, NULL); - } - /* Instance of old-style classes */ - else if (PyInstance_Check(args)) - return PyInt_FromSsize_t(PyInstance_Type.tp_basicsize); - /* Old-style classes */ - else if (PyClass_Check(args)) - return PyInt_FromSsize_t(PyClass_Type.tp_basicsize); - else - return PyObject_CallMethod(args, "__sizeof__", NULL); + else + res = PyObject_CallFunctionObjArgs(method, args, NULL); + } + return res; } PyDoc_STRVAR(getsizeof_doc, Index: Lib/test/test_sys.py =================================================================== --- Lib/test/test_sys.py (revision 64556) +++ Lib/test/test_sys.py (working copy) @@ -559,7 +559,25 @@ self.check_sizeof((), size(h)) self.check_sizeof((1,2,3), size(h) + 3*self.P) + def test_moduleobjects(self): + # Some objects from built-in modules + h = self.header + size = self.calcsize + # _sre.PatternObject + import re + x = re.compile("") + self.check_sizeof(x, size(h + 'P PPP PiP PH')) + + # _sre.Match + x = re.match('','') + self.check_sizeof(x, 42) + + # _struct.Struct + x = struct.Struct("") + self.check_sizeof(x, size(h + 'PPPPP')) + + def test_main(): test_classes = (SysModuleTest, SizeofTest) Index: Modules/_sre.c =================================================================== --- Modules/_sre.c (revision 64556) +++ Modules/_sre.c (working copy) @@ -3083,6 +3083,11 @@ #endif } +static PyObject* +match_sizeof(MatchObject *self) { + return PyInt_FromSsize_t(42); +} + static PyMethodDef match_methods[] = { {"group", (PyCFunction) match_group, METH_VARARGS}, {"start", (PyCFunction) match_start, METH_VARARGS}, @@ -3093,6 +3098,7 @@ {"expand", (PyCFunction) match_expand, METH_O}, {"__copy__", (PyCFunction) match_copy, METH_NOARGS}, {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O}, + {"__sizeof__", (PyCFunction) match_sizeof, METH_NOARGS}, {NULL, NULL} };