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