problem using C-bindings

E

eq

Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction")

The Python-code would look like this:
MyClass.py:

class MyClass:
def MyFunction(self):
print 'Hello'

My C-application can do all the steps except the last one.
myapp.c:

#include <Python.h>

static PyMethodDef ModuleMethods[] = { {NULL} };

void attachFunc(PyObject* class,PyObject* dict,char* func_code,char* name)
{
PyObject* pyfunc_code;
PyObject* pyfunc;
pyfunc_code=Py_CompileString(func_code,"",Py_file_input);
pyfunc=PyFunction_New(pyfunc_code,dict);
PyObject_SetAttrString(class,name,pyfunc);
}

int main(int argc,char** argv)
{
Py_SetProgramName(argv[0]);
Py_Initialize();
PyObject* module;
PyObject* module_dict;
PyObject* class;
PyObject* class_dict;
PyObject* class_name;

module=Py_InitModule("MyModule",ModuleMethods);
module_dict=PyModule_GetDict(module);
class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);

attachFunc(class,module_dict,"print 'hello'\n","MyFunction");

PyRun_SimpleString("import MyModule\n");
PyRun_SimpleString("t=MyModule.MyClass()\n");
PyRun_SimpleString("t.MyFunction()\n");
return 0;
}

When executing the application, I get the following(because of the
"t.MyFunction()") Traceback (most recent call last):
File "<string>", line 1, in ?
TypeError: ?() takes no arguments (1 given)

What am I doing wrong?

Greetings,
Henning
 
J

Jack Diederich

Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction") [snip]
class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);
[snip]

Take a look at Modules/xxsubtype.c in the source distribution.
It is an example of how to subtype a builtin. xxmodule.c shows
how to make a class from scratch. Both are out of date but a good
sarting spot.

You could also give Pyrex a try, it makes it easier to write just
a hot function or two of a class in C. I like it to prototype C versions
of hotspot functions (but then do the final version 'by hand').

-Jack
 
E

eq

Am Thu, 19 Aug 2004 17:45:45 -0400 schrieb Jack Diederich:
Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction") [snip]
class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);
[snip]

Take a look at Modules/xxsubtype.c in the source distribution.
It is an example of how to subtype a builtin. xxmodule.c shows
how to make a class from scratch. Both are out of date but a good
sarting spot.
Hm, perhaps I over-complicated my problem:
I don't need a full python-class in pure C. I just need to create a
(python!) function(a dynamic one, not a static C function) and attach it
to an already existing python-class just by using C-calls.
I try to do this by compiling the function's code with:

pyfunc_code=Py_CompileString(func_code,"",Py_file_input);

where func_code could be something like "print 'hello'" and then I try to
make a function out of this by calling:

pyfunc=PyFunction_New(pyfunc_code,dict);

where dict is the global namespace for the function.
What I now want is to attach this function to the already created class
"MyClass".
 
J

Jack Diederich

Am Thu, 19 Aug 2004 17:45:45 -0400 schrieb Jack Diederich:
Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction") [snip]
class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);
[snip]

Take a look at Modules/xxsubtype.c in the source distribution.
It is an example of how to subtype a builtin. xxmodule.c shows
how to make a class from scratch. Both are out of date but a good
sarting spot.
Hm, perhaps I over-complicated my problem:
I don't need a full python-class in pure C. I just need to create a
(python!) function(a dynamic one, not a static C function) and attach it
to an already existing python-class just by using C-calls.
I try to do this by compiling the function's code with:

pyfunc_code=Py_CompileString(func_code,"",Py_file_input);

where func_code could be something like "print 'hello'" and then I try to
make a function out of this by calling:

pyfunc=PyFunction_New(pyfunc_code,dict);

where dict is the global namespace for the function.
What I now want is to attach this function to the already created class
"MyClass".

In that case I would see how xxmodule.c exports methods in the xx_methods
array and then in your python code have the class method call that exported
method.

import xxmodule
class MyClass(object):
def xxfunc(self, arg):
return xxmodule.xxfunc(self.someval, arg)

In practice I've never had a class that wasn't all python or all C but
I have written small helper functions in C that are called from python.

-Jack
 
E

eq

Am Thu, 19 Aug 2004 19:21:31 -0400 schrieb Jack Diederich:
Am Thu, 19 Aug 2004 17:45:45 -0400 schrieb Jack Diederich:
On Thu, Aug 19, 2004 at 10:32:15PM +0200, eq wrote:
Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction")
[snip]
class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);
[snip]

