#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.
This commit is contained in:
Amaury Forgeot d'Arc 2008-07-02 20:50:16 +00:00
parent 4118174315
commit e43d33a4db
13 changed files with 388 additions and 329 deletions

View file

@ -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)