From e43d33a4db0c0c9afcb70a26f682abfe889e845b Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Wed, 2 Jul 2008 20:50:16 +0000 Subject: [PATCH] #3247 Get rid of Py_FindMethod; use tp_members instead. Otherwise dir(_sre.SRE_Match) returns an empty list. First step: handle most occurrences, remove tp_getattr and fill the tp_methods and tp_members slots. Add some test about attribute access. --- Lib/test/test_re.py | 7 ++ Lib/test/test_winreg.py | 1 + Lib/test/test_zlib.py | 2 + Modules/_bsddb.c | 111 +++++++++--------- Modules/_sre.c | 241 ++++++++++++++++++++-------------------- Modules/_ssl.c | 24 ++-- Modules/_threadmodule.c | 26 +++-- Modules/_tkinter.c | 50 ++++++--- Modules/parsermodule.c | 62 ++++++----- Modules/selectmodule.c | 25 +++-- Modules/zlibmodule.c | 77 +++++++------ PC/_subprocess.c | 27 +++-- PC/winreg.c | 64 +++++------ 13 files changed, 388 insertions(+), 329 deletions(-) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 0b023c2fb79..fd41b6e5f4a 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -326,6 +326,13 @@ class ReTests(unittest.TestCase): self.assertNotEqual(re.match("^x{}$", "x{}"), None) def test_getattr(self): + self.assertEqual(re.compile("(?i)(a)(b)").pattern, "(?i)(a)(b)") + self.assertEqual(re.compile("(?i)(a)(b)").flags, re.I) + self.assertEqual(re.compile("(?i)(a)(b)").groups, 2) + self.assertEqual(re.compile("(?i)(a)(b)").groupindex, {}) + self.assertEqual(re.compile("(?i)(?Pa)(?Pb)").groupindex, + {'first': 1, 'other': 2}) + self.assertEqual(re.match("(a)", "a").pos, 0) self.assertEqual(re.match("(a)", "a").endpos, 1) self.assertEqual(re.match("(a)", "a").string, "a") diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 3dbabc591f4..b4ca5827c22 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -29,6 +29,7 @@ class WinregTests(unittest.TestCase): # Set the default value for this key. SetValue(root_key, test_key_name, REG_SZ, "Default value") key = CreateKey(root_key, test_key_name) + self.assert_(key.handle != 0) # Create a sub-key sub_key = CreateKey(key, subkeystr) # Give the sub-key some named values diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 485ffdc2fb3..b5f3fe50281 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -161,6 +161,7 @@ class CompressObjectTestCase(unittest.TestCase): self.assertEqual(b'', dco.unconsumed_tail, ######## "(A) uct should be b'': not %d long" % len(dco.unconsumed_tail)) + self.assertEqual(b'', dco.unused_data) if flush: bufs.append(dco.flush()) else: @@ -173,6 +174,7 @@ class CompressObjectTestCase(unittest.TestCase): self.assertEqual(b'', dco.unconsumed_tail, ######## "(B) uct should be b'': not %d long" % len(dco.unconsumed_tail)) + self.assertEqual(b'', dco.unused_data) self.assertEqual(data, b''.join(bufs)) # Failure means: "decompressobj with init options failed" diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index 6b543fd1d66..648fb0da99f 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -5324,54 +5324,21 @@ static PyMethodDef DBSequence_methods[] = { }; #endif - static PyObject* -DB_getattr(DBObject* self, char *name) +DBEnv_db_home_get(DBEnvObject* self) { - return Py_FindMethod(DB_methods, (PyObject* )self, name); -} - - -static PyObject* -DBEnv_getattr(DBEnvObject* self, char *name) -{ - if (!strcmp(name, "db_home")) { - CHECK_ENV_NOT_CLOSED(self); - if (self->db_env->db_home == NULL) { - RETURN_NONE(); - } - return PyUnicode_FromString(self->db_env->db_home); + CHECK_ENV_NOT_CLOSED(self); + if (self->db_env->db_home == NULL) { + RETURN_NONE(); } - - return Py_FindMethod(DBEnv_methods, (PyObject* )self, name); + return PyUnicode_FromString(self->db_env->db_home); } +static PyGetSetDef DBEnv_getsets[] = { + {"db_home", (getter)DBEnv_db_home_get, NULL,}, + {NULL} +}; -static PyObject* -DBCursor_getattr(DBCursorObject* self, char *name) -{ - return Py_FindMethod(DBCursor_methods, (PyObject* )self, name); -} - -static PyObject* -DBTxn_getattr(DBTxnObject* self, char *name) -{ - return Py_FindMethod(DBTxn_methods, (PyObject* )self, name); -} - -static PyObject* -DBLock_getattr(DBLockObject* self, char *name) -{ - return NULL; -} - -#if (DBVER >= 43) -static PyObject* -DBSequence_getattr(DBSequenceObject* self, char *name) -{ - return Py_FindMethod(DBSequence_methods, (PyObject* )self, name); -} -#endif static PyTypeObject DB_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -5381,8 +5348,8 @@ static PyTypeObject DB_Type = { /* methods */ (destructor)DB_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DB_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ @@ -5400,6 +5367,9 @@ static PyTypeObject DB_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DB_methods, /* tp_methods */ }; @@ -5411,7 +5381,7 @@ static PyTypeObject DBCursor_Type = { /* methods */ (destructor)DBCursor_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DBCursor_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -5430,6 +5400,9 @@ static PyTypeObject DBCursor_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DBCursor_methods, /* tp_methods */ }; @@ -5441,7 +5414,7 @@ static PyTypeObject DBEnv_Type = { /* methods */ (destructor)DBEnv_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DBEnv_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -5460,6 +5433,11 @@ static PyTypeObject DBEnv_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DBEnv_methods, /* tp_methods */ + 0, /* tp_members */ + DBEnv_getsets, /* tp_getsets */ }; static PyTypeObject DBTxn_Type = { @@ -5470,8 +5448,8 @@ static PyTypeObject DBTxn_Type = { /* methods */ (destructor)DBTxn_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DBTxn_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ @@ -5489,6 +5467,9 @@ static PyTypeObject DBTxn_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DBTxn_methods, /* tp_methods */ }; @@ -5500,8 +5481,8 @@ static PyTypeObject DBLock_Type = { /* methods */ (destructor)DBLock_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DBLock_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ @@ -5530,7 +5511,7 @@ static PyTypeObject DBSequence_Type = { /* methods */ (destructor)DBSequence_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)DBSequence_getattr,/*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -5549,6 +5530,9 @@ static PyTypeObject DBSequence_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DBSequence_methods, /* tp_methods */ }; #endif @@ -5668,16 +5652,21 @@ PyMODINIT_FUNC PyInit__bsddb(void) PyObject* svnid_s = PyUnicode_FromString(svn_id); PyObject* py_api; - /* Initialize the type of the new type objects here; doing it here - is required for portability to Windows without requiring C++. */ - Py_TYPE(&DB_Type) = &PyType_Type; - Py_TYPE(&DBCursor_Type) = &PyType_Type; - Py_TYPE(&DBEnv_Type) = &PyType_Type; - Py_TYPE(&DBTxn_Type) = &PyType_Type; - Py_TYPE(&DBLock_Type) = &PyType_Type; -#if (DBVER >= 43) - Py_TYPE(&DBSequence_Type) = &PyType_Type; -#endif + /* Initialize object types */ + if (PyType_Ready(&DB_Type) < 0) + return NULL; + if (PyType_Ready(&DBCursor_Type) < 0) + return NULL; + if (PyType_Ready(&DBEnv_Type) < 0) + return NULL; + if (PyType_Ready(&DBTxn_Type) < 0) + return NULL; + if (PyType_Ready(&DBLock_Type) < 0) + return NULL; +#if (DBVER >= 43) + if (PyType_Ready(&DBSequence_Type) < 0) + return NULL; +#endif #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE) diff --git a/Modules/_sre.c b/Modules/_sre.c index ab8addacd50..a0e974a570a 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2597,46 +2597,22 @@ static PyMethodDef pattern_methods[] = { {NULL, NULL} }; -static PyObject* -pattern_getattr(PatternObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(pattern_methods, (PyObject*) self, name); - - if (res) - return res; - - PyErr_Clear(); - - /* attributes */ - if (!strcmp(name, "pattern")) { - Py_INCREF(self->pattern); - return self->pattern; - } - - if (!strcmp(name, "flags")) - return Py_BuildValue("i", self->flags); - - if (!strcmp(name, "groups")) - return Py_BuildValue("i", self->groups); - - if (!strcmp(name, "groupindex") && self->groupindex) { - Py_INCREF(self->groupindex); - return self->groupindex; - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} +#define PAT_OFF(x) offsetof(PatternObject, x) +static PyMemberDef pattern_members[] = { + {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY}, + {"flags", T_INT, PAT_OFF(flags), READONLY}, + {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, + {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY}, + {NULL} /* Sentinel */ +}; static PyTypeObject Pattern_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_" SRE_MODULE ".SRE_Pattern", sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)pattern_getattr, /*tp_getattr*/ + (destructor)pattern_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -2655,6 +2631,10 @@ static PyTypeObject Pattern_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pattern_methods, /* tp_methods */ + pattern_members, /* tp_members */ }; static PyObject * @@ -3098,70 +3078,56 @@ static PyMethodDef match_methods[] = { {NULL, NULL} }; -static PyObject* -match_getattr(MatchObject* self, char* name) +static PyObject * +match_lastindex_get(MatchObject *self) { - PyObject* res; - - res = Py_FindMethod(match_methods, (PyObject*) self, name); - if (res) - return res; - - PyErr_Clear(); - - if (!strcmp(name, "lastindex")) { - if (self->lastindex >= 0) - return Py_BuildValue("i", self->lastindex); - Py_INCREF(Py_None); - return Py_None; - } - - if (!strcmp(name, "lastgroup")) { - if (self->pattern->indexgroup && self->lastindex >= 0) { - PyObject* result = PySequence_GetItem( - self->pattern->indexgroup, self->lastindex - ); - if (result) - return result; - PyErr_Clear(); - } - Py_INCREF(Py_None); - return Py_None; - } - - if (!strcmp(name, "string")) { - if (self->string) { - Py_INCREF(self->string); - return self->string; - } else { - Py_INCREF(Py_None); - return Py_None; - } - } - - if (!strcmp(name, "regs")) { - if (self->regs) { - Py_INCREF(self->regs); - return self->regs; - } else - return match_regs(self); - } - - if (!strcmp(name, "re")) { - Py_INCREF(self->pattern); - return (PyObject*) self->pattern; - } - - if (!strcmp(name, "pos")) - return Py_BuildValue("i", self->pos); - - if (!strcmp(name, "endpos")) - return Py_BuildValue("i", self->endpos); - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; + if (self->lastindex >= 0) + return Py_BuildValue("i", self->lastindex); + Py_INCREF(Py_None); + return Py_None; } +static PyObject * +match_lastgroup_get(MatchObject *self) +{ + if (self->pattern->indexgroup && self->lastindex >= 0) { + PyObject* result = PySequence_GetItem( + self->pattern->indexgroup, self->lastindex + ); + if (result) + return result; + PyErr_Clear(); + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +match_regs_get(MatchObject *self) +{ + if (self->regs) { + Py_INCREF(self->regs); + return self->regs; + } else + return match_regs(self); +} + +static PyGetSetDef match_getset[] = { + {"lastindex", (getter)match_lastindex_get, (setter)NULL}, + {"lastgroup", (getter)match_lastgroup_get, (setter)NULL}, + {"regs", (getter)match_regs_get, (setter)NULL}, + {NULL} +}; + +#define MATCH_OFF(x) offsetof(MatchObject, x) +static PyMemberDef match_members[] = { + {"string", T_OBJECT, MATCH_OFF(string), READONLY}, + {"re", T_OBJECT, MATCH_OFF(pattern), READONLY}, + {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY}, + {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY}, + {NULL} +}; + /* FIXME: implement setattr("string", None) as a special case (to detach the associated string, if any */ @@ -3169,9 +3135,32 @@ static PyTypeObject Match_Type = { PyVarObject_HEAD_INIT(NULL,0) "_" SRE_MODULE ".SRE_Match", sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)match_getattr /*tp_getattr*/ + (destructor)match_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + match_methods, /* tp_methods */ + match_members, /* tp_members */ + match_getset, /* tp_getset */ }; static PyObject* @@ -3320,34 +3309,42 @@ static PyMethodDef scanner_methods[] = { {NULL, NULL} }; -static PyObject* -scanner_getattr(ScannerObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(scanner_methods, (PyObject*) self, name); - if (res) - return res; - - PyErr_Clear(); - - /* attributes */ - if (!strcmp(name, "pattern")) { - Py_INCREF(self->pattern); - return self->pattern; - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} +#define SCAN_OFF(x) offsetof(ScannerObject, x) +static PyMemberDef scanner_members[] = { + {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY}, + {NULL} /* Sentinel */ +}; static PyTypeObject Scanner_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_" SRE_MODULE ".SRE_Scanner", sizeof(ScannerObject), 0, - (destructor)scanner_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)scanner_getattr, /*tp_getattr*/ + (destructor)scanner_dealloc,/* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + scanner_methods, /* tp_methods */ + scanner_members, /* tp_members */ + 0, /* tp_getset */ }; static PyObject* diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f2e95b94ad5..25b82b44d60 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1384,11 +1384,6 @@ static PyMethodDef PySSLMethods[] = { {NULL, NULL} }; -static PyObject *PySSL_getattr(PySSLObject *self, char *name) -{ - return Py_FindMethod(PySSLMethods, (PyObject *)self, name); -} - static PyTypeObject PySSL_Type = { PyVarObject_HEAD_INIT(NULL, 0) "ssl.SSLContext", /*tp_name*/ @@ -1397,7 +1392,7 @@ static PyTypeObject PySSL_Type = { /* methods */ (destructor)PySSL_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)PySSL_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -1405,6 +1400,20 @@ static PyTypeObject PySSL_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PySSLMethods, /*tp_methods*/ }; #ifdef HAVE_OPENSSL_RAND @@ -1581,7 +1590,8 @@ PyInit__ssl(void) { PyObject *m, *d; - Py_TYPE(&PySSL_Type) = &PyType_Type; + if (PyType_Ready(&PySSL_Type) < 0) + return NULL; m = PyModule_Create(&_sslmodule); if (m == NULL) diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index d2299aa4fb2..f0d03d74362 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -119,12 +119,6 @@ static PyMethodDef lock_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyObject * -lock_getattr(lockobject *self, char *name) -{ - return Py_FindMethod(lock_methods, (PyObject *)self, name); -} - static PyTypeObject Locktype = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "_thread.lock", /*tp_name*/ @@ -133,10 +127,28 @@ static PyTypeObject Locktype = { /* methods */ (destructor)lock_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)lock_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + lock_methods, /*tp_methods*/ }; static lockobject * diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index cb0ab422802..4e36daccd3d 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -2327,12 +2327,6 @@ Tktt_Repr(PyObject *self) return PyUnicode_FromString(buf); } -static PyObject * -Tktt_GetAttr(PyObject *self, char *name) -{ - return Py_FindMethod(Tktt_methods, self, name); -} - static PyTypeObject Tktt_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -2341,7 +2335,7 @@ static PyTypeObject Tktt_Type = 0, /*tp_itemsize */ Tktt_Dealloc, /*tp_dealloc */ 0, /*tp_print */ - Tktt_GetAttr, /*tp_getattr */ + 0, /*tp_getattr */ 0, /*tp_setattr */ 0, /*tp_compare */ Tktt_Repr, /*tp_repr */ @@ -2349,6 +2343,20 @@ static PyTypeObject Tktt_Type = 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Tktt_methods, /*tp_methods*/ }; @@ -2671,12 +2679,6 @@ Tkapp_Dealloc(PyObject *self) DisableEventHook(); } -static PyObject * -Tkapp_GetAttr(PyObject *self, char *name) -{ - return Py_FindMethod(Tkapp_methods, self, name); -} - static PyTypeObject Tkapp_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -2685,7 +2687,7 @@ static PyTypeObject Tkapp_Type = 0, /*tp_itemsize */ Tkapp_Dealloc, /*tp_dealloc */ 0, /*tp_print */ - Tkapp_GetAttr, /*tp_getattr */ + 0, /*tp_getattr */ 0, /*tp_setattr */ 0, /*tp_compare */ 0, /*tp_repr */ @@ -2693,6 +2695,20 @@ static PyTypeObject Tkapp_Type = 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Tkapp_methods, /*tp_methods*/ }; @@ -3026,7 +3042,8 @@ PyInit__tkinter(void) { PyObject *m, *d, *uexe, *cexe; - Py_TYPE(&Tkapp_Type) = &PyType_Type; + if (PyType_Ready(&Tkapp_Type) < 0) + return NULL; #ifdef WITH_THREAD tcl_lock = PyThread_allocate_lock(); @@ -3054,7 +3071,8 @@ PyInit__tkinter(void) PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type); - Py_TYPE(&Tktt_Type) = &PyType_Type; + if (PyType_Ready(&Tktt_Type) < 0) + return NULL; PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type); Py_TYPE(&PyTclObject_Type) = &PyType_Type; diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index cd7a3b2d5da..ab41aaf4a47 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -161,8 +161,28 @@ typedef struct { static void parser_free(PyST_Object *st); static int parser_compare(PyST_Object *left, PyST_Object *right); -static PyObject *parser_getattr(PyObject *self, char *name); +static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *); +#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) + +static PyMethodDef parser_methods[] = { + {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE, + PyDoc_STR("Compile this ST object into a code object.")}, + {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE, + PyDoc_STR("Determines if this ST object was created from an expression.")}, + {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE, + PyDoc_STR("Determines if this ST object was created from a suite.")}, + {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE, + PyDoc_STR("Creates a list-tree representation of this ST.")}, + {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE, + PyDoc_STR("Creates a tuple-tree representation of this ST.")}, + + {NULL, NULL, 0, NULL} +}; static PyTypeObject PyST_Type = { @@ -172,7 +192,7 @@ PyTypeObject PyST_Type = { 0, /* tp_itemsize */ (destructor)parser_free, /* tp_dealloc */ 0, /* tp_print */ - parser_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)parser_compare, /* tp_compare */ 0, /* tp_repr */ @@ -191,7 +211,14 @@ PyTypeObject PyST_Type = { Py_TPFLAGS_DEFAULT, /* tp_flags */ /* __doc__ */ - "Intermediate representation of a Python parse tree." + "Intermediate representation of a Python parse tree.", + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + parser_methods, /* tp_methods */ }; /* PyST_Type */ @@ -450,32 +477,6 @@ parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) } -#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) - -static PyMethodDef -parser_methods[] = { - {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE, - PyDoc_STR("Compile this ST object into a code object.")}, - {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from an expression.")}, - {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from a suite.")}, - {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a list-tree representation of this ST.")}, - {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a tuple-tree representation of this ST.")}, - - {NULL, NULL, 0, NULL} -}; - - -static PyObject* -parser_getattr(PyObject *self, char *name) -{ - return (Py_FindMethod(parser_methods, self, name)); -} - - /* err_string(char* message) * * Sets the error string for an exception of type ParserError. @@ -3067,7 +3068,8 @@ PyInit_parser(void) { PyObject *module, *copyreg; - Py_TYPE(&PyST_Type) = &PyType_Type; + if (PyType_Ready(&PyST_Type) < 0) + return NULL; module = PyModule_Create(&parsermodule); if (module == NULL) return NULL; diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index f1c71e43dfb..daabf03ac23 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -625,12 +625,6 @@ poll_dealloc(pollObject *self) PyObject_Del(self); } -static PyObject * -poll_getattr(pollObject *self, char *name) -{ - return Py_FindMethod(poll_methods, (PyObject *)self, name); -} - static PyTypeObject poll_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ @@ -641,7 +635,7 @@ static PyTypeObject poll_Type = { /* methods */ (destructor)poll_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)poll_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -649,6 +643,20 @@ static PyTypeObject poll_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + poll_methods, /*tp_methods*/ }; PyDoc_STRVAR(poll_doc, @@ -1764,7 +1772,8 @@ PyInit_select(void) #else { #endif - Py_TYPE(&poll_Type) = &PyType_Type; + if (PyType_Ready(&poll_Type) < 0) + return NULL; PyModule_AddIntConstant(m, "POLLIN", POLLIN); PyModule_AddIntConstant(m, "POLLPRI", POLLPRI); PyModule_AddIntConstant(m, "POLLOUT", POLLOUT); diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index e63063fdcfd..b6f324bfcce 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -5,6 +5,7 @@ #include "Python.h" +#include "structmember.h" #include "zlib.h" #ifdef WITH_THREAD @@ -879,35 +880,12 @@ static PyMethodDef Decomp_methods[] = {NULL, NULL} }; -static PyObject * -Comp_getattr(compobject *self, char *name) -{ - /* No ENTER/LEAVE_ZLIB is necessary because this fn doesn't touch - internal data. */ - - return Py_FindMethod(comp_methods, (PyObject *)self, name); -} - -static PyObject * -Decomp_getattr(compobject *self, char *name) -{ - PyObject * retval; - - ENTER_ZLIB - - if (strcmp(name, "unused_data") == 0) { - Py_INCREF(self->unused_data); - retval = self->unused_data; - } else if (strcmp(name, "unconsumed_tail") == 0) { - Py_INCREF(self->unconsumed_tail); - retval = self->unconsumed_tail; - } else - retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name); - - LEAVE_ZLIB - - return retval; -} +#define COMP_OFF(x) offsetof(compobject, x) +static PyMemberDef Decomp_members[] = { + {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, + {"unconsumed_tail", T_OBJECT, COMP_OFF(unconsumed_tail), READONLY}, + {NULL}, +}; PyDoc_STRVAR(adler32__doc__, "adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n" @@ -972,13 +950,28 @@ static PyTypeObject Comptype = { 0, (destructor)Comp_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)Comp_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + comp_methods, /*tp_methods*/ }; static PyTypeObject Decomptype = { @@ -988,13 +981,29 @@ static PyTypeObject Decomptype = { 0, (destructor)Decomp_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)Decomp_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Decomp_methods, /*tp_methods*/ + Decomp_members, /*tp_members*/ }; PyDoc_STRVAR(zlib_module_documentation, @@ -1028,8 +1037,10 @@ PyMODINIT_FUNC PyInit_zlib(void) { PyObject *m, *ver; - Py_TYPE(&Comptype) = &PyType_Type; - Py_TYPE(&Decomptype) = &PyType_Type; + if (PyType_Ready(&Comptype) < 0) + return NULL; + if (PyType_Ready(&Decomptype) < 0) + return NULL; m = PyModule_Create(&zlibmodule); if (m == NULL) return NULL; diff --git a/PC/_subprocess.c b/PC/_subprocess.c index c256ca35d89..77a8a85e47e 100644 --- a/PC/_subprocess.c +++ b/PC/_subprocess.c @@ -110,12 +110,6 @@ static PyMethodDef sp_handle_methods[] = { {NULL, NULL} }; -static PyObject* -sp_handle_getattr(sp_handle_object* self, char* name) -{ - return Py_FindMethod(sp_handle_methods, (PyObject*) self, name); -} - static PyObject* sp_handle_as_int(sp_handle_object* self) { @@ -129,14 +123,28 @@ static PyTypeObject sp_handle_type = { "_subprocess_handle", sizeof(sp_handle_object), 0, (destructor) sp_handle_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc) sp_handle_getattr,/*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ &sp_handle_as_number, /*tp_as_number */ 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ - 0 /*tp_hash*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + sp_handle_methods, /*tp_methods*/ }; /* -------------------------------------------------------------------- */ @@ -560,8 +568,9 @@ PyInit__subprocess() PyObject *m; /* patch up object descriptors */ - Py_TYPE(&sp_handle_type) = &PyType_Type; sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int; + if (PyType_Ready(&sp_handle_type) < 0) + return NULL; m = PyModule_Create(&_subprocessmodule); if (m == NULL) diff --git a/PC/winreg.c b/PC/winreg.c index 571209fdff5..e53a448e1d4 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -455,9 +455,24 @@ static PyNumberMethods PyHKEY_NumberMethods = PyHKEY_unaryFailureFunc, /* nb_float */ }; +static PyObject *PyHKEY_CloseMethod(PyObject *self, PyObject *args); +static PyObject *PyHKEY_DetachMethod(PyObject *self, PyObject *args); +static PyObject *PyHKEY_Enter(PyObject *self); +static PyObject *PyHKEY_Exit(PyObject *self, PyObject *args); -/* fwd declare __getattr__ */ -static PyObject *PyHKEY_getattr(PyObject *self, const char *name); +static struct PyMethodDef PyHKEY_methods[] = { + {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, + {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, + {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, + {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, + {NULL} +}; + +#define OFF(e) offsetof(PyHKEYObject, e) +static PyMemberDef PyHKEY_memberlist[] = { + {"handle", T_INT, OFF(hkey), READONLY}, + {NULL} /* Sentinel */ +}; /* The type itself */ PyTypeObject PyHKEY_Type = @@ -468,7 +483,7 @@ PyTypeObject PyHKEY_Type = 0, PyHKEY_deallocFunc, /* tp_dealloc */ 0, /* tp_print */ - PyHKEY_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ PyHKEY_compareFunc, /* tp_compare */ 0, /* tp_repr */ @@ -483,13 +498,14 @@ PyTypeObject PyHKEY_Type = 0, /* tp_as_buffer */ 0, /* tp_flags */ PyHKEY_doc, /* tp_doc */ -}; - -#define OFF(e) offsetof(PyHKEYObject, e) - -static PyMemberDef PyHKEY_memberlist[] = { - {"handle", T_INT, OFF(hkey), READONLY}, - {NULL} /* Sentinel */ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyHKEY_methods, /*tp_methods*/ + PyHKEY_memberlist, /*tp_members*/ }; /************************************************************************ @@ -536,31 +552,6 @@ PyHKEY_Exit(PyObject *self, PyObject *args) } -static struct PyMethodDef PyHKEY_methods[] = { - {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, - {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, - {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, - {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, - {NULL} -}; - -/*static*/ PyObject * -PyHKEY_getattr(PyObject *self, const char *name) -{ - PyObject *res; - - res = Py_FindMethod(PyHKEY_methods, self, name); - if (res != NULL) - return res; - PyErr_Clear(); - if (strcmp(name, "handle") == 0) - return PyLong_FromVoidPtr(((PyHKEYObject *)self)->hkey); - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", - Py_TYPE(self)->tp_name, name); - return NULL; -} - /************************************************************************ The public PyHKEY API (well, not public yet :-) ************************************************************************/ @@ -1582,8 +1573,9 @@ PyMODINIT_FUNC PyInit_winreg(void) if (m == NULL) return NULL; d = PyModule_GetDict(m); - Py_TYPE(&PyHKEY_Type) = &PyType_Type; PyHKEY_Type.tp_doc = PyHKEY_doc; + if (PyType_Ready(&PyHKEY_Type) < 0) + return NULL; Py_INCREF(&PyHKEY_Type); if (PyDict_SetItemString(d, "HKEYType", (PyObject *)&PyHKEY_Type) != 0)