1 //metadoc Python copyrigth Aslak Gronflaten, 2006
2 //metadoc Python license BSD revised
3 /*metadoc Python description
4 This object provides access the world of python.
6 //metadoc Python credit Based on code by Steve Dekorte
7 //metadoc Python category Server
13 #include "IoDirectory.h"
17 #define DATA(self) ((PythonData *)IoObject_dataPointer(self))
19 IoTag
*IoPython_newTag(void *state
)
21 IoTag
*tag
= IoTag_newWithName_("Python");
22 IoTag_state_(tag
, state
);
23 IoTag_cloneFunc_(tag
, (IoTagCloneFunc
*)IoPython_rawClone
);
24 IoTag_freeFunc_(tag
, (IoTagFreeFunc
*)IoPython_free
);
28 IoPython
*IoPython_proto(void *state
)
31 IoObject
*self
= IoObject_new(state
);
32 IoObject_tag_(self
, IoPython_newTag(state
));
33 IoObject_setDataPointer_(self
, PythonData_new());
35 IoState_registerProtoWithFunc_(state
, self
, IoPython_proto
);
38 IoMethodTable methodTable
[] = {
39 {"credits", IoPython_credits
},
40 {"forward", IoPython_forward
},
41 {"import", IoPython_import
},
42 {"invoke", IoPython_call
},
43 {"print", IoPython_print
},
46 IoObject_addMethodTable_(self
, methodTable
);
48 DATA(self
)->data
= (void *) 1; // Hack
52 IoPython
*IoPython_rawClone(IoPython
*proto
)
54 IoPython
*self
= IoObject_rawClonePrimitive(proto
);
55 IoObject_setDataPointer_(self
, PythonData_new());
59 /* ----------------------------------------------------------- */
61 IoPython
*IoPython_new(void *state
)
63 IoObject
*proto
= IoState_protoWithInitFunction_(state
, IoPython_proto
);
64 return IOCLONE(proto
);
67 void IoPython_free(IoPython
*self
)
69 PythonData_free(DATA(self
));
71 /* ----------------------------------------------------------- */
73 IoObject
*wrap(IoPython
*self
, PyObject
*o
) {
74 IoPython
*ret
= IoPython_new(IOSTATE
);
79 IoObject
*IoPython_credits(IoPython
*self
, IoObject
*locals
, IoMessage
*m
)
81 return IOSYMBOL("Python/Io bridge by Aslak Gronflaten");
84 IoObject
*IoPython_print(IoPython
*self
, IoObject
*locals
, IoMessage
*m
)
86 PyObject
*obj
= DATA(self
)->data
;
88 PyObject_Print(obj
, stdout
, 0);
94 * Convert an Io object to PyObject.
95 * At the moment, we can't pass in any objects, just those that can be translated,
96 * until I build a python wrapper around an io object, reverse of what I did here.
97 * TODO: Memory management!!!
99 PyObject
*convertIo(IoObject
*self
, IoObject
*obj
) {
102 ret
= PyFloat_FromDouble(CNUMBER(obj
));
107 ret
= PyString_FromString(CSTRING(obj
));
111 printf("Unable to convert parameter to python.\n");
116 * Tries to convert the obj to an Io object, if possible. If not, return null.
117 * Can't decref if this method is used on both pFunc and pValue
119 IoObject
*convertPy(IoObject
*self
, PyObject
*obj
) {
120 //PyObject_Print(obj, stdout, 0);
121 //PyObject *pType = PyObject_Type(obj);
122 //PyObject_Print(pType, stdout, 0);
123 IoObject
*ret
; // Return value
125 if(PyString_Check(obj
)) {
126 // Convert to Io sequence and return.
127 IoSeq
*ret
= IoSeq_newWithCString_(IOSTATE
, PyString_AsString(obj
));
128 // TODO:::: Memory management! Who's responsible here! (I am, that's who)
132 if(PyFloat_Check(obj
)) {
133 ret
= IoNumber_newWithDouble_(IOSTATE
, PyFloat_AS_DOUBLE(obj
));
137 if(PyInt_Check(obj
)) {
138 ret
= IoNumber_newWithDouble_(IOSTATE
, PyInt_AS_LONG(obj
));
142 if(PyList_Check(obj
)) {
143 // We have a list. So, make an Io list, and convert every element, and insert them.
144 int len
= PyList_GET_SIZE(obj
);
145 ret
= IoList_new(IOSTATE
);
148 PyObject
*o
= PyList_GET_ITEM(obj
, i
);
149 IoObject
*x
= convertPy(self
, o
);
151 IoList_rawAppend_(ret
, x
);
155 if(PyDict_Check(obj
)) {
156 // We have a dictionary. Make an Io map, and convert all values.
157 // or should we.... Io's map can only have string keys... hardly a replacement, now is it.
158 // Would be better to build a good wrapper around the python dict.
160 if(PyCallable_Check(obj
)) {
161 //ret = IoState_doString_(IOSTATE, "method(return self invoke(\"\")");
162 // TODO: We should return a callable object here... Don't know how though. Yet.
164 return wrap(self
, obj
);
169 IoObject
*IoPython_call_int(IoPython
*self
, IoObject
*locals
, IoMessage
*m
, int argOffset
, char *functionName
)
171 int argc
= IoMessage_argCount(m
);
173 PyObject
*pModule
= DATA(self
)->data
;
175 fprintf(stderr
, "We have null pModule for function %s ", functionName
);
178 if(!PyObject_HasAttrString(pModule
, functionName
)){
179 fprintf(stderr
, "Module has no function %s ", functionName
);
183 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, functionName
);
184 /* pFunc is a new reference */
186 if (pFunc
&& PyCallable_Check(pFunc
)) {
187 PyObject
*pArgs
= PyTuple_New(argc
- argOffset
); // argc
189 for(i
= argOffset
;i
<argc
;i
++) {
190 IoObject
*param
= IoMessage_locals_valueArgAt_(m
, locals
, i
);
191 PyObject
*pyValue
= convertIo(self
, param
);
192 PyTuple_SetItem(pArgs
, i
-argOffset
, pyValue
);
194 PyObject
*pValue
= PyObject_CallObject(pFunc
, pArgs
);
197 if (pValue
!= NULL
) {
198 return convertPy(self
, pValue
);
200 if (PyErr_Occurred())
202 fprintf(stderr
,"Call failed\n");
205 if (PyErr_Occurred())
208 return convertPy(self
, pFunc
);
210 fprintf(stderr
, "Cannot find python function \"%s\"\n", functionName
);
215 IoObject
*IoPython_forward(IoPython
*self
, IoObject
*locals
, IoMessage
*m
)
217 IoSymbol
*name
= IoMessage_name(m
);
218 char *functionName
= IoSeq_asCString(name
);
219 return IoPython_call_int(self
, locals
, m
, 0, functionName
);
222 IoObject
*IoPython_call(IoPython
*self
, IoObject
*locals
, IoMessage
*m
)
224 IoSeq
*name
= IoMessage_locals_seqArgAt_(m
, locals
, 0);
225 char *functionName
= IoSeq_asCString(name
);
226 return IoPython_call_int(self
, locals
, m
, 1, functionName
);
231 * Import a module, return reference to it as a Python object
233 IoObject
*IoPython_import(IoPython
*self
, IoObject
*locals
, IoMessage
*m
)
235 IoSeq
*name
= IoMessage_locals_seqArgAt_(m
, locals
, 0);
236 char *nameString
= IoSeq_asCString(name
);
238 PyObject
*pName
, *pModule
;
239 pName
= PyString_FromString(nameString
);
240 /* Error checking of pName left out */
242 pModule
= PyImport_Import(pName
);
245 fprintf(stderr
, "Could not find module %s\n", nameString
);
249 // Set slots (for easier introspection and use from io)
251 PyObject *dict = PyModule_GetDict(pModule);
252 PyObject *keys = PyDict_Keys(dict);
254 for(i = 0;i<PyList_Size(keys);i++) {
255 PyObject *key = PyList_GetItem(keys, i);
256 PyObject *value = PyDict_GetItem(dict, key);
257 // TODO: Not allowed method vall IoSeq_newSymbolWithCString_
258 if(!PyCallable_Check(value)) {// don't want methods blocking the forward
259 IoObject_setSlot_to_(self, IOSYMBOL(PyString_AsString(key)), convertPy(self, value));
267 // Now, we've got the module. Wrap it and return it.
268 return wrap(self
, pModule
);