Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Py_FindMethod to docs #22

Closed
ghost opened this issue Jan 21, 2018 · 7 comments · Fixed by #47
Closed

Add Py_FindMethod to docs #22

ghost opened this issue Jan 21, 2018 · 7 comments · Fixed by #47

Comments

@ghost
Copy link

ghost commented Jan 21, 2018

No description provided.

@fbergmann
Copy link

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.

@encukou
Copy link
Owner

encukou commented Mar 5, 2018

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.

@fbergmann
Copy link

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.

@encukou
Copy link
Owner

encukou commented Mar 5, 2018

Is the code you're working on open-source, by any chance?
It would be nice to have a real-world example.

@fbergmann
Copy link

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.

@davvid
Copy link
Contributor

davvid commented Sep 13, 2021

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! ]

@encukou
Copy link
Owner

encukou commented Sep 13, 2021

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.

davvid added a commit to davvid/py3c that referenced this issue Sep 13, 2021
Add a "Py_FindMethod and Generic Attributes" section to document the
use of Py_FindMethod.

Document how to upgrade old code that uses Py_FindMethod() from a custom
tp_getattr function.

Provide an example demonstrating how to replace general usage of
Py_FindMethod.

Closes encukou#22
Signed-off-by: David Aguilar <davvid@gmail.com>
davvid added a commit to davvid/py3c that referenced this issue Sep 16, 2021
Add a "Py_FindMethod and Generic Attributes" section to document the
use of Py_FindMethod.

Document how to upgrade old code that uses Py_FindMethod() from a custom
tp_getattr function.

Closes encukou#22
Signed-off-by: David Aguilar <davvid@gmail.com>
encukou pushed a commit that referenced this issue Oct 15, 2021
Add a "Py_FindMethod and Generic Attributes" section to document the
use of Py_FindMethod.

Document how to upgrade old code that uses Py_FindMethod() from a custom
tp_getattr function.

Closes #22
Signed-off-by: David Aguilar <davvid@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants