py api was raising SystemError exception incorrectly, this is intended for internal...
[blender.git] / source / blender / python / generic / py_capi_utils.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21 */
22
23 #include <Python.h>
24
25 #include "py_capi_utils.h"
26
27 /* for debugging */
28 void PyC_ObSpit(const char *name, PyObject *var) {
29         fprintf(stderr, "<%s> : ", name);
30         if (var==NULL) {
31                 fprintf(stderr, "<NIL>");
32         }
33         else {
34                 PyObject_Print(var, stderr, 0);
35                 fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
36                 fprintf(stderr, " ptr:%p", (void *)var);
37                 
38                 fprintf(stderr, " type:");
39                 if(Py_TYPE(var))
40                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
41                 else
42                         fprintf(stderr, "<NIL>");
43         }
44         fprintf(stderr, "\n");
45 }
46
47 void PyC_LineSpit(void) {
48         const char *filename;
49         int lineno;
50
51         PyErr_Clear();
52         PyC_FileAndNum(&filename, &lineno);
53         
54         fprintf(stderr, "%s:%d\n", filename, lineno);
55 }
56
57 void PyC_FileAndNum(const char **filename, int *lineno)
58 {
59         PyObject *getframe, *frame;
60         PyObject *f_lineno= NULL, *co_filename= NULL;
61         
62         if (filename)   *filename= NULL;
63         if (lineno)             *lineno = -1;
64         
65         getframe = PySys_GetObject("_getframe"); // borrowed
66         if (getframe==NULL) {
67                 PyErr_Clear();
68                 return;
69         }
70         
71         frame = PyObject_CallObject(getframe, NULL);
72         if (frame==NULL) {
73                 PyErr_Clear();
74                 return;
75         }
76         
77         /* when executing a script */
78         if (filename) {
79                 co_filename= PyC_Object_GetAttrStringArgs(frame, 2, "f_code", "co_filename");
80                 if (co_filename==NULL) {
81                         PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_code.co_filename");
82                         Py_DECREF(frame);
83                         return;
84                 }
85                 
86                 *filename = _PyUnicode_AsString(co_filename);
87                 Py_DECREF(co_filename);
88         }
89         
90         /* when executing a module */
91         if(filename && *filename == NULL) {
92                 /* try an alternative method to get the filename - module based
93                  * references below are all borrowed (double checked) */
94                 PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
95                 if(mod_name) {
96                         PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
97                         if(mod) {
98                                 *filename= PyModule_GetFilename(mod);
99                         }
100
101                         /* unlikely, fallback */
102                         if(*filename == NULL) {
103                                 *filename= _PyUnicode_AsString(mod_name);
104                         }
105                 }
106         }
107                 
108         
109         if (lineno) {
110                 f_lineno= PyObject_GetAttrString(frame, "f_lineno");
111                 if (f_lineno==NULL) {
112                         PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_lineno");
113                         Py_DECREF(frame);
114                         return;
115                 }
116                 
117                 *lineno = (int)PyLong_AsSsize_t(f_lineno);
118                 Py_DECREF(f_lineno);
119         }
120
121         Py_DECREF(frame);
122 }
123
124 /* Would be nice if python had this built in */
125 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
126 {
127         Py_ssize_t i;
128         PyObject *item= o;
129         char *attr;
130         
131         va_list vargs;
132
133         va_start(vargs, n);
134         for (i=0; i<n; i++) {
135                 attr = va_arg(vargs, char *);
136                 item = PyObject_GetAttrString(item, attr);
137                 
138                 if (item) 
139                         Py_DECREF(item);
140                 else /* python will set the error value here */
141                         break;
142                 
143         }
144         va_end(vargs);
145         
146         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
147         return item;
148 }
149
150 /* returns the exception string as a new PyUnicode object, depends on external StringIO module */
151 PyObject *PyC_ExceptionBuffer(void)
152 {
153         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
154         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
155         PyObject *string_io = NULL;
156         PyObject *string_io_buf = NULL;
157         PyObject *string_io_mod= NULL;
158         PyObject *string_io_getvalue= NULL;
159         
160         PyObject *error_type, *error_value, *error_traceback;
161         
162         if (!PyErr_Occurred())
163                 return NULL;
164         
165         PyErr_Fetch(&error_type, &error_value, &error_traceback);
166         
167         PyErr_Clear();
168         
169         /* import io
170          * string_io = io.StringIO()
171          */
172         
173         if(! (string_io_mod= PyImport_ImportModule("io")) ) {
174                 goto error_cleanup;
175         } else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
176                 goto error_cleanup;
177         } else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
178                 goto error_cleanup;
179         }
180         
181         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
182         Py_INCREF(stderr_backup);
183         
184         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
185         PySys_SetObject("stderr", string_io);
186         
187         PyErr_Restore(error_type, error_value, error_traceback);
188         PyErr_Print(); /* print the error */
189         PyErr_Clear();
190         
191         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
192         
193         PySys_SetObject("stdout", stdout_backup);
194         PySys_SetObject("stderr", stderr_backup);
195         
196         Py_DECREF(stdout_backup); /* now sys owns the ref again */
197         Py_DECREF(stderr_backup);
198         
199         Py_DECREF(string_io_mod);
200         Py_DECREF(string_io_getvalue);
201         Py_DECREF(string_io); /* free the original reference */
202         
203         PyErr_Clear();
204         return string_io_buf;
205         
206         
207 error_cleanup:
208         /* could not import the module so print the error and close */
209         Py_XDECREF(string_io_mod);
210         Py_XDECREF(string_io);
211         
212         PyErr_Restore(error_type, error_value, error_traceback);
213         PyErr_Print(); /* print the error */
214         PyErr_Clear();
215         
216         return NULL;
217 }
218
219
220 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
221 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
222 {
223         char *result;
224
225         result= _PyUnicode_AsString(py_str);
226
227         if(result) {
228                 /* 99% of the time this is enough but we better support non unicode
229                  * chars since blender doesnt limit this */
230                 return result;
231         }
232         else if(PyBytes_Check(py_str)) {
233                 PyErr_Clear();
234                 return PyBytes_AS_STRING(py_str);
235         }
236         else {
237                 /* mostly copied from fileio.c's, fileio_init */
238                 PyObject *stringobj;
239                 PyObject *u;
240
241                 PyErr_Clear();
242                 
243                 u= PyUnicode_FromObject(py_str); /* coerce into unicode */
244                 
245                 if (u == NULL)
246                         return NULL;
247
248                 stringobj= PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(u), PyUnicode_GET_SIZE(u), "surrogateescape");
249                 Py_DECREF(u);
250                 if (stringobj == NULL)
251                         return NULL;
252                 if (!PyBytes_Check(stringobj)) { /* this seems wrong but it works fine */
253                         // printf("encoder failed to return bytes\n");
254                         Py_DECREF(stringobj);
255                         return NULL;
256                 }
257                 *coerce= stringobj;
258
259                 return PyBytes_AS_STRING(stringobj);
260         }
261 }
262
263 PyObject *PyC_UnicodeFromByte(const char *str)
264 {
265         PyObject *result= PyUnicode_FromString(str);
266         if(result) {
267                 /* 99% of the time this is enough but we better support non unicode
268                  * chars since blender doesnt limit this */
269                 return result;
270         }
271         else {
272                 PyErr_Clear();
273                 /* this means paths will always be accessible once converted, on all OS's */
274                 result= PyUnicode_DecodeFSDefault(str);
275                 return result;
276         }
277 }
278
279 /*****************************************************************************
280 * Description: This function creates a new Python dictionary object.
281 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
282 * note: important we use the dict from __main__, this is what python expects
283   for 'pickle' to work as well as strings like this...
284  >> foo = 10
285  >> print(__import__("__main__").foo)
286 *
287 * note: this overwrites __main__ which gives problems with nested calles.
288 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
289 * any chance that python is in the call stack.
290 *****************************************************************************/
291 PyObject *PyC_DefaultNameSpace(const char *filename)
292 {
293         PyInterpreterState *interp= PyThreadState_GET()->interp;
294         PyObject *mod_main= PyModule_New("__main__");   
295         PyDict_SetItemString(interp->modules, "__main__", mod_main);
296         Py_DECREF(mod_main); /* sys.modules owns now */
297         PyModule_AddStringConstant(mod_main, "__name__", "__main__");
298         if(filename)
299                 PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
300         PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
301         Py_INCREF(interp->builtins); /* AddObject steals a reference */
302         return PyModule_GetDict(mod_main);
303 }
304
305 /* restore MUST be called after this */
306 void PyC_MainModule_Backup(PyObject **main_mod)
307 {
308         PyInterpreterState *interp= PyThreadState_GET()->interp;
309         *main_mod= PyDict_GetItemString(interp->modules, "__main__");
310         Py_XINCREF(*main_mod); /* dont free */
311 }
312
313 void PyC_MainModule_Restore(PyObject *main_mod)
314 {
315         PyInterpreterState *interp= PyThreadState_GET()->interp;
316         PyDict_SetItemString(interp->modules, "__main__", main_mod);
317         Py_XDECREF(main_mod);
318 }
319
320 /* Would be nice if python had this built in */
321 void PyC_RunQuicky(const char *filepath, int n, ...)
322 {
323         FILE *fp= fopen(filepath, "r");
324
325         if(fp) {
326                 PyGILState_STATE gilstate= PyGILState_Ensure();
327
328                 va_list vargs;  
329
330                 int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
331                 int i;
332
333                 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
334                 PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
335
336                 PyObject *py_result, *ret;
337
338                 PyObject *struct_mod= PyImport_ImportModule("struct");
339                 PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
340                 PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
341                 PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
342
343                 Py_DECREF(struct_mod);
344
345                 va_start(vargs, n);
346                 for (i=0; i * 2<n; i++) {
347                         char *format = va_arg(vargs, char *);
348                         void *ptr = va_arg(vargs, void *);
349
350                         ret= PyObject_CallFunction(calcsize, (char *)"s", format);
351
352                         if(ret) {
353                                 sizes[i]= PyLong_AsSsize_t(ret);
354                                 Py_DECREF(ret);
355                                 ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
356                         }
357
358                         if(ret == NULL) {
359                                 printf("PyC_InlineRun error, line:%d\n", __LINE__);
360                                 PyErr_Print();
361                                 PyErr_Clear();
362
363                                 PyList_SET_ITEM(values, i, Py_None); /* hold user */
364                                 Py_INCREF(Py_None);
365
366                                 sizes[i]= 0;
367                         }
368                         else {
369                                 if(PyTuple_GET_SIZE(ret) == 1) {
370                                         /* convenience, convert single tuples into single values */
371                                         PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
372                                         Py_INCREF(tmp);
373                                         Py_DECREF(ret);
374                                         ret = tmp;
375                                 }
376
377                                 PyList_SET_ITEM(values, i, ret); /* hold user */
378                         }
379                 }
380                 va_end(vargs);
381                 
382                 /* set the value so we can access it */
383                 PyDict_SetItemString(py_dict, "values", values);
384
385                 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
386
387                 fclose(fp);
388
389                 if(py_result) {
390
391                         /* we could skip this but then only slice assignment would work
392                          * better not be so strict */
393                         values= PyDict_GetItemString(py_dict, "values");
394
395                         if(values && PyList_Check(values)) {
396
397                                 /* dont use the result */
398                                 Py_DECREF(py_result);
399                                 py_result= NULL;
400
401                                 /* now get the values back */
402                                 va_start(vargs, n);
403                                 for (i=0; i*2 <n; i++) {
404                                         char *format = va_arg(vargs, char *);
405                                         void *ptr = va_arg(vargs, void *);
406                                         
407                                         PyObject *item;
408                                         PyObject *item_new;
409                                         /* prepend the string formatting and remake the tuple */
410                                         item= PyList_GET_ITEM(values, i);
411                                         if(PyTuple_CheckExact(item)) {
412                                                 int ofs= PyTuple_GET_SIZE(item);
413                                                 item_new= PyTuple_New(ofs + 1);
414                                                 while(ofs--) {
415                                                         PyObject *member= PyTuple_GET_ITEM(item, ofs);
416                                                         PyTuple_SET_ITEM(item_new, ofs + 1, member);
417                                                         Py_INCREF(member);
418                                                 }
419
420                                                 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
421                                         }
422                                         else {
423                                                 item_new= Py_BuildValue("sO", format, item);
424                                         }
425
426                                         ret = PyObject_Call(pack, item_new, NULL);
427
428                                         if(ret) {
429                                                 /* copy the bytes back into memory */
430                                                 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
431                                                 Py_DECREF(ret);
432                                         }
433                                         else {
434                                                 printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
435                                                 PyC_ObSpit("failed converting:", item_new);
436                                                 PyErr_Print();
437                                                 PyErr_Clear();
438                                         }
439
440                                         Py_DECREF(item_new);
441                                 }
442                                 va_end(vargs);
443                         }
444                         else {
445                                 printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
446                         }
447                 }
448                 else {
449                         printf("PyC_InlineRun error line:%d\n", __LINE__);
450                         PyErr_Print();
451                         PyErr_Clear();
452                 }
453
454                 Py_DECREF(calcsize);
455                 Py_DECREF(pack);
456                 Py_DECREF(unpack);
457
458                 PyMem_FREE(sizes);
459
460                 PyGILState_Release(gilstate);
461         }
462 }