fix [#26951] blenderplayer and runtimes will not load
[blender-staging.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 #include "BKE_font.h" /* only for utf8towchar, should replace with py funcs but too late in release now */
34
35 #define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
36
37 /* for debugging */
38 void PyC_ObSpit(const char *name, PyObject *var) {
39         fprintf(stderr, "<%s> : ", name);
40         if (var==NULL) {
41                 fprintf(stderr, "<NIL>");
42         }
43         else {
44                 PyObject_Print(var, stderr, 0);
45                 fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
46                 fprintf(stderr, " ptr:%p", (void *)var);
47                 
48                 fprintf(stderr, " type:");
49                 if(Py_TYPE(var))
50                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
51                 else
52                         fprintf(stderr, "<NIL>");
53         }
54         fprintf(stderr, "\n");
55 }
56
57 void PyC_LineSpit(void) {
58
59         const char *filename;
60         int lineno;
61
62         /* Note, allow calling from outside python (RNA) */
63         if(!PYC_INTERPRETER_ACTIVE) {
64                 fprintf(stderr, "python line lookup failed, interpreter inactive\n");
65                 return;
66         }
67
68         PyErr_Clear();
69         PyC_FileAndNum(&filename, &lineno);
70         
71         fprintf(stderr, "%s:%d\n", filename, lineno);
72 }
73
74 void PyC_FileAndNum(const char **filename, int *lineno)
75 {
76         PyFrameObject *frame;
77         
78         if (filename)   *filename= NULL;
79         if (lineno)             *lineno = -1;
80
81         if (!(frame= PyThreadState_GET()->frame)) {
82                 return;
83         }
84
85         /* when executing a script */
86         if (filename) {
87                 *filename = _PyUnicode_AsString(frame->f_code->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         if (lineno) {
109                 *lineno = PyFrame_GetLineNumber(frame);
110         }
111 }
112
113 /* Would be nice if python had this built in */
114 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
115 {
116         Py_ssize_t i;
117         PyObject *item= o;
118         char *attr;
119         
120         va_list vargs;
121
122         va_start(vargs, n);
123         for (i=0; i<n; i++) {
124                 attr = va_arg(vargs, char *);
125                 item = PyObject_GetAttrString(item, attr);
126                 
127                 if (item) 
128                         Py_DECREF(item);
129                 else /* python will set the error value here */
130                         break;
131                 
132         }
133         va_end(vargs);
134         
135         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
136         return item;
137 }
138
139 /* returns the exception string as a new PyUnicode object, depends on external StringIO module */
140 PyObject *PyC_ExceptionBuffer(void)
141 {
142         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
143         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
144         PyObject *string_io = NULL;
145         PyObject *string_io_buf = NULL;
146         PyObject *string_io_mod= NULL;
147         PyObject *string_io_getvalue= NULL;
148         
149         PyObject *error_type, *error_value, *error_traceback;
150         
151         if (!PyErr_Occurred())
152                 return NULL;
153         
154         PyErr_Fetch(&error_type, &error_value, &error_traceback);
155         
156         PyErr_Clear();
157         
158         /* import io
159          * string_io = io.StringIO()
160          */
161         
162         if(! (string_io_mod= PyImport_ImportModule("io")) ) {
163                 goto error_cleanup;
164         }
165         else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
166                 goto error_cleanup;
167         }
168         else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
169                 goto error_cleanup;
170         }
171         
172         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
173         Py_INCREF(stderr_backup);
174         
175         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
176         PySys_SetObject("stderr", string_io);
177         
178         PyErr_Restore(error_type, error_value, error_traceback);
179         PyErr_Print(); /* print the error */
180         PyErr_Clear();
181         
182         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
183         
184         PySys_SetObject("stdout", stdout_backup);
185         PySys_SetObject("stderr", stderr_backup);
186         
187         Py_DECREF(stdout_backup); /* now sys owns the ref again */
188         Py_DECREF(stderr_backup);
189         
190         Py_DECREF(string_io_mod);
191         Py_DECREF(string_io_getvalue);
192         Py_DECREF(string_io); /* free the original reference */
193         
194         PyErr_Clear();
195         return string_io_buf;
196         
197         
198 error_cleanup:
199         /* could not import the module so print the error and close */
200         Py_XDECREF(string_io_mod);
201         Py_XDECREF(string_io);
202         
203         PyErr_Restore(error_type, error_value, error_traceback);
204         PyErr_Print(); /* print the error */
205         PyErr_Clear();
206         
207         return NULL;
208 }
209
210
211 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
212 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
213 {
214         char *result;
215
216         result= _PyUnicode_AsString(py_str);
217
218         if(result) {
219                 /* 99% of the time this is enough but we better support non unicode
220                  * chars since blender doesnt limit this */
221                 return result;
222         }
223         else if(PyBytes_Check(py_str)) {
224                 PyErr_Clear();
225                 return PyBytes_AS_STRING(py_str);
226         }
227         else {
228                 return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
229         }
230 }
231
232 PyObject *PyC_UnicodeFromByte(const char *str)
233 {
234         PyObject *result= PyUnicode_FromString(str);
235         if(result) {
236                 /* 99% of the time this is enough but we better support non unicode
237                  * chars since blender doesnt limit this */
238                 return result;
239         }
240         else {
241                 PyErr_Clear();
242                 /* this means paths will always be accessible once converted, on all OS's */
243                 result= PyUnicode_DecodeFSDefault(str);
244                 return result;
245         }
246 }
247
248 /*****************************************************************************
249 * Description: This function creates a new Python dictionary object.
250 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
251 * note: important we use the dict from __main__, this is what python expects
252   for 'pickle' to work as well as strings like this...
253  >> foo = 10
254  >> print(__import__("__main__").foo)
255 *
256 * note: this overwrites __main__ which gives problems with nested calles.
257 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
258 * any chance that python is in the call stack.
259 *****************************************************************************/
260 PyObject *PyC_DefaultNameSpace(const char *filename)
261 {
262         PyInterpreterState *interp= PyThreadState_GET()->interp;
263         PyObject *mod_main= PyModule_New("__main__");   
264         PyDict_SetItemString(interp->modules, "__main__", mod_main);
265         Py_DECREF(mod_main); /* sys.modules owns now */
266         PyModule_AddStringConstant(mod_main, "__name__", "__main__");
267         if(filename)
268                 PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
269         PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
270         Py_INCREF(interp->builtins); /* AddObject steals a reference */
271         return PyModule_GetDict(mod_main);
272 }
273
274 /* restore MUST be called after this */
275 void PyC_MainModule_Backup(PyObject **main_mod)
276 {
277         PyInterpreterState *interp= PyThreadState_GET()->interp;
278         *main_mod= PyDict_GetItemString(interp->modules, "__main__");
279         Py_XINCREF(*main_mod); /* dont free */
280 }
281
282 void PyC_MainModule_Restore(PyObject *main_mod)
283 {
284         PyInterpreterState *interp= PyThreadState_GET()->interp;
285         PyDict_SetItemString(interp->modules, "__main__", main_mod);
286         Py_XDECREF(main_mod);
287 }
288
289 /* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */
290 void PyC_SetHomePath(const char *py_path_bundle)
291 {
292         if(py_path_bundle==NULL) {
293                 /* Common enough to have bundled *nix python but complain on OSX/Win */
294 #if defined(__APPLE__) || defined(_WIN32)
295                 fprintf(stderr, "Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built)\n");
296 #endif
297                 return;
298         }
299         /* set the environment path */
300         printf("found bundled python: %s\n", py_path_bundle);
301
302 #ifdef __APPLE__
303         /* OSX allow file/directory names to contain : character (represented as / in the Finder)
304          but current Python lib (release 3.1.1) doesn't handle these correctly */
305         if(strchr(py_path_bundle, ':'))
306                 printf("Warning : Blender application is located in a path containing : or / chars\
307                            \nThis may make python import function fail\n");
308 #endif
309
310 #ifdef _WIN32
311         /* cmake/MSVC debug build crashes without this, why only
312            in this case is unknown.. */
313         {
314                 BLI_setenv("PYTHONPATH", py_path_bundle);
315         }
316 #endif
317
318         {
319                 static wchar_t py_path_bundle_wchar[1024];
320
321                 /* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */
322                 /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
323
324                 utf8towchar(py_path_bundle_wchar, py_path_bundle);
325
326                 Py_SetPythonHome(py_path_bundle_wchar);
327                 // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
328         }
329 }
330
331 /* Would be nice if python had this built in */
332 void PyC_RunQuicky(const char *filepath, int n, ...)
333 {
334         FILE *fp= fopen(filepath, "r");
335
336         if(fp) {
337                 PyGILState_STATE gilstate= PyGILState_Ensure();
338
339                 va_list vargs;  
340
341                 int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
342                 int i;
343
344                 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
345                 PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
346
347                 PyObject *py_result, *ret;
348
349                 PyObject *struct_mod= PyImport_ImportModule("struct");
350                 PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
351                 PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
352                 PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
353
354                 Py_DECREF(struct_mod);
355
356                 va_start(vargs, n);
357                 for (i=0; i * 2<n; i++) {
358                         char *format = va_arg(vargs, char *);
359                         void *ptr = va_arg(vargs, void *);
360
361                         ret= PyObject_CallFunction(calcsize, (char *)"s", format);
362
363                         if(ret) {
364                                 sizes[i]= PyLong_AsSsize_t(ret);
365                                 Py_DECREF(ret);
366                                 ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
367                         }
368
369                         if(ret == NULL) {
370                                 printf("PyC_InlineRun error, line:%d\n", __LINE__);
371                                 PyErr_Print();
372                                 PyErr_Clear();
373
374                                 PyList_SET_ITEM(values, i, Py_None); /* hold user */
375                                 Py_INCREF(Py_None);
376
377                                 sizes[i]= 0;
378                         }
379                         else {
380                                 if(PyTuple_GET_SIZE(ret) == 1) {
381                                         /* convenience, convert single tuples into single values */
382                                         PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
383                                         Py_INCREF(tmp);
384                                         Py_DECREF(ret);
385                                         ret = tmp;
386                                 }
387
388                                 PyList_SET_ITEM(values, i, ret); /* hold user */
389                         }
390                 }
391                 va_end(vargs);
392                 
393                 /* set the value so we can access it */
394                 PyDict_SetItemString(py_dict, "values", values);
395
396                 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
397
398                 fclose(fp);
399
400                 if(py_result) {
401
402                         /* we could skip this but then only slice assignment would work
403                          * better not be so strict */
404                         values= PyDict_GetItemString(py_dict, "values");
405
406                         if(values && PyList_Check(values)) {
407
408                                 /* dont use the result */
409                                 Py_DECREF(py_result);
410                                 py_result= NULL;
411
412                                 /* now get the values back */
413                                 va_start(vargs, n);
414                                 for (i=0; i*2 <n; i++) {
415                                         char *format = va_arg(vargs, char *);
416                                         void *ptr = va_arg(vargs, void *);
417                                         
418                                         PyObject *item;
419                                         PyObject *item_new;
420                                         /* prepend the string formatting and remake the tuple */
421                                         item= PyList_GET_ITEM(values, i);
422                                         if(PyTuple_CheckExact(item)) {
423                                                 int ofs= PyTuple_GET_SIZE(item);
424                                                 item_new= PyTuple_New(ofs + 1);
425                                                 while(ofs--) {
426                                                         PyObject *member= PyTuple_GET_ITEM(item, ofs);
427                                                         PyTuple_SET_ITEM(item_new, ofs + 1, member);
428                                                         Py_INCREF(member);
429                                                 }
430
431                                                 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
432                                         }
433                                         else {
434                                                 item_new= Py_BuildValue("sO", format, item);
435                                         }
436
437                                         ret = PyObject_Call(pack, item_new, NULL);
438
439                                         if(ret) {
440                                                 /* copy the bytes back into memory */
441                                                 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
442                                                 Py_DECREF(ret);
443                                         }
444                                         else {
445                                                 printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
446                                                 PyC_ObSpit("failed converting:", item_new);
447                                                 PyErr_Print();
448                                                 PyErr_Clear();
449                                         }
450
451                                         Py_DECREF(item_new);
452                                 }
453                                 va_end(vargs);
454                         }
455                         else {
456                                 printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
457                         }
458                 }
459                 else {
460                         printf("PyC_InlineRun error line:%d\n", __LINE__);
461                         PyErr_Print();
462                         PyErr_Clear();
463                 }
464
465                 Py_DECREF(calcsize);
466                 Py_DECREF(pack);
467                 Py_DECREF(unpack);
468
469                 PyMem_FREE(sizes);
470
471                 PyGILState_Release(gilstate);
472         }
473 }