Take a look at Modules/xxsubtype.c in the source distribution.
It is an example of how to subtype a builtin. xxmodule.c shows
how to make a class from scratch. Both are out of date but a good
sarting spot.
Hm, perhaps I over-complicated my problem:
I don't need a full python-class in pure C. I just need to create a
(python!) function(a dynamic one, not a static C function) and attach it
to an already existing python-class just by using C-calls.
I try to do this by compiling the function's code with:

pyfunc_code=Py_CompileString(func_code,"",Py_file_input);

where func_code could be something like "print 'hello'" and then I try to
make a function out of this by calling:

pyfunc=PyFunction_New(pyfunc_code,dict);

where dict is the global namespace for the function.
What I now want is to attach this function to the already created class
"MyClass".

In that case I would see how xxmodule.c exports methods in the xx_methods
array and then in your python code have the class method call that exported
method.

That's not the point, the problem is that no example i've found(including
the xx_* files) shows how to create a python function from C-code. To make
the thing worse, there's also no example how to add such a function to a
class by using C code.
The xx_* files only create static C methods what is not what I want.
 
S

Scott David Daniels

eq said:
Am Thu, 19 Aug 2004 17:45:45 -0400 schrieb Jack Diederich:

Hi,

I'm trying to create a program(written in C) that does the following
things using embedded Python:
1. Create a module(say, "MyModule")
2. Create a class in that module(say, "MyClass")
3. Create a function in that module(say, "MyFunction")
[snip]

class_dict=PyDict_New();
class_name=PyString_FromString("MyClass");
class=PyClass_New(NULL,class_dict,class_name);
PyDict_SetItemString(module_dict,"MyClass",class);

[snip]

Take a look at Modules/xxsubtype.c in the source distribution.
It is an example of how to subtype a builtin. xxmodule.c shows
how to make a class from scratch. Both are out of date but a good
sarting spot.

Hm, perhaps I over-complicated my problem:
I don't need a full python-class in pure C. I just need to create a
(python!) function(a dynamic one, not a static C function) and attach it
to an already existing python-class just by using C-calls.
You've already managed this. The error message is telling you it has
no place to put "self".
I try to do this by compiling the function's code with:

pyfunc_code=Py_CompileString(func_code,"",Py_file_input);

where func_code could be something like "print 'hello'" and then I try to
make a function out of this by calling:

pyfunc=PyFunction_New(pyfunc_code,dict);

where dict is the global namespace for the function.
What I now want is to attach this function to the already created class
"MyClass".
You should call "staticmethod" on your pyfunc before putting it into the
class.


The error message you got before:
TypeError: ?() takes no arguments (1 given)
indicates that you had defined a 0-arg function and were calling it
with one arg. That arg was the "self" arg. You could do the moral
equivalent of:
MyClass.MyFunction = staticmethod(MyClass.MyFunction)
after the code you have now. Alternatively you could pull staticmethod
from __builtins__ and "apply" it yourself before storing in attachFunc.

Just guessing from "funcobject.h", but I'll bet you could also change
attachFunc as follows

void attachFunc(PyObject* class, PyObject* dict,
char* func_code, char* name)
{
PyObject* pyfunc_code;
PyObject* pyfunc;
pyfunc_code=Py_CompileString(func_code,"",Py_file_input);
pyfunc=PyFunction_New(pyfunc_code,dict);
pyfunc=PyStaticMethod_New(pyfunc);

PyObject_SetAttrString(class,name,pyfunc);
}

You do know you need to do much more error checkig here, don't you?
Untested (my mail machine and my C machine are different).

int attachFunc(PyObject* class, PyObject* dict,
char* func_code, char* name)
{
PyObject* pyfunc_code = NULL;
PyObject* pyfunc = NULL;
PyObject* pyfunc_static = NULL;
int result = -1; /* 0 for success */

pyfunc_code = Py_CompileString(func_code, "", Py_file_input);
if (pyfunc_code) {
pyfunc = PyFunction_New(pyfunc_code, dict);
if (pyfunc) {
pyfunc_static = PyStaticMethod_New(pyfunc);
result = PyObject_SetAttrString(class, name, pyfunc);
}
Py_XDECREF(pyfunc_static);
Py_XDECREF(pyfunc);
Py_XDECREF(pyfunc_code);
return result;
}

-Scott David Daniels
(e-mail address removed)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top