PyObject_CallObject: difference between functions and class methods

Discussion in 'Python' started by mauro, Sep 27, 2007.

  1. mauro

    mauro Guest

    Hi all!

    I am trying to call within a C extension a Python function provided as
    an argument by the user with: PyObject_Call(). The C extension should
    work also if the user supplies a class method, but in this case I am
    getting an error. Do I need to explicitly pass 'self' as an argument
    to PyObject_Call()? If so, how can I do that?

    Now, I am using:

    if ((tmp_args = PyTuple_New(1)) == NULL)
    PyErr_SetString( PyExc_ReferenceError, "attempt to access a null-
    pointer" );
    PyTuple_SetItem(tmp_args, 0, paramlist);

    to create the tuple required by PyObject_Call(), but I have no idea on
    how to add a reference to 'self'.

    Here is what I would like to obtain:

    ##
    import mymodule

    def myfunc(x):
    # Do something
    return [z]

    class MyClass:
    def mymethod(self, x):
    # Do something
    return z
    def runme(self):
    mymodule.main(myfunc) # This will work
    mymodule.main(self.mymethod) # This will not work (Segmentation
    fault)

    x = MyClass()
    x.runme()
    ##

    Thanks in advance.

    Mauro
     
    mauro, Sep 27, 2007
    #1
    1. Advertising

  2. Re: PyObject_CallObject: difference between functions and classmethods

    [ Note that there is now a mailing list dedicated to the C API:
    http://mail.python.org/mailman/listinfo/capi-sig ]

    mauro <> writes:

    > I am trying to call within a C extension a Python function provided as
    > an argument by the user with: PyObject_Call(). The C extension should
    > work also if the user supplies a class method, but in this case I am
    > getting an error. Do I need to explicitly pass 'self' as an argument
    > to PyObject_Call()?


    You don't. The reference to self will be added automatically when
    invoking the function you receive as object.method.

    > if ((tmp_args = PyTuple_New(1)) == NULL)
    > PyErr_SetString( PyExc_ReferenceError, "attempt to access a null-
    > pointer" );
    > PyTuple_SetItem(tmp_args, 0, paramlist);


    Maybe you are mismanaging the reference count -- PyTuple_SetItem
    steals the refcount of its argument. Anyway, why not use
    PyObject_CallFunction or PyObject_CallFunctionObjArgs? For example:

    PyObject *
    mymodule_main(PyObject *ignored, PyObject *func)
    {
    PyObject *result, *my_param;
    /* ... do something, e.g. create my_param ... */

    /* call func */
    result = PyObject_CallFunction(received_func, "O", my_param);
    Py_DECREF(my_param); /* assuming you no longer need it */
    if (!result)
    return NULL;

    /* ... do something with result ... */

    Py_DECREF(result);
    Py_INCREF(Py_None);
    return Py_None; /* or whatever */
    }
     
    Hrvoje Niksic, Sep 27, 2007
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jakk
    Replies:
    4
    Views:
    12,642
  2. John Smith
    Replies:
    0
    Views:
    524
    John Smith
    Aug 17, 2004
  3. John M. Gabriele
    Replies:
    18
    Views:
    1,225
    Steven Bethard
    Feb 18, 2005
  4. Sami Vaisanen
    Replies:
    1
    Views:
    422
    Gabriel Genellina
    Oct 20, 2007
  5. Kenneth McDonald
    Replies:
    5
    Views:
    387
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page