]> granicus.if.org Git - python/commitdiff
#3247: Get rid of Py_FindMethod:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>
Wed, 2 Jul 2008 21:41:01 +0000 (21:41 +0000)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>
Wed, 2 Jul 2008 21:41:01 +0000 (21:41 +0000)
Second step: keep tp_getattr functions when they are complex,
but use PyObject_GenericGetAttr() as a fallback.

These were the last occurrences of Py_FindMethod.

Include/methodobject.h
Modules/_elementtree.c
Modules/pyexpat.c
Objects/methodobject.c

index cd1d2655640fdb7922aa859b0e5149ead648af4d..81e84ceae4d4150bd36ab7508be02558143219bf 100644 (file)
@@ -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 */
index 099df7b7150cac180e783501d4b5e2ad5c5ed678..da223c4ee09f7ae1cf0456aa226849d65d6d604a 100644 (file)
@@ -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);
index 92fc753659ba57612bd307605ebc095624eba7eb..e85f3924c70d7801c1cb875fac18e9a1ec93e382 100644 (file)
@@ -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);
index 3d208c16736f020fd249ebd58a246a0cebb55008..cb6f1ba86acbb40d4d15cc10b55a8f9bfce92c77 100644 (file)
@@ -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