Closed ghost closed 3 years ago
Hi,
PyObject_GenericGetAttr
should work in most cases.
Describing this in depth is on my radar, but I'm swamped by other work at the moment.
Ok .. figured it (mostly) out ... not quite as dir(customtype)
still lists an error, but i can call the methods again. the trick was to manually iterate through the method dictionary until the right PyMethodDef
was encountered and then call an return PyCFunction_New
with the method definition and self
.
Since PyObject_GenericGetAttr
didn't know about my method definitions it just returned an element not found.
Is the code you're working on open-source, by any chance? It would be nice to have a real-world example.
It will be, once it is all working. In the mean time here the relevant code snippet:
static PyObject * ds_getattro(PyObject *self, PyObject *nameobj)
{
// try to resolve by name
char* name = PyBytes_AsString(nameobj);
if (name != NULL && strcmp(name, "len") == 0)
return Py_BuildValue("i", getLength((tds *)self));
if (name != NULL && strcmp(name, "__members__") == 0)
return Py_BuildValue("[s]", "len");
#if PY_MAJOR_VERSION >= 3
{
int i;
// try to find handler manually
for (i = 0; DataStream_methods[i].ml_name != NULL; ++i) {
if (strcmp(name, DataStream_methods[i].ml_name) == 0) {
PyObject *result = PyCFunction_New(&DataStream_methods[i], self);
if (result == NULL)
result = Py_None;
Py_INCREF(result);
return result;
}
}
}
// use generic which will give us an error
return PyObject_GenericGetAttr((PyObject *)self, nameobj);
#else
return Py_FindMethod(DataStream_methods, (PyObject *)self, name);
#endif
}
like i said, i could not yet find why dir
will no longer print all available methods, when it used to work in python 2.
I ran into a similar situation. What worked really well was having an ifdef that activates on Python3 that sets the tp_methods
field of the type object struct to point to the PyMethodDef array (DataStream_methods
in your example).
That should eliminate the need for custom code in getattro for looking up the methods -- tp_methods
will do it for you. This also fixed the dir(...)
situation in my scenario.
Maybe py3c should not add Py_FindMethod support, but if there's some useful information in this issue then perhaps it can be folded into the docs.
[ I realize I'm responding to an issue from 2018 but figured this might be helpful for someone else as well. cheers! ]
It's still an open issue :) My priorities did shift; I'll probably not get to adding this myself, but I'm happy to review pull requests.
I just came across this myself, it would be great if there would be a macro for
Py_FindMethod
as well, or at least if a workaround would be described.