Committing patch "[#27676] Change window size/resolution in realtime" by me.
[blender-staging.git] / source / blender / python / generic / py_capi_utils.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/python/generic/py_capi_utils.c
22  *  \ingroup pygen
23  *
24  * Extend upon CPython's API, filling in some gaps, these functions use PyC_
25  * prefix to distinguish them apart from CPython.
26  *
27  * \note
28  * This module should only depend on CPython, however it currently uses
29  * BLI_string_utf8() for unicode conversion.
30  */
31
32
33 #include <Python.h>
34 #include <frameobject.h>
35
36 #include "py_capi_utils.h"
37
38 #include "BLI_string_utf8.h" /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */
39
40 #ifdef _WIN32 /* BLI_setenv */
41 #include "BLI_path_util.h"
42 #endif
43
44 /* array utility function */
45 int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix)
46 {
47         PyObject *value_fast;
48         int value_len;
49         int i;
50
51         if (!(value_fast=PySequence_Fast(value, error_prefix))) {
52                 return -1;
53         }
54
55         value_len= PySequence_Fast_GET_SIZE(value_fast);
56
57         if (value_len != length) {
58                 Py_DECREF(value);
59                 PyErr_Format(PyExc_TypeError,
60                              "%.200s: invalid sequence length. expected %d, got %d",
61                              error_prefix, length, value_len);
62                 return -1;
63         }
64
65         /* for each type */
66         if (type == &PyFloat_Type) {
67                 if (is_double) {
68                         double *array_double= array;
69                         for (i=0; i<length; i++) {
70                                 array_double[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
71                         }
72                 }
73                 else {
74                         float *array_float= array;
75                         for (i=0; i<length; i++) {
76                                 array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
77                         }
78                 }
79         }
80         else if (type == &PyLong_Type) {
81                 /* could use is_double for 'long int' but no use now */
82                 int *array_int= array;
83                 for (i=0; i<length; i++) {
84                         array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
85                 }
86         }
87         else if (type == &PyBool_Type) {
88                 int *array_bool= array;
89                 for (i=0; i<length; i++) {
90                         array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
91                 }
92         }
93         else {
94                 Py_DECREF(value_fast);
95                 PyErr_Format(PyExc_TypeError,
96                              "%s: internal error %s is invalid",
97                              error_prefix, type->tp_name);
98                 return -1;
99         }
100
101         Py_DECREF(value_fast);
102
103         if (PyErr_Occurred()) {
104                 PyErr_Format(PyExc_TypeError,
105                              "%s: one or more items could not be used as a %s",
106                              error_prefix, type->tp_name);
107                 return -1;
108         }
109
110         return 0;
111 }
112
113
114 /* for debugging */
115 void PyC_ObSpit(const char *name, PyObject *var)
116 {
117         fprintf(stderr, "<%s> : ", name);
118         if (var==NULL) {
119                 fprintf(stderr, "<NIL>");
120         }
121         else {
122                 PyObject_Print(var, stderr, 0);
123                 fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
124                 fprintf(stderr, " ptr:%p", (void *)var);
125                 
126                 fprintf(stderr, " type:");
127                 if (Py_TYPE(var))
128                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
129                 else
130                         fprintf(stderr, "<NIL>");
131         }
132         fprintf(stderr, "\n");
133 }
134
135 void PyC_LineSpit(void)
136 {
137
138         const char *filename;
139         int lineno;
140
141         /* Note, allow calling from outside python (RNA) */
142         if (!PYC_INTERPRETER_ACTIVE) {
143                 fprintf(stderr, "python line lookup failed, interpreter inactive\n");
144                 return;
145         }
146
147         PyErr_Clear();
148         PyC_FileAndNum(&filename, &lineno);
149         
150         fprintf(stderr, "%s:%d\n", filename, lineno);
151 }
152
153 void PyC_FileAndNum(const char **filename, int *lineno)
154 {
155         PyFrameObject *frame;
156         
157         if (filename)   *filename= NULL;
158         if (lineno)             *lineno = -1;
159
160         if (!(frame= PyThreadState_GET()->frame)) {
161                 return;
162         }
163
164         /* when executing a script */
165         if (filename) {
166                 *filename = _PyUnicode_AsString(frame->f_code->co_filename);
167         }
168
169         /* when executing a module */
170         if (filename && *filename == NULL) {
171                 /* try an alternative method to get the filename - module based
172                  * references below are all borrowed (double checked) */
173                 PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
174                 if (mod_name) {
175                         PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
176                         if (mod) {
177                                 *filename= PyModule_GetFilename(mod);
178                         }
179
180                         /* unlikely, fallback */
181                         if (*filename == NULL) {
182                                 *filename= _PyUnicode_AsString(mod_name);
183                         }
184                 }
185         }
186
187         if (lineno) {
188                 *lineno = PyFrame_GetLineNumber(frame);
189         }
190 }
191
192 void PyC_FileAndNum_Safe(const char **filename, int *lineno)
193 {
194         if (!PYC_INTERPRETER_ACTIVE) {
195                 return;
196         }
197
198         PyC_FileAndNum(filename, lineno);
199 }
200
201 /* Would be nice if python had this built in */
202 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
203 {
204         Py_ssize_t i;
205         PyObject *item= o;
206         char *attr;
207         
208         va_list vargs;
209
210         va_start(vargs, n);
211         for (i=0; i<n; i++) {
212                 attr = va_arg(vargs, char *);
213                 item = PyObject_GetAttrString(item, attr);
214                 
215                 if (item) 
216                         Py_DECREF(item);
217                 else /* python will set the error value here */
218                         break;
219                 
220         }
221         va_end(vargs);
222         
223         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
224         return item;
225 }
226
227 /* similar to PyErr_Format(),
228  *
229  * implimentation - we cant actually preprend the existing exception,
230  * because it could have _any_ argiments given to it, so instead we get its
231  * __str__ output and raise our own exception including it.
232  */
233 PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
234 {
235         PyObject *error_value_prefix;
236         va_list args;
237
238         va_start(args, format);
239         error_value_prefix= PyUnicode_FromFormatV(format, args); /* can fail and be NULL */
240         va_end(args);
241
242         if (PyErr_Occurred()) {
243                 PyObject *error_type, *error_value, *error_traceback;
244                 PyErr_Fetch(&error_type, &error_value, &error_traceback);
245                 PyErr_Format(exception_type_prefix,
246                              "%S, %.200s(%S)",
247                              error_value_prefix,
248                              Py_TYPE(error_value)->tp_name,
249                              error_value
250                              );
251         }
252         else {
253                 PyErr_SetObject(exception_type_prefix,
254                                 error_value_prefix
255                                 );
256         }
257
258         Py_XDECREF(error_value_prefix);
259
260         /* dumb to always return NULL but matches PyErr_Format */
261         return NULL;
262 }
263
264
265 /* returns the exception string as a new PyUnicode object, depends on external traceback module */
266 #if 0
267
268 /* this version uses traceback module but somehow fails on UI errors */
269
270 PyObject *PyC_ExceptionBuffer(void)
271 {
272         PyObject *traceback_mod= NULL;
273         PyObject *format_tb_func= NULL;
274         PyObject *ret= NULL;
275
276         if (! (traceback_mod= PyImport_ImportModule("traceback")) ) {
277                 goto error_cleanup;
278         }
279         else if (! (format_tb_func= PyObject_GetAttrString(traceback_mod, "format_exc"))) {
280                 goto error_cleanup;
281         }
282
283         ret= PyObject_CallObject(format_tb_func, NULL);
284
285         if (ret == Py_None) {
286                 Py_DECREF(ret);
287                 ret= NULL;
288         }
289
290 error_cleanup:
291         /* could not import the module so print the error and close */
292         Py_XDECREF(traceback_mod);
293         Py_XDECREF(format_tb_func);
294
295         return ret;
296 }
297 #else /* verbose, non-threadsafe version */
298 PyObject *PyC_ExceptionBuffer(void)
299 {
300         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
301         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
302         PyObject *string_io = NULL;
303         PyObject *string_io_buf = NULL;
304         PyObject *string_io_mod= NULL;
305         PyObject *string_io_getvalue= NULL;
306
307         PyObject *error_type, *error_value, *error_traceback;
308
309         if (!PyErr_Occurred())
310                 return NULL;
311
312         PyErr_Fetch(&error_type, &error_value, &error_traceback);
313
314         PyErr_Clear();
315
316         /* import io
317          * string_io = io.StringIO()
318          */
319
320         if (! (string_io_mod= PyImport_ImportModule("io")) ) {
321                 goto error_cleanup;
322         }
323         else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
324                 goto error_cleanup;
325         }
326         else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
327                 goto error_cleanup;
328         }
329
330         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
331         Py_INCREF(stderr_backup);
332
333         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
334         PySys_SetObject("stderr", string_io);
335
336         PyErr_Restore(error_type, error_value, error_traceback);
337         PyErr_Print(); /* print the error */
338         PyErr_Clear();
339
340         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
341
342         PySys_SetObject("stdout", stdout_backup);
343         PySys_SetObject("stderr", stderr_backup);
344
345         Py_DECREF(stdout_backup); /* now sys owns the ref again */
346         Py_DECREF(stderr_backup);
347
348         Py_DECREF(string_io_mod);
349         Py_DECREF(string_io_getvalue);
350         Py_DECREF(string_io); /* free the original reference */
351
352         PyErr_Clear();
353         return string_io_buf;
354
355
356 error_cleanup:
357         /* could not import the module so print the error and close */
358         Py_XDECREF(string_io_mod);
359         Py_XDECREF(string_io);
360
361         PyErr_Restore(error_type, error_value, error_traceback);
362         PyErr_Print(); /* print the error */
363         PyErr_Clear();
364
365         return NULL;
366 }
367 #endif
368
369
370 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
371 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
372 {
373         const char *result;
374
375         result= _PyUnicode_AsString(py_str);
376
377         if (result) {
378                 /* 99% of the time this is enough but we better support non unicode
379                  * chars since blender doesnt limit this */
380                 return result;
381         }
382         else {
383                 PyErr_Clear();
384
385                 if (PyBytes_Check(py_str)) {
386                         return PyBytes_AS_STRING(py_str);
387                 }
388                 else if ((*coerce= PyUnicode_EncodeFSDefault(py_str))) {
389                         return PyBytes_AS_STRING(*coerce);
390                 }
391                 else {
392                         /* leave error raised from EncodeFS */
393                         return NULL;
394                 }
395         }
396 }
397
398 PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
399 {
400     PyObject *result= PyUnicode_FromStringAndSize(str, size);
401         if (result) {
402                 /* 99% of the time this is enough but we better support non unicode
403                  * chars since blender doesnt limit this */
404                 return result;
405         }
406         else {
407                 PyErr_Clear();
408                 /* this means paths will always be accessible once converted, on all OS's */
409                 result= PyUnicode_DecodeFSDefaultAndSize(str, size);
410                 return result;
411         }
412 }
413
414 PyObject *PyC_UnicodeFromByte(const char *str)
415 {
416         return PyC_UnicodeFromByteAndSize(str, strlen(str));
417 }
418
419 /*****************************************************************************
420 * Description: This function creates a new Python dictionary object.
421 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
422 * note: important we use the dict from __main__, this is what python expects
423   for 'pickle' to work as well as strings like this...
424  >> foo = 10
425  >> print(__import__("__main__").foo)
426 *
427 * note: this overwrites __main__ which gives problems with nested calles.
428 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
429 * any chance that python is in the call stack.
430 *****************************************************************************/
431 PyObject *PyC_DefaultNameSpace(const char *filename)
432 {
433         PyInterpreterState *interp= PyThreadState_GET()->interp;
434         PyObject *mod_main= PyModule_New("__main__");   
435         PyDict_SetItemString(interp->modules, "__main__", mod_main);
436         Py_DECREF(mod_main); /* sys.modules owns now */
437         PyModule_AddStringConstant(mod_main, "__name__", "__main__");
438         if (filename)
439                 PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
440         PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
441         Py_INCREF(interp->builtins); /* AddObject steals a reference */
442         return PyModule_GetDict(mod_main);
443 }
444
445 /* restore MUST be called after this */
446 void PyC_MainModule_Backup(PyObject **main_mod)
447 {
448         PyInterpreterState *interp= PyThreadState_GET()->interp;
449         *main_mod= PyDict_GetItemString(interp->modules, "__main__");
450         Py_XINCREF(*main_mod); /* dont free */
451 }
452
453 void PyC_MainModule_Restore(PyObject *main_mod)
454 {
455         PyInterpreterState *interp= PyThreadState_GET()->interp;
456         PyDict_SetItemString(interp->modules, "__main__", main_mod);
457         Py_XDECREF(main_mod);
458 }
459
460 /* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */
461 void PyC_SetHomePath(const char *py_path_bundle)
462 {
463         if (py_path_bundle==NULL) {
464                 /* Common enough to have bundled *nix python but complain on OSX/Win */
465 #if defined(__APPLE__) || defined(_WIN32)
466                 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");
467 #endif
468                 return;
469         }
470         /* set the environment path */
471         printf("found bundled python: %s\n", py_path_bundle);
472
473 #ifdef __APPLE__
474         /* OSX allow file/directory names to contain : character (represented as / in the Finder)
475          but current Python lib (release 3.1.1) doesn't handle these correctly */
476         if (strchr(py_path_bundle, ':'))
477                 printf("Warning : Blender application is located in a path containing : or / chars\
478                            \nThis may make python import function fail\n");
479 #endif
480
481 #ifdef _WIN32
482         /* cmake/MSVC debug build crashes without this, why only
483            in this case is unknown.. */
484         {
485                 BLI_setenv("PYTHONPATH", py_path_bundle);
486         }
487 #endif
488
489         {
490                 static wchar_t py_path_bundle_wchar[1024];
491
492                 /* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */
493                 /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
494
495                 BLI_strncpy_wchar_from_utf8(py_path_bundle_wchar, py_path_bundle, sizeof(py_path_bundle_wchar) / sizeof(wchar_t));
496
497                 Py_SetPythonHome(py_path_bundle_wchar);
498                 // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
499         }
500 }
501
502 /* Would be nice if python had this built in */
503 void PyC_RunQuicky(const char *filepath, int n, ...)
504 {
505         FILE *fp= fopen(filepath, "r");
506
507         if (fp) {
508                 PyGILState_STATE gilstate= PyGILState_Ensure();
509
510                 va_list vargs;  
511
512                 int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
513                 int i;
514
515                 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
516                 PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
517
518                 PyObject *py_result, *ret;
519
520                 PyObject *struct_mod= PyImport_ImportModule("struct");
521                 PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
522                 PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
523                 PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
524
525                 Py_DECREF(struct_mod);
526
527                 va_start(vargs, n);
528                 for (i=0; i * 2<n; i++) {
529                         char *format = va_arg(vargs, char *);
530                         void *ptr = va_arg(vargs, void *);
531
532                         ret= PyObject_CallFunction(calcsize, (char *)"s", format);
533
534                         if (ret) {
535                                 sizes[i]= PyLong_AsSsize_t(ret);
536                                 Py_DECREF(ret);
537                                 ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
538                         }
539
540                         if (ret == NULL) {
541                                 printf("PyC_InlineRun error, line:%d\n", __LINE__);
542                                 PyErr_Print();
543                                 PyErr_Clear();
544
545                                 PyList_SET_ITEM(values, i, Py_None); /* hold user */
546                                 Py_INCREF(Py_None);
547
548                                 sizes[i]= 0;
549                         }
550                         else {
551                                 if (PyTuple_GET_SIZE(ret) == 1) {
552                                         /* convenience, convert single tuples into single values */
553                                         PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
554                                         Py_INCREF(tmp);
555                                         Py_DECREF(ret);
556                                         ret = tmp;
557                                 }
558
559                                 PyList_SET_ITEM(values, i, ret); /* hold user */
560                         }
561                 }
562                 va_end(vargs);
563                 
564                 /* set the value so we can access it */
565                 PyDict_SetItemString(py_dict, "values", values);
566
567                 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
568
569                 fclose(fp);
570
571                 if (py_result) {
572
573                         /* we could skip this but then only slice assignment would work
574                          * better not be so strict */
575                         values= PyDict_GetItemString(py_dict, "values");
576
577                         if (values && PyList_Check(values)) {
578
579                                 /* dont use the result */
580                                 Py_DECREF(py_result);
581                                 py_result= NULL;
582
583                                 /* now get the values back */
584                                 va_start(vargs, n);
585                                 for (i=0; i*2 <n; i++) {
586                                         char *format = va_arg(vargs, char *);
587                                         void *ptr = va_arg(vargs, void *);
588                                         
589                                         PyObject *item;
590                                         PyObject *item_new;
591                                         /* prepend the string formatting and remake the tuple */
592                                         item= PyList_GET_ITEM(values, i);
593                                         if (PyTuple_CheckExact(item)) {
594                                                 int ofs= PyTuple_GET_SIZE(item);
595                                                 item_new= PyTuple_New(ofs + 1);
596                                                 while (ofs--) {
597                                                         PyObject *member= PyTuple_GET_ITEM(item, ofs);
598                                                         PyTuple_SET_ITEM(item_new, ofs + 1, member);
599                                                         Py_INCREF(member);
600                                                 }
601
602                                                 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
603                                         }
604                                         else {
605                                                 item_new= Py_BuildValue("sO", format, item);
606                                         }
607
608                                         ret = PyObject_Call(pack, item_new, NULL);
609
610                                         if (ret) {
611                                                 /* copy the bytes back into memory */
612                                                 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
613                                                 Py_DECREF(ret);
614                                         }
615                                         else {
616                                                 printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
617                                                 PyC_ObSpit("failed converting:", item_new);
618                                                 PyErr_Print();
619                                                 PyErr_Clear();
620                                         }
621
622                                         Py_DECREF(item_new);
623                                 }
624                                 va_end(vargs);
625                         }
626                         else {
627                                 printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
628                         }
629                 }
630                 else {
631                         printf("PyC_InlineRun error line:%d\n", __LINE__);
632                         PyErr_Print();
633                         PyErr_Clear();
634                 }
635
636                 Py_DECREF(calcsize);
637                 Py_DECREF(pack);
638                 Py_DECREF(unpack);
639
640                 PyMem_FREE(sizes);
641
642                 PyGILState_Release(gilstate);
643         }
644 }