diff --git a/Include/methodobject.h b/Include/methodobject.h index cd1d2655640..81e84ceae4d 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -43,8 +43,6 @@ struct PyMethodDef { }; typedef struct PyMethodDef PyMethodDef; -PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, const char *); - #define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, PyObject *); @@ -70,14 +68,6 @@ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, #define METH_COEXIST 0x0040 -typedef struct PyMethodChain { - PyMethodDef *methods; /* Methods of this type */ - struct PyMethodChain *link; /* NULL or base type */ -} PyMethodChain; - -PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *, - const char *); - typedef struct { PyObject_HEAD PyMethodDef *m_ml; /* Description of the C function to call */ diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 099df7b7150..da223c4ee09 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1297,15 +1297,13 @@ static PyMethodDef element_methods[] = { }; static PyObject* -element_getattr(ElementObject* self, char* name) +element_getattro(ElementObject* self, PyObject* nameobj) { PyObject* res; + char *name = ""; - res = Py_FindMethod(element_methods, (PyObject*) self, name); - if (res) - return res; - - PyErr_Clear(); + if (PyUnicode_Check(nameobj)) + name = PyUnicode_AsString(nameobj); if (strcmp(name, "tag") == 0) res = self->tag; @@ -1318,14 +1316,10 @@ element_getattr(ElementObject* self, char* name) element_new_extra(self, NULL); res = element_get_attrib(self); } else { - PyErr_SetString(PyExc_AttributeError, name); - return NULL; + return PyObject_GenericGetAttr((PyObject*) self, nameobj); } - if (!res) - return NULL; - - Py_INCREF(res); + Py_XINCREF(res); return res; } @@ -1382,12 +1376,29 @@ static PyTypeObject Element_Type = { /* methods */ (destructor)element_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)element_getattr, /* tp_getattr */ + 0, /* tp_getattr */ (setattrfunc)element_setattr, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)element_repr, /* tp_repr */ 0, /* tp_as_number */ &element_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + (getattrofunc)element_getattro, /* 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 */ + element_methods, /* tp_methods */ + 0, /* tp_members */ }; /* ==================================================================== */ @@ -1783,19 +1794,35 @@ static PyMethodDef treebuilder_methods[] = { {NULL, NULL} }; -static PyObject* -treebuilder_getattr(TreeBuilderObject* self, char* name) -{ - return Py_FindMethod(treebuilder_methods, (PyObject*) self, name); -} - static PyTypeObject TreeBuilder_Type = { PyVarObject_HEAD_INIT(NULL, 0) "TreeBuilder", sizeof(TreeBuilderObject), 0, /* methods */ (destructor)treebuilder_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)treebuilder_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 */ + treebuilder_methods, /* tp_methods */ + 0, /* tp_members */ }; /* ==================================================================== */ @@ -2496,13 +2523,13 @@ static PyMethodDef xmlparser_methods[] = { }; static PyObject* -xmlparser_getattr(XMLParserObject* self, char* name) +xmlparser_getattro(XMLParserObject* self, PyObject* nameobj) { PyObject* res; + char *name = ""; - res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name); - if (res) - return res; + if (PyUnicode_Check(nameobj)) + name = PyUnicode_AsString(nameobj); PyErr_Clear(); @@ -2516,8 +2543,7 @@ xmlparser_getattr(XMLParserObject* self, char* name) XML_MINOR_VERSION, XML_MICRO_VERSION); return PyBytes_FromString(buffer); } else { - PyErr_SetString(PyExc_AttributeError, name); - return NULL; + return PyObject_GenericGetAttr((PyObject*) self, nameobj); } Py_INCREF(res); @@ -2530,7 +2556,29 @@ static PyTypeObject XMLParser_Type = { /* methods */ (destructor)xmlparser_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc)xmlparser_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 */ + (getattrofunc)xmlparser_getattro, /* 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 */ + xmlparser_methods, /* tp_methods */ + 0, /* tp_members */ }; #endif @@ -2572,10 +2620,14 @@ PyInit__elementtree(void) struct PyExpat_CAPI* capi; #endif - /* Patch object type */ - Py_TYPE(&Element_Type) = Py_TYPE(&TreeBuilder_Type) = &PyType_Type; + /* Initialize object types */ + if (PyType_Ready(&TreeBuilder_Type) < 0) + return NULL; + if (PyType_Ready(&Element_Type) < 0) + return NULL; #if defined(USE_EXPAT) - Py_TYPE(&XMLParser_Type) = &PyType_Type; + if (PyType_Ready(&XMLParser_Type) < 0) + return NULL; #endif m = PyModule_Create(&_elementtreemodule); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 92fc753659b..e85f3924c70 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1135,6 +1135,8 @@ xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) } #endif +static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs); + static struct PyMethodDef xmlparse_methods[] = { {"Parse", (PyCFunction)xmlparse_Parse, METH_VARARGS, xmlparse_Parse__doc__}, @@ -1154,6 +1156,7 @@ static struct PyMethodDef xmlparse_methods[] = { {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD, METH_VARARGS, xmlparse_UseForeignDTD__doc__}, #endif + {"__dir__", xmlparse_dir, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; @@ -1329,9 +1332,15 @@ get_pybool(int istrue) } static PyObject * -xmlparse_getattr(xmlparseobject *self, char *name) +xmlparse_getattro(xmlparseobject *self, PyObject *nameobj) { - int handlernum = handlername2int(name); + char *name = ""; + int handlernum = -1; + + if (PyUnicode_Check(nameobj)) + name = PyUnicode_AsString(nameobj); + + handlernum = handlername2int(name); if (handlernum != -1) { PyObject *result = self->handlers[handlernum]; @@ -1390,7 +1399,7 @@ xmlparse_getattr(xmlparseobject *self, char *name) } } - return Py_FindMethod(xmlparse_methods, (PyObject *)self, name); + return PyObject_GenericGetAttr((PyObject*)self, nameobj); } static PyObject * @@ -1603,11 +1612,6 @@ xmlparse_clear(xmlparseobject *op) PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser"); -static PyMethodDef xmlparse_tp_methods[] = { - {"__dir__", xmlparse_dir, METH_NOARGS}, - {NULL, NULL} /* sentinel */ -}; - static PyTypeObject Xmlparsetype = { PyVarObject_HEAD_INIT(NULL, 0) "pyexpat.xmlparser", /*tp_name*/ @@ -1616,7 +1620,7 @@ static PyTypeObject Xmlparsetype = { /* methods */ (destructor)xmlparse_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ - (getattrfunc)xmlparse_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ (setattrfunc)xmlparse_setattr, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ @@ -1626,7 +1630,7 @@ static PyTypeObject Xmlparsetype = { (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ - 0, /* tp_getattro */ + (getattrofunc)xmlparse_getattro, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef Py_TPFLAGS_HAVE_GC @@ -1641,7 +1645,7 @@ static PyTypeObject Xmlparsetype = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - xmlparse_tp_methods /* tp_methods */ + xmlparse_methods, /* tp_methods */ }; /* End of code for xmlparser objects */ @@ -1794,7 +1798,8 @@ MODULE_INITFUNC(void) if (modelmod_name == NULL) return NULL; - Py_TYPE(&Xmlparsetype) = &PyType_Type; + if (PyType_Ready(&Xmlparsetype) < 0) + return NULL; /* Create the module and add the functions */ m = PyModule_Create(&pyexpatmodule); diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 3d208c16736..cb6f1ba86ac 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -280,43 +280,6 @@ PyTypeObject PyCFunction_Type = { 0, /* tp_dict */ }; -/* Find a method in a method chain */ - -PyObject * -Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name) -{ - if (name[0] == '_' && name[1] == '_') { - if (strcmp(name, "__doc__") == 0) { - const char *doc = self->ob_type->tp_doc; - if (doc != NULL) - return PyUnicode_FromString(doc); - } - } - while (chain != NULL) { - PyMethodDef *ml = chain->methods; - for (; ml->ml_name != NULL; ml++) { - if (name[0] == ml->ml_name[0] && - strcmp(name+1, ml->ml_name+1) == 0) - /* XXX */ - return PyCFunction_New(ml, self); - } - chain = chain->link; - } - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -/* Find a method in a single method list */ - -PyObject * -Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name) -{ - PyMethodChain chain; - chain.methods = methods; - chain.link = NULL; - return Py_FindMethodInChain(&chain, self, name); -} - /* Clear out the free list */ int