Blender  V3.3
py_capi_utils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
14 /* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
15 #define PY_SSIZE_T_CLEAN
16 
17 #include <Python.h>
18 #include <frameobject.h>
19 
20 #include "BLI_utildefines.h" /* for bool */
21 
22 #include "py_capi_utils.h"
23 
24 #include "python_utildefines.h"
25 
26 #ifndef MATH_STANDALONE
27 # include "MEM_guardedalloc.h"
28 
29 # include "BLI_string.h"
30 
31 /* Only for BLI_strncpy_wchar_from_utf8,
32  * should replace with py funcs but too late in release now. */
33 # include "BLI_string_utf8.h"
34 #endif
35 
36 #ifdef _WIN32
37 # include "BLI_math_base.h" /* isfinite() */
38 #endif
39 
40 /* -------------------------------------------------------------------- */
44 /* array utility function */
46  const size_t array_item_size,
47  PyObject *value_fast,
48  const Py_ssize_t length,
49  const PyTypeObject *type,
50  const char *error_prefix)
51 {
52  const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
53  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
54  Py_ssize_t i;
55 
56  BLI_assert(PyList_Check(value_fast) || PyTuple_Check(value_fast));
57 
58  if (value_len != length) {
59  PyErr_Format(PyExc_TypeError,
60  "%.200s: invalid sequence length. expected %d, got %d",
61  error_prefix,
62  length,
63  value_len);
64  return -1;
65  }
66 
67  /* for each type */
68  if (type == &PyFloat_Type) {
69  switch (array_item_size) {
70  case sizeof(double): {
71  double *array_double = array;
72  for (i = 0; i < length; i++) {
73  array_double[i] = PyFloat_AsDouble(value_fast_items[i]);
74  }
75  break;
76  }
77  case sizeof(float): {
78  float *array_float = array;
79  for (i = 0; i < length; i++) {
80  array_float[i] = PyFloat_AsDouble(value_fast_items[i]);
81  }
82  break;
83  }
84  default: {
85  /* Internal error. */
87  }
88  }
89  }
90  else if (type == &PyLong_Type) {
91  switch (array_item_size) {
92  case sizeof(int64_t): {
93  int64_t *array_int = array;
94  for (i = 0; i < length; i++) {
95  array_int[i] = PyC_Long_AsI64(value_fast_items[i]);
96  }
97  break;
98  }
99  case sizeof(int32_t): {
100  int32_t *array_int = array;
101  for (i = 0; i < length; i++) {
102  array_int[i] = PyC_Long_AsI32(value_fast_items[i]);
103  }
104  break;
105  }
106  case sizeof(int16_t): {
107  int16_t *array_int = array;
108  for (i = 0; i < length; i++) {
109  array_int[i] = PyC_Long_AsI16(value_fast_items[i]);
110  }
111  break;
112  }
113  case sizeof(int8_t): {
114  int8_t *array_int = array;
115  for (i = 0; i < length; i++) {
116  array_int[i] = PyC_Long_AsI8(value_fast_items[i]);
117  }
118  break;
119  }
120  default: {
121  /* Internal error. */
123  }
124  }
125  }
126  else if (type == &PyBool_Type) {
127  switch (array_item_size) {
128  case sizeof(int64_t): {
129  int64_t *array_bool = array;
130  for (i = 0; i < length; i++) {
131  array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
132  }
133  break;
134  }
135  case sizeof(int32_t): {
136  int32_t *array_bool = array;
137  for (i = 0; i < length; i++) {
138  array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
139  }
140  break;
141  }
142  case sizeof(int16_t): {
143  int16_t *array_bool = array;
144  for (i = 0; i < length; i++) {
145  array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
146  }
147  break;
148  }
149  case sizeof(int8_t): {
150  int8_t *array_bool = array;
151  for (i = 0; i < length; i++) {
152  array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
153  }
154  break;
155  }
156  default: {
157  /* Internal error. */
159  }
160  }
161  }
162  else {
163  PyErr_Format(PyExc_TypeError, "%s: internal error %s is invalid", error_prefix, type->tp_name);
164  return -1;
165  }
166 
167  if (PyErr_Occurred()) {
168  PyErr_Format(PyExc_TypeError,
169  "%s: one or more items could not be used as a %s",
170  error_prefix,
171  type->tp_name);
172  return -1;
173  }
174 
175  return 0;
176 }
177 
178 int PyC_AsArray(void *array,
179  const size_t array_item_size,
180  PyObject *value,
181  const Py_ssize_t length,
182  const PyTypeObject *type,
183  const char *error_prefix)
184 {
185  PyObject *value_fast;
186  int ret;
187 
188  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
189  return -1;
190  }
191 
192  ret = PyC_AsArray_FAST(array, array_item_size, value_fast, length, type, error_prefix);
193  Py_DECREF(value_fast);
194  return ret;
195 }
196 
197 static int PyC_AsArray_Multi_impl(void **array_p,
198  const size_t array_item_size,
199  PyObject *value,
200  const int *dims,
201  const int dims_len,
202  const PyTypeObject *type,
203  const char *error_prefix);
204 
205 static int PyC_AsArray_Multi_FAST_impl(void **array_p,
206  const size_t array_item_size,
207  PyObject *value_fast,
208  const int *dims,
209  const int dims_len,
210  const PyTypeObject *type,
211  const char *error_prefix)
212 {
213  const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
214  const int length = dims[0];
215 
216  if (dims_len == 1) {
217  if (PyC_AsArray_FAST(*array_p, array_item_size, value_fast, length, type, error_prefix) ==
218  -1) {
219  return -1;
220  }
221  *array_p = POINTER_OFFSET(*array_p, array_item_size * length);
222  }
223  else {
224  if (value_len != length) {
225  PyErr_Format(PyExc_TypeError,
226  "%.200s: invalid sequence length. expected %d, got %d",
227  error_prefix,
228  length,
229  value_len);
230  return -1;
231  }
232 
233  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
234  const int *dims_next = dims + 1;
235  const int dims_next_len = dims_len - 1;
236 
237  for (int i = 0; i < length; i++) {
238  if (PyC_AsArray_Multi_impl(array_p,
239  array_item_size,
240  value_fast_items[i],
241  dims_next,
242  dims_next_len,
243  type,
244  error_prefix) == -1) {
245  return -1;
246  }
247  }
248  }
249  return 0;
250 }
251 
252 static int PyC_AsArray_Multi_impl(void **array_p,
253  const size_t array_item_size,
254  PyObject *value,
255  const int *dims,
256  const int dims_len,
257  const PyTypeObject *type,
258  const char *error_prefix)
259 {
260  PyObject *value_fast;
261  int ret;
262 
263  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
264  return -1;
265  }
266 
268  array_p, array_item_size, value_fast, dims, dims_len, type, error_prefix);
269  Py_DECREF(value_fast);
270  return ret;
271 }
272 
274  const size_t array_item_size,
275  PyObject *value_fast,
276  const int *dims,
277  const int dims_len,
278  const PyTypeObject *type,
279  const char *error_prefix)
280 {
282  &array, array_item_size, value_fast, dims, dims_len, type, error_prefix);
283 }
284 
286  const size_t array_item_size,
287  PyObject *value,
288  const int *dims,
289  const int dims_len,
290  const PyTypeObject *type,
291  const char *error_prefix)
292 {
293  return PyC_AsArray_Multi_impl(
294  &array, array_item_size, value, dims, dims_len, type, error_prefix);
295 }
296 
299 /* -------------------------------------------------------------------- */
305 /* array utility function */
306 PyObject *PyC_Tuple_PackArray_F32(const float *array, uint len)
307 {
308  PyObject *tuple = PyTuple_New(len);
309  for (uint i = 0; i < len; i++) {
310  PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
311  }
312  return tuple;
313 }
314 
315 PyObject *PyC_Tuple_PackArray_F64(const double *array, uint len)
316 {
317  PyObject *tuple = PyTuple_New(len);
318  for (uint i = 0; i < len; i++) {
319  PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
320  }
321  return tuple;
322 }
323 
324 PyObject *PyC_Tuple_PackArray_I32(const int *array, uint len)
325 {
326  PyObject *tuple = PyTuple_New(len);
327  for (uint i = 0; i < len; i++) {
328  PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array[i]));
329  }
330  return tuple;
331 }
332 
334 {
335  PyObject *tuple = PyTuple_New(len);
336  for (uint i = 0; i < len; i++) {
337  PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
338  }
339  return tuple;
340 }
341 
342 PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
343 {
344  PyObject *tuple = PyTuple_New(len);
345  for (uint i = 0; i < len; i++) {
346  PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
347  }
348  return tuple;
349 }
350 
353 /* -------------------------------------------------------------------- */
357 static PyObject *PyC_Tuple_PackArray_Multi_F32_impl(const float **array_p,
358  const int dims[],
359  const int dims_len)
360 {
361  const int len = dims[0];
362  if (dims_len == 1) {
363  PyObject *tuple = PyC_Tuple_PackArray_F32(*array_p, len);
364  *array_p = (*array_p) + len;
365  return tuple;
366  }
367  PyObject *tuple = PyTuple_New(dims[0]);
368  const int *dims_next = dims + 1;
369  const int dims_next_len = dims_len - 1;
370  for (uint i = 0; i < len; i++) {
371  PyTuple_SET_ITEM(
372  tuple, i, PyC_Tuple_PackArray_Multi_F32_impl(array_p, dims_next, dims_next_len));
373  }
374  return tuple;
375 }
376 PyObject *PyC_Tuple_PackArray_Multi_F32(const float *array, const int dims[], const int dims_len)
377 {
378  return PyC_Tuple_PackArray_Multi_F32_impl(&array, dims, dims_len);
379 }
380 
381 static PyObject *PyC_Tuple_PackArray_Multi_F64_impl(const double **array_p,
382  const int dims[],
383  const int dims_len)
384 {
385  const int len = dims[0];
386  if (dims_len == 1) {
387  PyObject *tuple = PyC_Tuple_PackArray_F64(*array_p, len);
388  *array_p = (*array_p) + len;
389  return tuple;
390  }
391  PyObject *tuple = PyTuple_New(dims[0]);
392  const int *dims_next = dims + 1;
393  const int dims_next_len = dims_len - 1;
394  for (uint i = 0; i < len; i++) {
395  PyTuple_SET_ITEM(
396  tuple, i, PyC_Tuple_PackArray_Multi_F64_impl(array_p, dims_next, dims_next_len));
397  }
398  return tuple;
399 }
400 PyObject *PyC_Tuple_PackArray_Multi_F64(const double *array, const int dims[], const int dims_len)
401 {
402  return PyC_Tuple_PackArray_Multi_F64_impl(&array, dims, dims_len);
403 }
404 
405 static PyObject *PyC_Tuple_PackArray_Multi_I32_impl(const int **array_p,
406  const int dims[],
407  const int dims_len)
408 {
409  const int len = dims[0];
410  if (dims_len == 1) {
411  PyObject *tuple = PyC_Tuple_PackArray_I32(*array_p, len);
412  *array_p = (*array_p) + len;
413  return tuple;
414  }
415  PyObject *tuple = PyTuple_New(dims[0]);
416  const int *dims_next = dims + 1;
417  const int dims_next_len = dims_len - 1;
418  for (uint i = 0; i < len; i++) {
419  PyTuple_SET_ITEM(
420  tuple, i, PyC_Tuple_PackArray_Multi_I32_impl(array_p, dims_next, dims_next_len));
421  }
422  return tuple;
423 }
424 PyObject *PyC_Tuple_PackArray_Multi_I32(const int *array, const int dims[], const int dims_len)
425 {
426  return PyC_Tuple_PackArray_Multi_I32_impl(&array, dims, dims_len);
427 }
428 
429 static PyObject *PyC_Tuple_PackArray_Multi_Bool_impl(const bool **array_p,
430  const int dims[],
431  const int dims_len)
432 {
433  const int len = dims[0];
434  if (dims_len == 1) {
435  PyObject *tuple = PyC_Tuple_PackArray_Bool(*array_p, len);
436  *array_p = (*array_p) + len;
437  return tuple;
438  }
439  PyObject *tuple = PyTuple_New(dims[0]);
440  const int *dims_next = dims + 1;
441  const int dims_next_len = dims_len - 1;
442  for (uint i = 0; i < len; i++) {
443  PyTuple_SET_ITEM(
444  tuple, i, PyC_Tuple_PackArray_Multi_Bool_impl(array_p, dims_next, dims_next_len));
445  }
446  return tuple;
447 }
448 PyObject *PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], const int dims_len)
449 {
450  return PyC_Tuple_PackArray_Multi_Bool_impl(&array, dims, dims_len);
451 }
452 
455 /* -------------------------------------------------------------------- */
459 void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
460 {
461  const uint tot = PyTuple_GET_SIZE(tuple);
462  uint i;
463 
464  for (i = 0; i < tot; i++) {
465  PyTuple_SET_ITEM(tuple, i, value);
466  Py_INCREF(value);
467  }
468 }
469 
470 void PyC_List_Fill(PyObject *list, PyObject *value)
471 {
472  const uint tot = PyList_GET_SIZE(list);
473  uint i;
474 
475  for (i = 0; i < tot; i++) {
476  PyList_SET_ITEM(list, i, value);
477  Py_INCREF(value);
478  }
479 }
480 
483 /* -------------------------------------------------------------------- */
487 int PyC_ParseBool(PyObject *o, void *p)
488 {
489  bool *bool_p = p;
490  long value;
491  if (((value = PyLong_AsLong(o)) == -1) || !ELEM(value, 0, 1)) {
492  PyErr_Format(PyExc_ValueError, "expected a bool or int (0/1), got %s", Py_TYPE(o)->tp_name);
493  return 0;
494  }
495 
496  *bool_p = value ? true : false;
497  return 1;
498 }
499 
500 int PyC_ParseStringEnum(PyObject *o, void *p)
501 {
502  struct PyC_StringEnum *e = p;
503  const char *value = PyUnicode_AsUTF8(o);
504  if (value == NULL) {
505  PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
506  return 0;
507  }
508  int i;
509  for (i = 0; e->items[i].id; i++) {
510  if (STREQ(e->items[i].id, value)) {
511  e->value_found = e->items[i].value;
512  return 1;
513  }
514  }
515 
516  /* Set as a precaution. */
517  e->value_found = -1;
518 
519  PyObject *enum_items = PyTuple_New(i);
520  for (i = 0; e->items[i].id; i++) {
521  PyTuple_SET_ITEM(enum_items, i, PyUnicode_FromString(e->items[i].id));
522  }
523  PyErr_Format(PyExc_ValueError, "expected a string in %S, got '%s'", enum_items, value);
524  Py_DECREF(enum_items);
525  return 0;
526 }
527 
529  const int value)
530 {
531  for (int i = 0; items[i].id; i++) {
532  if (items[i].value == value) {
533  return items[i].id;
534  }
535  }
536  return NULL;
537 }
538 
539 /* Silly function, we don't use arg. just check its compatible with `__deepcopy__`. */
540 int PyC_CheckArgs_DeepCopy(PyObject *args)
541 {
542  PyObject *dummy_pydict;
543  return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
544 }
545 
548 #ifndef MATH_STANDALONE
549 
550 /* -------------------------------------------------------------------- */
556 /* for debugging */
557 void PyC_ObSpit(const char *name, PyObject *var)
558 {
559  const char *null_str = "<null>";
560  fprintf(stderr, "<%s> : ", name);
561  if (var == NULL) {
562  fprintf(stderr, "%s\n", null_str);
563  }
564  else {
565  PyObject_Print(var, stderr, 0);
566  const PyTypeObject *type = Py_TYPE(var);
567  fprintf(stderr,
568  " ref:%d, ptr:%p, type: %s\n",
569  (int)var->ob_refcnt,
570  (void *)var,
571  type ? type->tp_name : null_str);
572  }
573 }
574 
575 void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var)
576 {
577  /* No name, creator of string can manage that. */
578  const char *null_str = "<null>";
579  if (var == NULL) {
580  BLI_snprintf(result, result_len, "%s", null_str);
581  }
582  else {
583  const PyTypeObject *type = Py_TYPE(var);
584  PyObject *var_str = PyObject_Repr(var);
585  if (var_str == NULL) {
586  /* We could print error here,
587  * but this may be used for generating errors - so don't for now. */
588  PyErr_Clear();
589  }
591  result_len,
592  " ref=%d, ptr=%p, type=%s, value=%.200s",
593  (int)var->ob_refcnt,
594  (void *)var,
595  type ? type->tp_name : null_str,
596  var_str ? PyUnicode_AsUTF8(var_str) : "<error>");
597  if (var_str != NULL) {
598  Py_DECREF(var_str);
599  }
600  }
601 }
602 
603 void PyC_LineSpit(void)
604 {
605 
606  const char *filename;
607  int lineno;
608 
609  /* NOTE: allow calling from outside python (RNA). */
610  if (!PyC_IsInterpreterActive()) {
611  fprintf(stderr, "python line lookup failed, interpreter inactive\n");
612  return;
613  }
614 
615  PyErr_Clear();
616  PyC_FileAndNum(&filename, &lineno);
617 
618  fprintf(stderr, "%s:%d\n", filename, lineno);
619 }
620 
621 void PyC_StackSpit(void)
622 {
623  /* NOTE: allow calling from outside python (RNA). */
624  if (!PyC_IsInterpreterActive()) {
625  fprintf(stderr, "python line lookup failed, interpreter inactive\n");
626  return;
627  }
628 
629  /* lame but handy */
630  const PyGILState_STATE gilstate = PyGILState_Ensure();
631  PyRun_SimpleString("__import__('traceback').print_stack()");
632  PyGILState_Release(gilstate);
633 }
634 
637 /* -------------------------------------------------------------------- */
641 void PyC_FileAndNum(const char **r_filename, int *r_lineno)
642 {
643  PyFrameObject *frame;
644  PyCodeObject *code;
645 
646  if (r_filename) {
647  *r_filename = NULL;
648  }
649  if (r_lineno) {
650  *r_lineno = -1;
651  }
652 
653  if (!(frame = PyEval_GetFrame())) {
654  return;
655  }
656  if (!(code = PyFrame_GetCode(frame))) {
657  return;
658  }
659 
660  /* when executing a script */
661  if (r_filename) {
662  *r_filename = PyUnicode_AsUTF8(code->co_filename);
663  }
664 
665  /* when executing a module */
666  if (r_filename && *r_filename == NULL) {
667  /* try an alternative method to get the r_filename - module based
668  * references below are all borrowed (double checked) */
669  PyObject *mod_name = PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
670  if (mod_name) {
671  PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
672  if (mod) {
673  PyObject *mod_file = PyModule_GetFilenameObject(mod);
674  if (mod_file) {
675  *r_filename = PyUnicode_AsUTF8(mod_name);
676  Py_DECREF(mod_file);
677  }
678  else {
679  PyErr_Clear();
680  }
681  }
682 
683  /* unlikely, fallback */
684  if (*r_filename == NULL) {
685  *r_filename = PyUnicode_AsUTF8(mod_name);
686  }
687  }
688  }
689 
690  if (r_lineno) {
691  *r_lineno = PyFrame_GetLineNumber(frame);
692  }
693 }
694 
695 void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
696 {
697  if (!PyC_IsInterpreterActive()) {
698  return;
699  }
700 
701  PyC_FileAndNum(r_filename, r_lineno);
702 }
703 
706 /* -------------------------------------------------------------------- */
710 /* Would be nice if python had this built in */
711 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
712 {
713  Py_ssize_t i;
714  PyObject *item = o;
715  const char *attr;
716 
717  va_list vargs;
718 
719  va_start(vargs, n);
720  for (i = 0; i < n; i++) {
721  attr = va_arg(vargs, char *);
722  item = PyObject_GetAttrString(item, attr);
723 
724  if (item) {
725  Py_DECREF(item);
726  }
727  else {
728  /* python will set the error value here */
729  break;
730  }
731  }
732  va_end(vargs);
733 
734  Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
735  return item;
736 }
737 
740 /* -------------------------------------------------------------------- */
744 PyObject *PyC_FrozenSetFromStrings(const char **strings)
745 {
746  const char **str;
747  PyObject *ret;
748 
749  ret = PyFrozenSet_New(NULL);
750 
751  for (str = strings; *str; str++) {
752  PyObject *py_str = PyUnicode_FromString(*str);
753  PySet_Add(ret, py_str);
754  Py_DECREF(py_str);
755  }
756 
757  return ret;
758 }
759 
762 /* -------------------------------------------------------------------- */
766 PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
767 {
768  PyObject *error_value_prefix;
769  va_list args;
770 
771  va_start(args, format);
772  error_value_prefix = PyUnicode_FromFormatV(format, args); /* can fail and be NULL */
773  va_end(args);
774 
775  if (PyErr_Occurred()) {
776  PyObject *error_type, *error_value, *error_traceback;
777  PyErr_Fetch(&error_type, &error_value, &error_traceback);
778 
779  if (PyUnicode_Check(error_value)) {
780  PyErr_Format(exception_type_prefix, "%S, %S", error_value_prefix, error_value);
781  }
782  else {
783  PyErr_Format(exception_type_prefix,
784  "%S, %.200s(%S)",
785  error_value_prefix,
786  Py_TYPE(error_value)->tp_name,
787  error_value);
788  }
789  }
790  else {
791  PyErr_SetObject(exception_type_prefix, error_value_prefix);
792  }
793 
794  Py_XDECREF(error_value_prefix);
795 
796  /* dumb to always return NULL but matches PyErr_Format */
797  return NULL;
798 }
799 
800 PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str)
801 {
802  return PyC_Err_Format_Prefix(exception_type_prefix, "%s", str);
803 }
804 
805 void PyC_Err_PrintWithFunc(PyObject *py_func)
806 {
807  /* since we return to C code we can't leave the error */
808  PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
809  PyErr_Print();
810  PyErr_Clear();
811 
812  /* use py style error */
813  fprintf(stderr,
814  "File \"%s\", line %d, in %s\n",
815  PyUnicode_AsUTF8(f_code->co_filename),
816  f_code->co_firstlineno,
817  PyUnicode_AsUTF8(((PyFunctionObject *)py_func)->func_name));
818 }
819 
822 /* -------------------------------------------------------------------- */
826 static void pyc_exception_buffer_handle_system_exit(PyObject *error_type,
827  PyObject *error_value,
828  PyObject *error_traceback)
829 {
830  if (!PyErr_GivenExceptionMatches(error_type, PyExc_SystemExit)) {
831  return;
832  }
833  /* Inspecting, follow Python's logic in #_Py_HandleSystemExit & treat as a regular exception. */
834  if (_Py_GetConfig()->inspect) {
835  return;
836  }
837 
838  /* NOTE(@campbellbarton): A `SystemExit` exception will exit immediately (unless inspecting).
839  * So print the error and exit now. This is necessary as the call to #PyErr_Print exits,
840  * the temporary `sys.stderr` assignment causes the output to be suppressed, failing silently.
841  * Instead, restore the error and print it. If Python changes it's behavior and doesn't exit in
842  * the future - continue to create the exception buffer, see: T99966.
843  *
844  * Arguably accessing a `SystemExit` exception as a buffer should be supported without exiting.
845  * (by temporarily enabling inspection for example) however - it's not obvious exactly when this
846  * should be enabled and complicates the Python API by introducing different kinds of execution.
847  * Since the rule of thumb is for Blender's embedded Python to match stand-alone Python,
848  * favor exiting when a `SystemExit` is raised.
849  * Especially since this exception more likely to be used for background/batch-processing
850  * utilities where exiting immediately makes sense, the possibility of this being called
851  * indirectly from python-drivers or modal-operators is less of a concern. */
852  PyErr_Restore(error_type, error_value, error_traceback);
853  PyErr_Print();
854 }
855 
856 /* returns the exception string as a new PyUnicode object, depends on external traceback module */
857 # if 0
858 
859 /* this version uses traceback module but somehow fails on UI errors */
860 
861 PyObject *PyC_ExceptionBuffer(void)
862 {
863  PyObject *traceback_mod = NULL;
864  PyObject *format_tb_func = NULL;
865  PyObject *ret = NULL;
866 
867  if (!(traceback_mod = PyImport_ImportModule("traceback"))) {
868  goto error_cleanup;
869  }
870  else if (!(format_tb_func = PyObject_GetAttrString(traceback_mod, "format_exc"))) {
871  goto error_cleanup;
872  }
873 
874  ret = PyObject_CallObject(format_tb_func, NULL);
875 
876  if (ret == Py_None) {
877  Py_DECREF(ret);
878  ret = NULL;
879  }
880 
881 error_cleanup:
882  /* could not import the module so print the error and close */
883  Py_XDECREF(traceback_mod);
884  Py_XDECREF(format_tb_func);
885 
886  return ret;
887 }
888 # else /* verbose, non-threadsafe version */
889 PyObject *PyC_ExceptionBuffer(void)
890 {
891  PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
892  PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
893  PyObject *string_io = NULL;
894  PyObject *string_io_buf = NULL;
895  PyObject *string_io_mod = NULL;
896  PyObject *string_io_getvalue = NULL;
897 
898  PyObject *error_type, *error_value, *error_traceback;
899 
900  if (!PyErr_Occurred()) {
901  return NULL;
902  }
903 
904  PyErr_Fetch(&error_type, &error_value, &error_traceback);
905 
906  pyc_exception_buffer_handle_system_exit(error_type, error_value, error_traceback);
907 
908  /* import io
909  * string_io = io.StringIO()
910  */
911 
912  if (!(string_io_mod = PyImport_ImportModule("io"))) {
913  goto error_cleanup;
914  }
915  else if (!(string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
916  goto error_cleanup;
917  }
918  else if (!(string_io_getvalue = PyObject_GetAttrString(string_io, "getvalue"))) {
919  goto error_cleanup;
920  }
921 
922  /* Since these were borrowed we don't want them freed when replaced. */
923  Py_INCREF(stdout_backup);
924  Py_INCREF(stderr_backup);
925 
926  /* Both of these are freed when restoring. */
927  PySys_SetObject("stdout", string_io);
928  PySys_SetObject("stderr", string_io);
929 
930  PyErr_Restore(error_type, error_value, error_traceback);
931  /* Printing clears (call #PyErr_Clear as well to ensure it's cleared). */
932  Py_XINCREF(error_type);
933  Py_XINCREF(error_value);
934  Py_XINCREF(error_traceback);
935  PyErr_Print(); /* print the error */
936  PyErr_Clear();
937 
938  string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
939 
940  PySys_SetObject("stdout", stdout_backup);
941  PySys_SetObject("stderr", stderr_backup);
942 
943  Py_DECREF(stdout_backup); /* now sys owns the ref again */
944  Py_DECREF(stderr_backup);
945 
946  Py_DECREF(string_io_mod);
947  Py_DECREF(string_io_getvalue);
948  Py_DECREF(string_io); /* free the original reference */
949 
950  PyErr_Restore(error_type, error_value, error_traceback);
951 
952  return string_io_buf;
953 
954 error_cleanup:
955  /* Could not import the module so print the error and close. */
956  Py_XDECREF(string_io_mod);
957  Py_XDECREF(string_io);
958 
959  PyErr_Restore(error_type, error_value, error_traceback);
960  PyErr_Print(); /* print the error */
961  PyErr_Restore(error_type, error_value, error_traceback);
962 
963  return NULL;
964 }
965 # endif
966 
968 {
969  if (!PyErr_Occurred()) {
970  return NULL;
971  }
972 
973  PyObject *string_io_buf = NULL;
974 
975  PyObject *error_type, *error_value, *error_traceback;
976 
977  PyErr_Fetch(&error_type, &error_value, &error_traceback);
978 
979  /* Since #PyErr_Print is not called it's not essential that `SystemExit` exceptions are handled.
980  * Do this to match the behavior of #PyC_ExceptionBuffer since requesting a brief exception
981  * shouldn't result in completely different behavior. */
982  pyc_exception_buffer_handle_system_exit(error_type, error_value, error_traceback);
983 
984  if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) {
985  /* Special exception for syntax errors,
986  * in these cases the full error is verbose and not very useful,
987  * just use the initial text so we know what the error is. */
988  if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) {
989  string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0));
990  }
991  }
992 
993  if (string_io_buf == NULL) {
994  string_io_buf = PyObject_Str(error_value);
995  }
996 
997  /* Python does this too */
998  if (UNLIKELY(string_io_buf == NULL)) {
999  string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name);
1000  }
1001 
1002  PyErr_Restore(error_type, error_value, error_traceback);
1003 
1004  return string_io_buf;
1005 }
1006 
1009 /* -------------------------------------------------------------------- */
1015 const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
1016 {
1017  const char *result;
1018 
1019  result = PyUnicode_AsUTF8AndSize(py_str, size);
1020 
1021  if (result) {
1022  /* 99% of the time this is enough but we better support non unicode
1023  * chars since blender doesn't limit this */
1024  return result;
1025  }
1026 
1027  PyErr_Clear();
1028 
1029  if (PyBytes_Check(py_str)) {
1030  *size = PyBytes_GET_SIZE(py_str);
1031  return PyBytes_AS_STRING(py_str);
1032  }
1033  if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
1034  *size = PyBytes_GET_SIZE(*coerce);
1035  return PyBytes_AS_STRING(*coerce);
1036  }
1037 
1038  /* leave error raised from EncodeFS */
1039  return NULL;
1040 }
1041 
1042 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
1043 {
1044  const char *result;
1045 
1046  result = PyUnicode_AsUTF8(py_str);
1047 
1048  if (result) {
1049  /* 99% of the time this is enough but we better support non unicode
1050  * chars since blender doesn't limit this. */
1051  return result;
1052  }
1053 
1054  PyErr_Clear();
1055 
1056  if (PyBytes_Check(py_str)) {
1057  return PyBytes_AS_STRING(py_str);
1058  }
1059  if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
1060  return PyBytes_AS_STRING(*coerce);
1061  }
1062 
1063  /* leave error raised from EncodeFS */
1064  return NULL;
1065 }
1066 
1067 PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
1068 {
1069  PyObject *result = PyUnicode_FromStringAndSize(str, size);
1070  if (result) {
1071  /* 99% of the time this is enough but we better support non unicode
1072  * chars since blender doesn't limit this */
1073  return result;
1074  }
1075 
1076  PyErr_Clear();
1077  /* this means paths will always be accessible once converted, on all OS's */
1078  result = PyUnicode_DecodeFSDefaultAndSize(str, size);
1079  return result;
1080 }
1081 
1082 PyObject *PyC_UnicodeFromByte(const char *str)
1083 {
1084  return PyC_UnicodeFromByteAndSize(str, strlen(str));
1085 }
1086 
1089 /* -------------------------------------------------------------------- */
1093 PyObject *PyC_DefaultNameSpace(const char *filename)
1094 {
1095  PyObject *modules = PyImport_GetModuleDict();
1096  PyObject *builtins = PyEval_GetBuiltins();
1097  PyObject *mod_main = PyModule_New("__main__");
1098  PyDict_SetItemString(modules, "__main__", mod_main);
1099  Py_DECREF(mod_main); /* sys.modules owns now */
1100  PyModule_AddStringConstant(mod_main, "__name__", "__main__");
1101  if (filename) {
1102  /* __file__ mainly for nice UI'ness
1103  * NOTE: this won't map to a real file when executing text-blocks and buttons. */
1104  PyModule_AddObject(mod_main, "__file__", PyC_UnicodeFromByte(filename));
1105  }
1106  PyModule_AddObject(mod_main, "__builtins__", builtins);
1107  Py_INCREF(builtins); /* AddObject steals a reference */
1108  return PyModule_GetDict(mod_main);
1109 }
1110 
1111 bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
1112 {
1113  for (int i = 0; imports[i]; i++) {
1114  PyObject *name = PyUnicode_FromString(imports[i]);
1115  PyObject *mod = PyImport_ImportModuleLevelObject(name, NULL, NULL, 0, 0);
1116  bool ok = false;
1117  if (mod) {
1118  PyDict_SetItem(py_dict, name, mod);
1119  ok = true;
1120  Py_DECREF(mod);
1121  }
1122  Py_DECREF(name);
1123 
1124  if (!ok) {
1125  return false;
1126  }
1127  }
1128  return true;
1129 }
1130 
1131 void PyC_MainModule_Backup(PyObject **r_main_mod)
1132 {
1133  PyObject *modules = PyImport_GetModuleDict();
1134  *r_main_mod = PyDict_GetItemString(modules, "__main__");
1135  Py_XINCREF(*r_main_mod); /* don't free */
1136 }
1137 
1138 void PyC_MainModule_Restore(PyObject *main_mod)
1139 {
1140  PyObject *modules = PyImport_GetModuleDict();
1141  PyDict_SetItemString(modules, "__main__", main_mod);
1142  Py_XDECREF(main_mod);
1143 }
1144 
1146 {
1147  /* instead of PyThreadState_Get, which calls Py_FatalError */
1148  return (PyThreadState_GetDict() != NULL);
1149 }
1150 
1153 /* -------------------------------------------------------------------- */
1157 /* Would be nice if python had this built in
1158  * See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
1159  */
1160 void PyC_RunQuicky(const char *filepath, int n, ...)
1161 {
1162  FILE *fp = fopen(filepath, "r");
1163 
1164  if (fp) {
1165  const PyGILState_STATE gilstate = PyGILState_Ensure();
1166 
1167  va_list vargs;
1168 
1169  Py_ssize_t *sizes = PyMem_MALLOC(sizeof(*sizes) * (n / 2));
1170  int i;
1171 
1172  PyObject *py_dict = PyC_DefaultNameSpace(filepath);
1173  PyObject *values = PyList_New(n / 2); /* namespace owns this, don't free */
1174 
1175  PyObject *py_result, *ret;
1176 
1177  PyObject *struct_mod = PyImport_ImportModule("struct");
1178  PyObject *calcsize = PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
1179  PyObject *pack = PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
1180  PyObject *unpack = PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
1181 
1182  Py_DECREF(struct_mod);
1183 
1184  va_start(vargs, n);
1185  for (i = 0; i * 2 < n; i++) {
1186  const char *format = va_arg(vargs, char *);
1187  void *ptr = va_arg(vargs, void *);
1188 
1189  ret = PyObject_CallFunction(calcsize, "s", format);
1190 
1191  if (ret) {
1192  sizes[i] = PyLong_AsLong(ret);
1193  Py_DECREF(ret);
1194  ret = PyObject_CallFunction(unpack, "sy#", format, (char *)ptr, sizes[i]);
1195  }
1196 
1197  if (ret == NULL) {
1198  printf("%s error, line:%d\n", __func__, __LINE__);
1199  PyErr_Print();
1200  PyErr_Clear();
1201 
1202  PyList_SET_ITEM(values, i, Py_INCREF_RET(Py_None)); /* hold user */
1203 
1204  sizes[i] = 0;
1205  }
1206  else {
1207  if (PyTuple_GET_SIZE(ret) == 1) {
1208  /* convenience, convert single tuples into single values */
1209  PyObject *tmp = PyTuple_GET_ITEM(ret, 0);
1210  Py_INCREF(tmp);
1211  Py_DECREF(ret);
1212  ret = tmp;
1213  }
1214 
1215  PyList_SET_ITEM(values, i, ret); /* hold user */
1216  }
1217  }
1218  va_end(vargs);
1219 
1220  /* set the value so we can access it */
1221  PyDict_SetItemString(py_dict, "values", values);
1222  Py_DECREF(values);
1223 
1224  py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
1225 
1226  fclose(fp);
1227 
1228  if (py_result) {
1229 
1230  /* we could skip this but then only slice assignment would work
1231  * better not be so strict */
1232  values = PyDict_GetItemString(py_dict, "values");
1233 
1234  if (values && PyList_Check(values)) {
1235 
1236  /* don't use the result */
1237  Py_DECREF(py_result);
1238  py_result = NULL;
1239 
1240  /* now get the values back */
1241  va_start(vargs, n);
1242  for (i = 0; i * 2 < n; i++) {
1243  const char *format = va_arg(vargs, char *);
1244  void *ptr = va_arg(vargs, void *);
1245 
1246  PyObject *item;
1247  PyObject *item_new;
1248  /* prepend the string formatting and remake the tuple */
1249  item = PyList_GET_ITEM(values, i);
1250  if (PyTuple_CheckExact(item)) {
1251  int ofs = PyTuple_GET_SIZE(item);
1252  item_new = PyTuple_New(ofs + 1);
1253  while (ofs--) {
1254  PyObject *member = PyTuple_GET_ITEM(item, ofs);
1255  PyTuple_SET_ITEM(item_new, ofs + 1, member);
1256  Py_INCREF(member);
1257  }
1258 
1259  PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
1260  }
1261  else {
1262  item_new = Py_BuildValue("sO", format, item);
1263  }
1264 
1265  ret = PyObject_Call(pack, item_new, NULL);
1266 
1267  if (ret) {
1268  /* copy the bytes back into memory */
1269  memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
1270  Py_DECREF(ret);
1271  }
1272  else {
1273  printf("%s error on arg '%d', line:%d\n", __func__, i, __LINE__);
1274  PyC_ObSpit("failed converting:", item_new);
1275  PyErr_Print();
1276  PyErr_Clear();
1277  }
1278 
1279  Py_DECREF(item_new);
1280  }
1281  va_end(vargs);
1282  }
1283  else {
1284  printf("%s error, 'values' not a list, line:%d\n", __func__, __LINE__);
1285  }
1286  }
1287  else {
1288  printf("%s error line:%d\n", __func__, __LINE__);
1289  PyErr_Print();
1290  PyErr_Clear();
1291  }
1292 
1293  Py_DECREF(calcsize);
1294  Py_DECREF(pack);
1295  Py_DECREF(unpack);
1296 
1297  PyMem_FREE(sizes);
1298 
1299  PyGILState_Release(gilstate);
1300  }
1301  else {
1302  fprintf(stderr, "%s: '%s' missing\n", __func__, filepath);
1303  }
1304 }
1305 
1306 /* generic function to avoid depending on RNA */
1307 void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
1308 {
1309  PyObject *as_pointer;
1310  PyObject *pointer;
1311 
1312  if (STREQ(Py_TYPE(value)->tp_name, type_name) &&
1313  (as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
1314  PyCallable_Check(as_pointer)) {
1315  void *result = NULL;
1316 
1317  /* must be a 'type_name' object */
1318  pointer = PyObject_CallObject(as_pointer, NULL);
1319  Py_DECREF(as_pointer);
1320 
1321  if (!pointer) {
1322  PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1323  return NULL;
1324  }
1325  result = PyLong_AsVoidPtr(pointer);
1326  Py_DECREF(pointer);
1327  if (!result) {
1328  PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1329  }
1330 
1331  return result;
1332  }
1333 
1334  PyErr_Format(PyExc_TypeError,
1335  "expected '%.200s' type found '%.200s' instead",
1336  type_name,
1337  Py_TYPE(value)->tp_name);
1338  return NULL;
1339 }
1340 
1343 /* -------------------------------------------------------------------- */
1349 PyObject *PyC_FlagSet_AsString(const PyC_FlagSet *item)
1350 {
1351  PyObject *py_items = PyList_New(0);
1352  for (; item->identifier; item++) {
1353  PyList_APPEND(py_items, PyUnicode_FromString(item->identifier));
1354  }
1355  PyObject *py_string = PyObject_Repr(py_items);
1356  Py_DECREF(py_items);
1357  return py_string;
1358 }
1359 
1360 int PyC_FlagSet_ValueFromID_int(const PyC_FlagSet *item, const char *identifier, int *r_value)
1361 {
1362  for (; item->identifier; item++) {
1363  if (STREQ(item->identifier, identifier)) {
1364  *r_value = item->value;
1365  return 1;
1366  }
1367  }
1368 
1369  return 0;
1370 }
1371 
1373  const char *identifier,
1374  int *r_value,
1375  const char *error_prefix)
1376 {
1377  if (PyC_FlagSet_ValueFromID_int(item, identifier, r_value) == 0) {
1378  PyObject *enum_str = PyC_FlagSet_AsString(item);
1379  PyErr_Format(
1380  PyExc_ValueError, "%s: '%.200s' not found in (%U)", error_prefix, identifier, enum_str);
1381  Py_DECREF(enum_str);
1382  return -1;
1383  }
1384 
1385  return 0;
1386 }
1387 
1389  PyObject *value,
1390  int *r_value,
1391  const char *error_prefix)
1392 {
1393  /* set of enum items, concatenate all values with OR */
1394  int ret, flag = 0;
1395 
1396  /* set looping */
1397  Py_ssize_t pos = 0;
1398  Py_ssize_t hash = 0;
1399  PyObject *key;
1400 
1401  if (!PySet_Check(value)) {
1402  PyErr_Format(PyExc_TypeError,
1403  "%.200s expected a set, not %.200s",
1404  error_prefix,
1405  Py_TYPE(value)->tp_name);
1406  return -1;
1407  }
1408 
1409  *r_value = 0;
1410 
1411  while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1412  const char *param = PyUnicode_AsUTF8(key);
1413 
1414  if (param == NULL) {
1415  PyErr_Format(PyExc_TypeError,
1416  "%.200s set must contain strings, not %.200s",
1417  error_prefix,
1418  Py_TYPE(key)->tp_name);
1419  return -1;
1420  }
1421 
1422  if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) {
1423  return -1;
1424  }
1425 
1426  flag |= ret;
1427  }
1428 
1429  *r_value = flag;
1430  return 0;
1431 }
1432 
1434 {
1435  PyObject *ret = PySet_New(NULL);
1436  PyObject *pystr;
1437 
1438  for (; items->identifier; items++) {
1439  if (items->value & flag) {
1440  pystr = PyUnicode_FromString(items->identifier);
1441  PySet_Add(ret, pystr);
1442  Py_DECREF(pystr);
1443  }
1444  }
1445 
1446  return ret;
1447 }
1448 
1451 /* -------------------------------------------------------------------- */
1455 bool PyC_RunString_AsNumber(const char *imports[],
1456  const char *expr,
1457  const char *filename,
1458  double *r_value)
1459 {
1460  PyObject *py_dict, *mod, *retval;
1461  bool ok = true;
1462  PyObject *main_mod = NULL;
1463 
1464  PyC_MainModule_Backup(&main_mod);
1465 
1466  py_dict = PyC_DefaultNameSpace(filename);
1467 
1468  mod = PyImport_ImportModule("math");
1469  if (mod) {
1470  PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
1471  Py_DECREF(mod);
1472  }
1473  else { /* highly unlikely but possibly */
1474  PyErr_Print();
1475  PyErr_Clear();
1476  }
1477 
1478  if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1479  ok = false;
1480  }
1481  else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1482  ok = false;
1483  }
1484  else {
1485  double val;
1486 
1487  if (PyTuple_Check(retval)) {
1488  /* Users my have typed in 10km, 2m
1489  * add up all values */
1490  int i;
1491  val = 0.0;
1492 
1493  for (i = 0; i < PyTuple_GET_SIZE(retval); i++) {
1494  const double val_item = PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i));
1495  if (val_item == -1 && PyErr_Occurred()) {
1496  val = -1;
1497  break;
1498  }
1499  val += val_item;
1500  }
1501  }
1502  else {
1503  val = PyFloat_AsDouble(retval);
1504  }
1505  Py_DECREF(retval);
1506 
1507  if (val == -1 && PyErr_Occurred()) {
1508  ok = false;
1509  }
1510  else if (!isfinite(val)) {
1511  *r_value = 0.0;
1512  }
1513  else {
1514  *r_value = val;
1515  }
1516  }
1517 
1518  PyC_MainModule_Restore(main_mod);
1519 
1520  return ok;
1521 }
1522 
1523 bool PyC_RunString_AsIntPtr(const char *imports[],
1524  const char *expr,
1525  const char *filename,
1526  intptr_t *r_value)
1527 {
1528  PyObject *py_dict, *retval;
1529  bool ok = true;
1530  PyObject *main_mod = NULL;
1531 
1532  PyC_MainModule_Backup(&main_mod);
1533 
1534  py_dict = PyC_DefaultNameSpace(filename);
1535 
1536  if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1537  ok = false;
1538  }
1539  else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1540  ok = false;
1541  }
1542  else {
1543  intptr_t val;
1544 
1545  val = (intptr_t)PyLong_AsVoidPtr(retval);
1546  if (val == 0 && PyErr_Occurred()) {
1547  ok = false;
1548  }
1549  else {
1550  *r_value = val;
1551  }
1552 
1553  Py_DECREF(retval);
1554  }
1555 
1556  PyC_MainModule_Restore(main_mod);
1557 
1558  return ok;
1559 }
1560 
1561 bool PyC_RunString_AsStringAndSize(const char *imports[],
1562  const char *expr,
1563  const char *filename,
1564  char **r_value,
1565  size_t *r_value_size)
1566 {
1567  PyObject *py_dict, *retval;
1568  bool ok = true;
1569  PyObject *main_mod = NULL;
1570 
1571  PyC_MainModule_Backup(&main_mod);
1572 
1573  py_dict = PyC_DefaultNameSpace(filename);
1574 
1575  if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1576  ok = false;
1577  }
1578  else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1579  ok = false;
1580  }
1581  else {
1582  const char *val;
1583  Py_ssize_t val_len;
1584 
1585  val = PyUnicode_AsUTF8AndSize(retval, &val_len);
1586  if (val == NULL && PyErr_Occurred()) {
1587  ok = false;
1588  }
1589  else {
1590  char *val_alloc = MEM_mallocN(val_len + 1, __func__);
1591  memcpy(val_alloc, val, val_len + 1);
1592  *r_value = val_alloc;
1593  *r_value_size = val_len;
1594  }
1595 
1596  Py_DECREF(retval);
1597  }
1598 
1599  PyC_MainModule_Restore(main_mod);
1600 
1601  return ok;
1602 }
1603 
1604 bool PyC_RunString_AsString(const char *imports[],
1605  const char *expr,
1606  const char *filename,
1607  char **r_value)
1608 {
1609  size_t value_size;
1610  return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
1611 }
1612 
1615 #endif /* #ifndef MATH_STANDALONE */
1616 
1617 /* -------------------------------------------------------------------- */
1624 /* Compiler optimizes out redundant checks. */
1625 #ifdef __GNUC__
1626 # pragma warning(push)
1627 # pragma GCC diagnostic ignored "-Wtype-limits"
1628 #endif
1629 
1630 int PyC_Long_AsBool(PyObject *value)
1631 {
1632  const int test = _PyLong_AsInt(value);
1633  if (UNLIKELY(test == -1 && PyErr_Occurred())) {
1634  return -1;
1635  }
1636  if (UNLIKELY((uint)test > 1)) {
1637  PyErr_SetString(PyExc_TypeError, "Python number not a bool (0/1)");
1638  return -1;
1639  }
1640  return test;
1641 }
1642 
1643 int8_t PyC_Long_AsI8(PyObject *value)
1644 {
1645  const int test = _PyLong_AsInt(value);
1646  if (UNLIKELY(test == -1 && PyErr_Occurred())) {
1647  return -1;
1648  }
1649  if (UNLIKELY(test < INT8_MIN || test > INT8_MAX)) {
1650  PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int8");
1651  return -1;
1652  }
1653  return (int8_t)test;
1654 }
1655 
1656 int16_t PyC_Long_AsI16(PyObject *value)
1657 {
1658  const int test = _PyLong_AsInt(value);
1659  if (UNLIKELY(test == -1 && PyErr_Occurred())) {
1660  return -1;
1661  }
1662  if (UNLIKELY(test < INT16_MIN || test > INT16_MAX)) {
1663  PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int16");
1664  return -1;
1665  }
1666  return (int16_t)test;
1667 }
1668 
1669 /* Inlined in header:
1670  * PyC_Long_AsI32
1671  * PyC_Long_AsI64
1672  */
1673 
1674 uint8_t PyC_Long_AsU8(PyObject *value)
1675 {
1676  const ulong test = PyLong_AsUnsignedLong(value);
1677  if (UNLIKELY(test == (ulong)-1 && PyErr_Occurred())) {
1678  return (uint8_t)-1;
1679  }
1680  if (UNLIKELY(test > UINT8_MAX)) {
1681  PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint8");
1682  return (uint8_t)-1;
1683  }
1684  return (uint8_t)test;
1685 }
1686 
1687 uint16_t PyC_Long_AsU16(PyObject *value)
1688 {
1689  const ulong test = PyLong_AsUnsignedLong(value);
1690  if (UNLIKELY(test == (ulong)-1 && PyErr_Occurred())) {
1691  return (uint16_t)-1;
1692  }
1693  if (UNLIKELY(test > UINT16_MAX)) {
1694  PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint16");
1695  return (uint16_t)-1;
1696  }
1697  return (uint16_t)test;
1698 }
1699 
1700 uint32_t PyC_Long_AsU32(PyObject *value)
1701 {
1702  const ulong test = PyLong_AsUnsignedLong(value);
1703  if (UNLIKELY(test == (ulong)-1 && PyErr_Occurred())) {
1704  return (uint32_t)-1;
1705  }
1706  if (UNLIKELY(test > UINT32_MAX)) {
1707  PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint32");
1708  return (uint32_t)-1;
1709  }
1710  return (uint32_t)test;
1711 }
1712 
1713 /* Inlined in header:
1714  * PyC_Long_AsU64
1715  */
1716 
1717 #ifdef __GNUC__
1718 # pragma warning(pop)
1719 #endif
1720 
1723 /* -------------------------------------------------------------------- */
1727 char PyC_StructFmt_type_from_str(const char *typestr)
1728 {
1729  switch (typestr[0]) {
1730  case '!':
1731  case '<':
1732  case '=':
1733  case '>':
1734  case '@':
1735  return typestr[1];
1736  default:
1737  return typestr[0];
1738  }
1739 }
1740 
1742 {
1743  switch (format) {
1744  case 'f':
1745  case 'd':
1746  case 'e':
1747  return true;
1748  default:
1749  return false;
1750  }
1751 }
1752 
1754 {
1755  switch (format) {
1756  case 'i':
1757  case 'I':
1758  case 'l':
1759  case 'L':
1760  case 'h':
1761  case 'H':
1762  case 'b':
1763  case 'B':
1764  case 'q':
1765  case 'Q':
1766  case 'n':
1767  case 'N':
1768  case 'P':
1769  return true;
1770  default:
1771  return false;
1772  }
1773 }
1774 
1776 {
1777  switch (format) {
1778  case 'c':
1779  case 's':
1780  case 'p':
1781  return true;
1782  default:
1783  return false;
1784  }
1785 }
1786 
1788 {
1789  switch (format) {
1790  case '?':
1791  return true;
1792  default:
1793  return false;
1794  }
1795 }
1796 
typedef float(TangentPoint)[2]
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned long ulong
Definition: BLI_sys_types.h:69
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNLIKELY(x)
#define ELEM(...)
#define POINTER_OFFSET(v, ofs)
#define STREQ(a, b)
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
int len
Definition: draw_manager.c:108
#define str(s)
uint pos
format
Definition: logImageCore.h:38
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
bool isfinite(uchar)
Definition: scene/image.cpp:31
T length(const vec_base< T, Size > &a)
#define hash
Definition: noise.c:153
int16_t PyC_Long_AsI16(PyObject *value)
int PyC_AsArray_Multi_FAST(void *array, const size_t array_item_size, PyObject *value_fast, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
static PyObject * PyC_Tuple_PackArray_Multi_F32_impl(const float **array_p, const int dims[], const int dims_len)
char PyC_StructFmt_type_from_str(const char *typestr)
PyObject * PyC_DefaultNameSpace(const char *filename)
const char * PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
PyObject * PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
PyObject * PyC_FlagSet_AsString(const PyC_FlagSet *item)
static PyObject * PyC_Tuple_PackArray_Multi_Bool_impl(const bool **array_p, const int dims[], const int dims_len)
PyObject * PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], const int dims_len)
bool PyC_StructFmt_type_is_bool(char format)
uint8_t PyC_Long_AsU8(PyObject *value)
void PyC_ObSpit(const char *name, PyObject *var)
int8_t PyC_Long_AsI8(PyObject *value)
void PyC_RunQuicky(const char *filepath, int n,...)
bool PyC_RunString_AsString(const char *imports[], const char *expr, const char *filename, char **r_value)
PyObject * PyC_Tuple_PackArray_Bool(const bool *array, uint len)
PyObject * PyC_Tuple_PackArray_Multi_I32(const int *array, const int dims[], const int dims_len)
static void pyc_exception_buffer_handle_system_exit(PyObject *error_type, PyObject *error_value, PyObject *error_traceback)
static PyObject * PyC_Tuple_PackArray_Multi_F64_impl(const double **array_p, const int dims[], const int dims_len)
int PyC_CheckArgs_DeepCopy(PyObject *args)
static int PyC_AsArray_Multi_impl(void **array_p, const size_t array_item_size, PyObject *value, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
int PyC_FlagSet_ValueFromID(const PyC_FlagSet *item, const char *identifier, int *r_value, const char *error_prefix)
PyObject * PyC_Tuple_PackArray_I32FromBool(const int *array, uint len)
int PyC_ParseStringEnum(PyObject *o, void *p)
PyObject * PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
PyObject * PyC_Tuple_PackArray_Multi_F64(const double *array, const int dims[], const int dims_len)
PyObject * PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str)
bool PyC_StructFmt_type_is_int_any(char format)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
PyObject * PyC_Tuple_PackArray_Multi_F32(const float *array, const int dims[], const int dims_len)
PyObject * PyC_ExceptionBuffer(void)
int PyC_Long_AsBool(PyObject *value)
static PyObject * PyC_Tuple_PackArray_Multi_I32_impl(const int **array_p, const int dims[], const int dims_len)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format,...)
int PyC_FlagSet_ValueFromID_int(const PyC_FlagSet *item, const char *identifier, int *r_value)
PyObject * PyC_Tuple_PackArray_F32(const float *array, uint len)
const char * PyC_StringEnum_FindIDFromValue(const struct PyC_StringEnumItems *items, const int value)
bool PyC_RunString_AsNumber(const char *imports[], const char *expr, const char *filename, double *r_value)
bool PyC_StructFmt_type_is_byte(char format)
int PyC_FlagSet_ToBitfield(const PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix)
PyObject * PyC_ExceptionBuffer_Simple(void)
void PyC_StackSpit(void)
PyObject * PyC_Tuple_PackArray_I32(const int *array, uint len)
PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n,...)
int PyC_AsArray_Multi(void *array, const size_t array_item_size, PyObject *value, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
void PyC_MainModule_Backup(PyObject **r_main_mod)
bool PyC_RunString_AsStringAndSize(const char *imports[], const char *expr, const char *filename, char **r_value, size_t *r_value_size)
const char * PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
bool PyC_IsInterpreterActive(void)
uint32_t PyC_Long_AsU32(PyObject *value)
int PyC_AsArray_FAST(void *array, const size_t array_item_size, PyObject *value_fast, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
Definition: py_capi_utils.c:45
bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
void PyC_FileAndNum(const char **r_filename, int *r_lineno)
void PyC_List_Fill(PyObject *list, PyObject *value)
void PyC_LineSpit(void)
uint16_t PyC_Long_AsU16(PyObject *value)
void PyC_Err_PrintWithFunc(PyObject *py_func)
void PyC_MainModule_Restore(PyObject *main_mod)
PyObject * PyC_FrozenSetFromStrings(const char **strings)
PyObject * PyC_Tuple_PackArray_F64(const double *array, uint len)
PyObject * PyC_UnicodeFromByte(const char *str)
int PyC_ParseBool(PyObject *o, void *p)
static int PyC_AsArray_Multi_FAST_impl(void **array_p, const size_t array_item_size, PyObject *value_fast, const int *dims, const int dims_len, const PyTypeObject *type, const char *error_prefix)
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var)
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
bool PyC_StructFmt_type_is_float_any(char format)
bool PyC_RunString_AsIntPtr(const char *imports[], const char *expr, const char *filename, intptr_t *r_value)
header-only utilities
return ret
signed short int16_t
Definition: stdint.h:76
unsigned short uint16_t
Definition: stdint.h:79
#define UINT16_MAX
Definition: stdint.h:141
unsigned int uint32_t
Definition: stdint.h:80
__int64 int64_t
Definition: stdint.h:89
_W64 int intptr_t
Definition: stdint.h:118
#define INT8_MAX
Definition: stdint.h:133
signed int int32_t
Definition: stdint.h:77
#define UINT32_MAX
Definition: stdint.h:142
unsigned char uint8_t
Definition: stdint.h:78
#define INT16_MAX
Definition: stdint.h:135
#define UINT8_MAX
Definition: stdint.h:140
signed char int8_t
Definition: stdint.h:75
const char * identifier
const struct PyC_StringEnumItems * items
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490
PointerRNA * ptr
Definition: wm_files.c:3480