1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17 /** \file
18 * \ingroup pygen
19 *
20 * Extend upon CPython's API, filling in some gaps, these functions use PyC_
21 * prefix to distinguish them apart from CPython.
22 *
23 * \note
24 * This module should only depend on CPython, however it currently uses
25 * BLI_string_utf8() for unicode conversion.
26 */
27
28 /* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
29 #define PY_SSIZE_T_CLEAN
30
31 #include <Python.h>
32 #include <frameobject.h>
33
34 #include "BLI_utildefines.h" /* for bool */
35
36 #include "py_capi_utils.h"
37
38 #include "python_utildefines.h"
39
40 #ifndef MATH_STANDALONE
41 # include "MEM_guardedalloc.h"
42
43 # include "BLI_string.h"
44
45 /* Only for BLI_strncpy_wchar_from_utf8,
46 * should replace with py funcs but too late in release now. */
47 # include "BLI_string_utf8.h"
48 #endif
49
50 #ifdef _WIN32
51 # include "BLI_math_base.h" /* isfinite() */
52 #endif
53
54 /* -------------------------------------------------------------------- */
55 /** \name Fast Python to C Array Conversion for Primitive Types
56 * \{ */
57
58 /* array utility function */
PyC_AsArray_FAST(void * array,PyObject * value_fast,const Py_ssize_t length,const PyTypeObject * type,const bool is_double,const char * error_prefix)59 int PyC_AsArray_FAST(void *array,
60 PyObject *value_fast,
61 const Py_ssize_t length,
62 const PyTypeObject *type,
63 const bool is_double,
64 const char *error_prefix)
65 {
66 const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
67 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
68 Py_ssize_t i;
69
70 BLI_assert(PyList_Check(value_fast) || PyTuple_Check(value_fast));
71
72 if (value_len != length) {
73 PyErr_Format(PyExc_TypeError,
74 "%.200s: invalid sequence length. expected %d, got %d",
75 error_prefix,
76 length,
77 value_len);
78 return -1;
79 }
80
81 /* for each type */
82 if (type == &PyFloat_Type) {
83 if (is_double) {
84 double *array_double = array;
85 for (i = 0; i < length; i++) {
86 array_double[i] = PyFloat_AsDouble(value_fast_items[i]);
87 }
88 }
89 else {
90 float *array_float = array;
91 for (i = 0; i < length; i++) {
92 array_float[i] = PyFloat_AsDouble(value_fast_items[i]);
93 }
94 }
95 }
96 else if (type == &PyLong_Type) {
97 /* could use is_double for 'long int' but no use now */
98 int *array_int = array;
99 for (i = 0; i < length; i++) {
100 array_int[i] = PyC_Long_AsI32(value_fast_items[i]);
101 }
102 }
103 else if (type == &PyBool_Type) {
104 bool *array_bool = array;
105 for (i = 0; i < length; i++) {
106 array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
107 }
108 }
109 else {
110 PyErr_Format(PyExc_TypeError, "%s: internal error %s is invalid", error_prefix, type->tp_name);
111 return -1;
112 }
113
114 if (PyErr_Occurred()) {
115 PyErr_Format(PyExc_TypeError,
116 "%s: one or more items could not be used as a %s",
117 error_prefix,
118 type->tp_name);
119 return -1;
120 }
121
122 return 0;
123 }
124
PyC_AsArray(void * array,PyObject * value,const Py_ssize_t length,const PyTypeObject * type,const bool is_double,const char * error_prefix)125 int PyC_AsArray(void *array,
126 PyObject *value,
127 const Py_ssize_t length,
128 const PyTypeObject *type,
129 const bool is_double,
130 const char *error_prefix)
131 {
132 PyObject *value_fast;
133 int ret;
134
135 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
136 return -1;
137 }
138
139 ret = PyC_AsArray_FAST(array, value_fast, length, type, is_double, error_prefix);
140 Py_DECREF(value_fast);
141 return ret;
142 }
143
144 /** \} */
145
146 /* -------------------------------------------------------------------- */
147 /** \name Typed Tuple Packing
148 *
149 * \note See #PyC_Tuple_Pack_* macros that take multiple arguments.
150 * \{ */
151
152 /* array utility function */
PyC_Tuple_PackArray_F32(const float * array,uint len)153 PyObject *PyC_Tuple_PackArray_F32(const float *array, uint len)
154 {
155 PyObject *tuple = PyTuple_New(len);
156 for (uint i = 0; i < len; i++) {
157 PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
158 }
159 return tuple;
160 }
161
PyC_Tuple_PackArray_F64(const double * array,uint len)162 PyObject *PyC_Tuple_PackArray_F64(const double *array, uint len)
163 {
164 PyObject *tuple = PyTuple_New(len);
165 for (uint i = 0; i < len; i++) {
166 PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array[i]));
167 }
168 return tuple;
169 }
170
PyC_Tuple_PackArray_I32(const int * array,uint len)171 PyObject *PyC_Tuple_PackArray_I32(const int *array, uint len)
172 {
173 PyObject *tuple = PyTuple_New(len);
174 for (uint i = 0; i < len; i++) {
175 PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array[i]));
176 }
177 return tuple;
178 }
179
PyC_Tuple_PackArray_I32FromBool(const int * array,uint len)180 PyObject *PyC_Tuple_PackArray_I32FromBool(const int *array, uint len)
181 {
182 PyObject *tuple = PyTuple_New(len);
183 for (uint i = 0; i < len; i++) {
184 PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
185 }
186 return tuple;
187 }
188
PyC_Tuple_PackArray_Bool(const bool * array,uint len)189 PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
190 {
191 PyObject *tuple = PyTuple_New(len);
192 for (uint i = 0; i < len; i++) {
193 PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array[i]));
194 }
195 return tuple;
196 }
197
198 /** \} */
199
200 /* -------------------------------------------------------------------- */
201 /** \name Tuple/List Filling
202 * \{ */
203
204 /**
205 * Caller needs to ensure tuple is uninitialized.
206 * Handy for filling a tuple with None for eg.
207 */
PyC_Tuple_Fill(PyObject * tuple,PyObject * value)208 void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
209 {
210 const uint tot = PyTuple_GET_SIZE(tuple);
211 uint i;
212
213 for (i = 0; i < tot; i++) {
214 PyTuple_SET_ITEM(tuple, i, value);
215 Py_INCREF(value);
216 }
217 }
218
PyC_List_Fill(PyObject * list,PyObject * value)219 void PyC_List_Fill(PyObject *list, PyObject *value)
220 {
221 const uint tot = PyList_GET_SIZE(list);
222 uint i;
223
224 for (i = 0; i < tot; i++) {
225 PyList_SET_ITEM(list, i, value);
226 Py_INCREF(value);
227 }
228 }
229
230 /** \} */
231
232 /* -------------------------------------------------------------------- */
233 /** \name Bool/Enum Argument Parsing
234 * \{ */
235
236 /**
237 * Use with PyArg_ParseTuple's "O&" formatting.
238 *
239 * \see #PyC_Long_AsBool for a similar function to use outside of argument parsing.
240 */
PyC_ParseBool(PyObject * o,void * p)241 int PyC_ParseBool(PyObject *o, void *p)
242 {
243 bool *bool_p = p;
244 long value;
245 if (((value = PyLong_AsLong(o)) == -1) || !ELEM(value, 0, 1)) {
246 PyErr_Format(PyExc_ValueError, "expected a bool or int (0/1), got %s", Py_TYPE(o)->tp_name);
247 return 0;
248 }
249
250 *bool_p = value ? true : false;
251 return 1;
252 }
253
254 /**
255 * Use with PyArg_ParseTuple's "O&" formatting.
256 */
PyC_ParseStringEnum(PyObject * o,void * p)257 int PyC_ParseStringEnum(PyObject *o, void *p)
258 {
259 struct PyC_StringEnum *e = p;
260 const char *value = _PyUnicode_AsString(o);
261 if (value == NULL) {
262 PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
263 return 0;
264 }
265 int i;
266 for (i = 0; e->items[i].id; i++) {
267 if (STREQ(e->items[i].id, value)) {
268 e->value_found = e->items[i].value;
269 return 1;
270 }
271 }
272
273 /* Set as a precaution. */
274 e->value_found = -1;
275
276 PyObject *enum_items = PyTuple_New(i);
277 for (i = 0; e->items[i].id; i++) {
278 PyTuple_SET_ITEM(enum_items, i, PyUnicode_FromString(e->items[i].id));
279 }
280 PyErr_Format(PyExc_ValueError, "expected a string in %S, got '%s'", enum_items, value);
281 Py_DECREF(enum_items);
282 return 0;
283 }
284
285 /* silly function, we dont use arg. just check its compatible with __deepcopy__ */
PyC_CheckArgs_DeepCopy(PyObject * args)286 int PyC_CheckArgs_DeepCopy(PyObject *args)
287 {
288 PyObject *dummy_pydict;
289 return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
290 }
291
292 /** \} */
293
294 #ifndef MATH_STANDALONE
295
296 /* -------------------------------------------------------------------- */
297 /** \name Simple Printing (for debugging)
298 *
299 * These are useful to run directly from a debugger to be able to inspect the state.
300 * \{ */
301
302 /* for debugging */
PyC_ObSpit(const char * name,PyObject * var)303 void PyC_ObSpit(const char *name, PyObject *var)
304 {
305 const char *null_str = "<null>";
306 fprintf(stderr, "<%s> : ", name);
307 if (var == NULL) {
308 fprintf(stderr, "%s\n", null_str);
309 }
310 else {
311 PyObject_Print(var, stderr, 0);
312 const PyTypeObject *type = Py_TYPE(var);
313 fprintf(stderr,
314 " ref:%d, ptr:%p, type: %s\n",
315 (int)var->ob_refcnt,
316 (void *)var,
317 type ? type->tp_name : null_str);
318 }
319 }
320
321 /**
322 * A version of #PyC_ObSpit that writes into a string (and doesn't take a name argument).
323 * Use for logging.
324 */
PyC_ObSpitStr(char * result,size_t result_len,PyObject * var)325 void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var)
326 {
327 /* No name, creator of string can manage that. */
328 const char *null_str = "<null>";
329 if (var == NULL) {
330 BLI_snprintf(result, result_len, "%s", null_str);
331 }
332 else {
333 const PyTypeObject *type = Py_TYPE(var);
334 PyObject *var_str = PyObject_Repr(var);
335 if (var_str == NULL) {
336 /* We could print error here,
337 * but this may be used for generating errors - so don't for now. */
338 PyErr_Clear();
339 }
340 BLI_snprintf(result,
341 result_len,
342 " ref=%d, ptr=%p, type=%s, value=%.200s",
343 (int)var->ob_refcnt,
344 (void *)var,
345 type ? type->tp_name : null_str,
346 var_str ? _PyUnicode_AsString(var_str) : "<error>");
347 if (var_str != NULL) {
348 Py_DECREF(var_str);
349 }
350 }
351 }
352
PyC_LineSpit(void)353 void PyC_LineSpit(void)
354 {
355
356 const char *filename;
357 int lineno;
358
359 /* Note, allow calling from outside python (RNA) */
360 if (!PyC_IsInterpreterActive()) {
361 fprintf(stderr, "python line lookup failed, interpreter inactive\n");
362 return;
363 }
364
365 PyErr_Clear();
366 PyC_FileAndNum(&filename, &lineno);
367
368 fprintf(stderr, "%s:%d\n", filename, lineno);
369 }
370
PyC_StackSpit(void)371 void PyC_StackSpit(void)
372 {
373 /* Note, allow calling from outside python (RNA) */
374 if (!PyC_IsInterpreterActive()) {
375 fprintf(stderr, "python line lookup failed, interpreter inactive\n");
376 return;
377 }
378
379 /* lame but handy */
380 const PyGILState_STATE gilstate = PyGILState_Ensure();
381 PyRun_SimpleString("__import__('traceback').print_stack()");
382 PyGILState_Release(gilstate);
383 }
384
385 /** \} */
386
387 /* -------------------------------------------------------------------- */
388 /** \name Access Current Frame File Name & Line Number
389 * \{ */
390
PyC_FileAndNum(const char ** r_filename,int * r_lineno)391 void PyC_FileAndNum(const char **r_filename, int *r_lineno)
392 {
393 PyFrameObject *frame;
394
395 if (r_filename) {
396 *r_filename = NULL;
397 }
398 if (r_lineno) {
399 *r_lineno = -1;
400 }
401
402 if (!(frame = PyThreadState_GET()->frame)) {
403 return;
404 }
405
406 /* when executing a script */
407 if (r_filename) {
408 *r_filename = _PyUnicode_AsString(frame->f_code->co_filename);
409 }
410
411 /* when executing a module */
412 if (r_filename && *r_filename == NULL) {
413 /* try an alternative method to get the r_filename - module based
414 * references below are all borrowed (double checked) */
415 PyObject *mod_name = PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
416 if (mod_name) {
417 PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
418 if (mod) {
419 PyObject *mod_file = PyModule_GetFilenameObject(mod);
420 if (mod_file) {
421 *r_filename = _PyUnicode_AsString(mod_name);
422 Py_DECREF(mod_file);
423 }
424 else {
425 PyErr_Clear();
426 }
427 }
428
429 /* unlikely, fallback */
430 if (*r_filename == NULL) {
431 *r_filename = _PyUnicode_AsString(mod_name);
432 }
433 }
434 }
435
436 if (r_lineno) {
437 *r_lineno = PyFrame_GetLineNumber(frame);
438 }
439 }
440
PyC_FileAndNum_Safe(const char ** r_filename,int * r_lineno)441 void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
442 {
443 if (!PyC_IsInterpreterActive()) {
444 return;
445 }
446
447 PyC_FileAndNum(r_filename, r_lineno);
448 }
449
450 /** \} */
451
452 /* -------------------------------------------------------------------- */
453 /** \name Object Access Utilities
454 * \{ */
455
456 /* Would be nice if python had this built in */
PyC_Object_GetAttrStringArgs(PyObject * o,Py_ssize_t n,...)457 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
458 {
459 Py_ssize_t i;
460 PyObject *item = o;
461 const char *attr;
462
463 va_list vargs;
464
465 va_start(vargs, n);
466 for (i = 0; i < n; i++) {
467 attr = va_arg(vargs, char *);
468 item = PyObject_GetAttrString(item, attr);
469
470 if (item) {
471 Py_DECREF(item);
472 }
473 else {
474 /* python will set the error value here */
475 break;
476 }
477 }
478 va_end(vargs);
479
480 Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
481 return item;
482 }
483
484 /** \} */
485
486 /* -------------------------------------------------------------------- */
487 /** \name Frozen Set Creation
488 * \{ */
489
PyC_FrozenSetFromStrings(const char ** strings)490 PyObject *PyC_FrozenSetFromStrings(const char **strings)
491 {
492 const char **str;
493 PyObject *ret;
494
495 ret = PyFrozenSet_New(NULL);
496
497 for (str = strings; *str; str++) {
498 PyObject *py_str = PyUnicode_FromString(*str);
499 PySet_Add(ret, py_str);
500 Py_DECREF(py_str);
501 }
502
503 return ret;
504 }
505
506 /** \} */
507
508 /* -------------------------------------------------------------------- */
509 /** \name Exception Utilities
510 * \{ */
511
512 /**
513 * Similar to #PyErr_Format(),
514 *
515 * Implementation - we cant actually prepend the existing exception,
516 * because it could have _any_ arguments given to it, so instead we get its
517 * ``__str__`` output and raise our own exception including it.
518 */
PyC_Err_Format_Prefix(PyObject * exception_type_prefix,const char * format,...)519 PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
520 {
521 PyObject *error_value_prefix;
522 va_list args;
523
524 va_start(args, format);
525 error_value_prefix = PyUnicode_FromFormatV(format, args); /* can fail and be NULL */
526 va_end(args);
527
528 if (PyErr_Occurred()) {
529 PyObject *error_type, *error_value, *error_traceback;
530 PyErr_Fetch(&error_type, &error_value, &error_traceback);
531
532 if (PyUnicode_Check(error_value)) {
533 PyErr_Format(exception_type_prefix, "%S, %S", error_value_prefix, error_value);
534 }
535 else {
536 PyErr_Format(exception_type_prefix,
537 "%S, %.200s(%S)",
538 error_value_prefix,
539 Py_TYPE(error_value)->tp_name,
540 error_value);
541 }
542 }
543 else {
544 PyErr_SetObject(exception_type_prefix, error_value_prefix);
545 }
546
547 Py_XDECREF(error_value_prefix);
548
549 /* dumb to always return NULL but matches PyErr_Format */
550 return NULL;
551 }
552
PyC_Err_SetString_Prefix(PyObject * exception_type_prefix,const char * str)553 PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str)
554 {
555 return PyC_Err_Format_Prefix(exception_type_prefix, "%s", str);
556 }
557
558 /**
559 * Use for Python callbacks run directly from C,
560 * when we can't use normal methods of raising exceptions.
561 */
PyC_Err_PrintWithFunc(PyObject * py_func)562 void PyC_Err_PrintWithFunc(PyObject *py_func)
563 {
564 /* since we return to C code we can't leave the error */
565 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
566 PyErr_Print();
567 PyErr_Clear();
568
569 /* use py style error */
570 fprintf(stderr,
571 "File \"%s\", line %d, in %s\n",
572 _PyUnicode_AsString(f_code->co_filename),
573 f_code->co_firstlineno,
574 _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name));
575 }
576
577 /** \} */
578
579 /* -------------------------------------------------------------------- */
580 /** \name Exception Buffer Access
581 * \{ */
582
583 /* returns the exception string as a new PyUnicode object, depends on external traceback module */
584 # if 0
585
586 /* this version uses traceback module but somehow fails on UI errors */
587
588 PyObject *PyC_ExceptionBuffer(void)
589 {
590 PyObject *traceback_mod = NULL;
591 PyObject *format_tb_func = NULL;
592 PyObject *ret = NULL;
593
594 if (!(traceback_mod = PyImport_ImportModule("traceback"))) {
595 goto error_cleanup;
596 }
597 else if (!(format_tb_func = PyObject_GetAttrString(traceback_mod, "format_exc"))) {
598 goto error_cleanup;
599 }
600
601 ret = PyObject_CallObject(format_tb_func, NULL);
602
603 if (ret == Py_None) {
604 Py_DECREF(ret);
605 ret = NULL;
606 }
607
608 error_cleanup:
609 /* could not import the module so print the error and close */
610 Py_XDECREF(traceback_mod);
611 Py_XDECREF(format_tb_func);
612
613 return ret;
614 }
615 # else /* verbose, non-threadsafe version */
PyC_ExceptionBuffer(void)616 PyObject *PyC_ExceptionBuffer(void)
617 {
618 PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
619 PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
620 PyObject *string_io = NULL;
621 PyObject *string_io_buf = NULL;
622 PyObject *string_io_mod = NULL;
623 PyObject *string_io_getvalue = NULL;
624
625 PyObject *error_type, *error_value, *error_traceback;
626
627 if (!PyErr_Occurred()) {
628 return NULL;
629 }
630
631 PyErr_Fetch(&error_type, &error_value, &error_traceback);
632
633 PyErr_Clear();
634
635 /* import io
636 * string_io = io.StringIO()
637 */
638
639 if (!(string_io_mod = PyImport_ImportModule("io"))) {
640 goto error_cleanup;
641 }
642 else if (!(string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
643 goto error_cleanup;
644 }
645 else if (!(string_io_getvalue = PyObject_GetAttrString(string_io, "getvalue"))) {
646 goto error_cleanup;
647 }
648
649 /* Since these were borrowed we don't want them freed when replaced. */
650 Py_INCREF(stdout_backup);
651 Py_INCREF(stderr_backup);
652
653 /* Both of these are freed when restoring. */
654 PySys_SetObject("stdout", string_io);
655 PySys_SetObject("stderr", string_io);
656
657 PyErr_Restore(error_type, error_value, error_traceback);
658 PyErr_Print(); /* print the error */
659 PyErr_Clear();
660
661 string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
662
663 PySys_SetObject("stdout", stdout_backup);
664 PySys_SetObject("stderr", stderr_backup);
665
666 Py_DECREF(stdout_backup); /* now sys owns the ref again */
667 Py_DECREF(stderr_backup);
668
669 Py_DECREF(string_io_mod);
670 Py_DECREF(string_io_getvalue);
671 Py_DECREF(string_io); /* free the original reference */
672
673 PyErr_Clear();
674 return string_io_buf;
675
676 error_cleanup:
677 /* could not import the module so print the error and close */
678 Py_XDECREF(string_io_mod);
679 Py_XDECREF(string_io);
680
681 PyErr_Restore(error_type, error_value, error_traceback);
682 PyErr_Print(); /* print the error */
683 PyErr_Clear();
684
685 return NULL;
686 }
687 # endif
688
PyC_ExceptionBuffer_Simple(void)689 PyObject *PyC_ExceptionBuffer_Simple(void)
690 {
691 PyObject *string_io_buf = NULL;
692
693 PyObject *error_type, *error_value, *error_traceback;
694
695 if (!PyErr_Occurred()) {
696 return NULL;
697 }
698
699 PyErr_Fetch(&error_type, &error_value, &error_traceback);
700
701 if (error_value == NULL) {
702 return NULL;
703 }
704
705 if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) {
706 /* Special exception for syntax errors,
707 * in these cases the full error is verbose and not very useful,
708 * just use the initial text so we know what the error is. */
709 if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) {
710 string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0));
711 }
712 }
713
714 if (string_io_buf == NULL) {
715 string_io_buf = PyObject_Str(error_value);
716 }
717
718 /* Python does this too */
719 if (UNLIKELY(string_io_buf == NULL)) {
720 string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name);
721 }
722
723 PyErr_Restore(error_type, error_value, error_traceback);
724
725 PyErr_Print();
726 PyErr_Clear();
727 return string_io_buf;
728 }
729
730 /** \} */
731
732 /* -------------------------------------------------------------------- */
733 /** \name Unicode Conversion
734 *
735 * In some cases we need to coerce strings, avoid doing this inline.
736 * \{ */
737
738 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
PyC_UnicodeAsByteAndSize(PyObject * py_str,Py_ssize_t * size,PyObject ** coerce)739 const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
740 {
741 const char *result;
742
743 result = _PyUnicode_AsStringAndSize(py_str, size);
744
745 if (result) {
746 /* 99% of the time this is enough but we better support non unicode
747 * chars since blender doesn't limit this */
748 return result;
749 }
750
751 PyErr_Clear();
752
753 if (PyBytes_Check(py_str)) {
754 *size = PyBytes_GET_SIZE(py_str);
755 return PyBytes_AS_STRING(py_str);
756 }
757 if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
758 *size = PyBytes_GET_SIZE(*coerce);
759 return PyBytes_AS_STRING(*coerce);
760 }
761
762 /* leave error raised from EncodeFS */
763 return NULL;
764 }
765
PyC_UnicodeAsByte(PyObject * py_str,PyObject ** coerce)766 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
767 {
768 const char *result;
769
770 result = _PyUnicode_AsString(py_str);
771
772 if (result) {
773 /* 99% of the time this is enough but we better support non unicode
774 * chars since blender doesn't limit this. */
775 return result;
776 }
777
778 PyErr_Clear();
779
780 if (PyBytes_Check(py_str)) {
781 return PyBytes_AS_STRING(py_str);
782 }
783 if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
784 return PyBytes_AS_STRING(*coerce);
785 }
786
787 /* leave error raised from EncodeFS */
788 return NULL;
789 }
790
PyC_UnicodeFromByteAndSize(const char * str,Py_ssize_t size)791 PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
792 {
793 PyObject *result = PyUnicode_FromStringAndSize(str, size);
794 if (result) {
795 /* 99% of the time this is enough but we better support non unicode
796 * chars since blender doesn't limit this */
797 return result;
798 }
799
800 PyErr_Clear();
801 /* this means paths will always be accessible once converted, on all OS's */
802 result = PyUnicode_DecodeFSDefaultAndSize(str, size);
803 return result;
804 }
805
PyC_UnicodeFromByte(const char * str)806 PyObject *PyC_UnicodeFromByte(const char *str)
807 {
808 return PyC_UnicodeFromByteAndSize(str, strlen(str));
809 }
810
811 /** \} */
812
813 /* -------------------------------------------------------------------- */
814 /** \name Name Space Creation/Manipulation
815 * \{ */
816
817 /*****************************************************************************
818 * Description: This function creates a new Python dictionary object.
819 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
820 * note: important we use the dict from __main__, this is what python expects
821 * for 'pickle' to work as well as strings like this...
822 * >> foo = 10
823 * >> print(__import__("__main__").foo)
824 *
825 * note: this overwrites __main__ which gives problems with nested calls.
826 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
827 * any chance that python is in the call stack.
828 ****************************************************************************/
PyC_DefaultNameSpace(const char * filename)829 PyObject *PyC_DefaultNameSpace(const char *filename)
830 {
831 PyObject *modules = PyImport_GetModuleDict();
832 PyObject *builtins = PyEval_GetBuiltins();
833 PyObject *mod_main = PyModule_New("__main__");
834 PyDict_SetItemString(modules, "__main__", mod_main);
835 Py_DECREF(mod_main); /* sys.modules owns now */
836 PyModule_AddStringConstant(mod_main, "__name__", "__main__");
837 if (filename) {
838 /* __file__ mainly for nice UI'ness
839 * note: this wont map to a real file when executing text-blocks and buttons. */
840 PyModule_AddObject(mod_main, "__file__", PyC_UnicodeFromByte(filename));
841 }
842 PyModule_AddObject(mod_main, "__builtins__", builtins);
843 Py_INCREF(builtins); /* AddObject steals a reference */
844 return PyModule_GetDict(mod_main);
845 }
846
PyC_NameSpace_ImportArray(PyObject * py_dict,const char * imports[])847 bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
848 {
849 for (int i = 0; imports[i]; i++) {
850 PyObject *name = PyUnicode_FromString(imports[i]);
851 PyObject *mod = PyImport_ImportModuleLevelObject(name, NULL, NULL, 0, 0);
852 bool ok = false;
853 if (mod) {
854 PyDict_SetItem(py_dict, name, mod);
855 ok = true;
856 Py_DECREF(mod);
857 }
858 Py_DECREF(name);
859
860 if (!ok) {
861 return false;
862 }
863 }
864 return true;
865 }
866
867 /* restore MUST be called after this */
PyC_MainModule_Backup(PyObject ** main_mod)868 void PyC_MainModule_Backup(PyObject **main_mod)
869 {
870 PyObject *modules = PyImport_GetModuleDict();
871 *main_mod = PyDict_GetItemString(modules, "__main__");
872 Py_XINCREF(*main_mod); /* don't free */
873 }
874
PyC_MainModule_Restore(PyObject * main_mod)875 void PyC_MainModule_Restore(PyObject *main_mod)
876 {
877 PyObject *modules = PyImport_GetModuleDict();
878 PyDict_SetItemString(modules, "__main__", main_mod);
879 Py_XDECREF(main_mod);
880 }
881
882 /** \} */
883
884 /* -------------------------------------------------------------------- */
885 /** \name #Py_SetPythonHome Wrapper
886 * \{ */
887
888 /**
889 * - Must be called before #Py_Initialize.
890 * - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`.
891 * - Note that the `PYTHONPATH` environment variable isn't reliable, see T31506.
892 * Use #Py_SetPythonHome instead.
893 */
PyC_SetHomePath(const char * py_path_bundle)894 void PyC_SetHomePath(const char *py_path_bundle)
895 {
896 if (py_path_bundle == NULL) {
897 /* Common enough to have bundled *nix python but complain on OSX/Win */
898 # if defined(__APPLE__) || defined(_WIN32)
899 fprintf(stderr,
900 "Warning! bundled python not found and is expected on this platform. "
901 "(if you built with CMake: 'install' target may have not been built)\n");
902 # endif
903 return;
904 }
905 /* set the environment path */
906 printf("found bundled python: %s\n", py_path_bundle);
907
908 # ifdef __APPLE__
909 /* OSX allow file/directory names to contain : character (represented as / in the Finder)
910 * but current Python lib (release 3.1.1) doesn't handle these correctly */
911 if (strchr(py_path_bundle, ':')) {
912 fprintf(stderr,
913 "Warning! Blender application is located in a path containing ':' or '/' chars\n"
914 "This may make python import function fail\n");
915 }
916 # endif
917
918 {
919 wchar_t py_path_bundle_wchar[1024];
920
921 /* Can't use this, on linux gives bug: T23018,
922 * TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */
923 /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
924
925 BLI_strncpy_wchar_from_utf8(
926 py_path_bundle_wchar, py_path_bundle, ARRAY_SIZE(py_path_bundle_wchar));
927
928 Py_SetPythonHome(py_path_bundle_wchar);
929 // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
930 }
931 }
932
PyC_IsInterpreterActive(void)933 bool PyC_IsInterpreterActive(void)
934 {
935 /* instead of PyThreadState_Get, which calls Py_FatalError */
936 return (PyThreadState_GetDict() != NULL);
937 }
938
939 /** \} */
940
941 /* -------------------------------------------------------------------- */
942 /** \name #Py_SetPythonHome Wrapper
943 * \{ */
944
945 /* Would be nice if python had this built in
946 * See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
947 */
PyC_RunQuicky(const char * filepath,int n,...)948 void PyC_RunQuicky(const char *filepath, int n, ...)
949 {
950 FILE *fp = fopen(filepath, "r");
951
952 if (fp) {
953 const PyGILState_STATE gilstate = PyGILState_Ensure();
954
955 va_list vargs;
956
957 Py_ssize_t *sizes = PyMem_MALLOC(sizeof(*sizes) * (n / 2));
958 int i;
959
960 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
961 PyObject *values = PyList_New(n / 2); /* namespace owns this, don't free */
962
963 PyObject *py_result, *ret;
964
965 PyObject *struct_mod = PyImport_ImportModule("struct");
966 PyObject *calcsize = PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
967 PyObject *pack = PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
968 PyObject *unpack = PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
969
970 Py_DECREF(struct_mod);
971
972 va_start(vargs, n);
973 for (i = 0; i * 2 < n; i++) {
974 const char *format = va_arg(vargs, char *);
975 void *ptr = va_arg(vargs, void *);
976
977 ret = PyObject_CallFunction(calcsize, "s", format);
978
979 if (ret) {
980 sizes[i] = PyLong_AsLong(ret);
981 Py_DECREF(ret);
982 ret = PyObject_CallFunction(unpack, "sy#", format, (char *)ptr, sizes[i]);
983 }
984
985 if (ret == NULL) {
986 printf("%s error, line:%d\n", __func__, __LINE__);
987 PyErr_Print();
988 PyErr_Clear();
989
990 PyList_SET_ITEM(values, i, Py_INCREF_RET(Py_None)); /* hold user */
991
992 sizes[i] = 0;
993 }
994 else {
995 if (PyTuple_GET_SIZE(ret) == 1) {
996 /* convenience, convert single tuples into single values */
997 PyObject *tmp = PyTuple_GET_ITEM(ret, 0);
998 Py_INCREF(tmp);
999 Py_DECREF(ret);
1000 ret = tmp;
1001 }
1002
1003 PyList_SET_ITEM(values, i, ret); /* hold user */
1004 }
1005 }
1006 va_end(vargs);
1007
1008 /* set the value so we can access it */
1009 PyDict_SetItemString(py_dict, "values", values);
1010 Py_DECREF(values);
1011
1012 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
1013
1014 fclose(fp);
1015
1016 if (py_result) {
1017
1018 /* we could skip this but then only slice assignment would work
1019 * better not be so strict */
1020 values = PyDict_GetItemString(py_dict, "values");
1021
1022 if (values && PyList_Check(values)) {
1023
1024 /* don't use the result */
1025 Py_DECREF(py_result);
1026 py_result = NULL;
1027
1028 /* now get the values back */
1029 va_start(vargs, n);
1030 for (i = 0; i * 2 < n; i++) {
1031 const char *format = va_arg(vargs, char *);
1032 void *ptr = va_arg(vargs, void *);
1033
1034 PyObject *item;
1035 PyObject *item_new;
1036 /* prepend the string formatting and remake the tuple */
1037 item = PyList_GET_ITEM(values, i);
1038 if (PyTuple_CheckExact(item)) {
1039 int ofs = PyTuple_GET_SIZE(item);
1040 item_new = PyTuple_New(ofs + 1);
1041 while (ofs--) {
1042 PyObject *member = PyTuple_GET_ITEM(item, ofs);
1043 PyTuple_SET_ITEM(item_new, ofs + 1, member);
1044 Py_INCREF(member);
1045 }
1046
1047 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
1048 }
1049 else {
1050 item_new = Py_BuildValue("sO", format, item);
1051 }
1052
1053 ret = PyObject_Call(pack, item_new, NULL);
1054
1055 if (ret) {
1056 /* copy the bytes back into memory */
1057 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
1058 Py_DECREF(ret);
1059 }
1060 else {
1061 printf("%s error on arg '%d', line:%d\n", __func__, i, __LINE__);
1062 PyC_ObSpit("failed converting:", item_new);
1063 PyErr_Print();
1064 PyErr_Clear();
1065 }
1066
1067 Py_DECREF(item_new);
1068 }
1069 va_end(vargs);
1070 }
1071 else {
1072 printf("%s error, 'values' not a list, line:%d\n", __func__, __LINE__);
1073 }
1074 }
1075 else {
1076 printf("%s error line:%d\n", __func__, __LINE__);
1077 PyErr_Print();
1078 PyErr_Clear();
1079 }
1080
1081 Py_DECREF(calcsize);
1082 Py_DECREF(pack);
1083 Py_DECREF(unpack);
1084
1085 PyMem_FREE(sizes);
1086
1087 PyGILState_Release(gilstate);
1088 }
1089 else {
1090 fprintf(stderr, "%s: '%s' missing\n", __func__, filepath);
1091 }
1092 }
1093
1094 /* generic function to avoid depending on RNA */
PyC_RNA_AsPointer(PyObject * value,const char * type_name)1095 void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
1096 {
1097 PyObject *as_pointer;
1098 PyObject *pointer;
1099
1100 if (STREQ(Py_TYPE(value)->tp_name, type_name) &&
1101 (as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
1102 PyCallable_Check(as_pointer)) {
1103 void *result = NULL;
1104
1105 /* must be a 'type_name' object */
1106 pointer = PyObject_CallObject(as_pointer, NULL);
1107 Py_DECREF(as_pointer);
1108
1109 if (!pointer) {
1110 PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1111 return NULL;
1112 }
1113 result = PyLong_AsVoidPtr(pointer);
1114 Py_DECREF(pointer);
1115 if (!result) {
1116 PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed");
1117 }
1118
1119 return result;
1120 }
1121
1122 PyErr_Format(PyExc_TypeError,
1123 "expected '%.200s' type found '%.200s' instead",
1124 type_name,
1125 Py_TYPE(value)->tp_name);
1126 return NULL;
1127 }
1128
1129 /** \} */
1130
1131 /* -------------------------------------------------------------------- */
1132 /** \name Flag Set Utilities (#PyC_FlagSet)
1133 *
1134 * Convert to/from Python set of strings to an int flag.
1135 * \{ */
1136
PyC_FlagSet_AsString(PyC_FlagSet * item)1137 PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item)
1138 {
1139 PyObject *py_items = PyList_New(0);
1140 for (; item->identifier; item++) {
1141 PyList_APPEND(py_items, PyUnicode_FromString(item->identifier));
1142 }
1143 PyObject *py_string = PyObject_Repr(py_items);
1144 Py_DECREF(py_items);
1145 return py_string;
1146 }
1147
PyC_FlagSet_ValueFromID_int(PyC_FlagSet * item,const char * identifier,int * r_value)1148 int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *r_value)
1149 {
1150 for (; item->identifier; item++) {
1151 if (STREQ(item->identifier, identifier)) {
1152 *r_value = item->value;
1153 return 1;
1154 }
1155 }
1156
1157 return 0;
1158 }
1159
PyC_FlagSet_ValueFromID(PyC_FlagSet * item,const char * identifier,int * r_value,const char * error_prefix)1160 int PyC_FlagSet_ValueFromID(PyC_FlagSet *item,
1161 const char *identifier,
1162 int *r_value,
1163 const char *error_prefix)
1164 {
1165 if (PyC_FlagSet_ValueFromID_int(item, identifier, r_value) == 0) {
1166 PyObject *enum_str = PyC_FlagSet_AsString(item);
1167 PyErr_Format(
1168 PyExc_ValueError, "%s: '%.200s' not found in (%U)", error_prefix, identifier, enum_str);
1169 Py_DECREF(enum_str);
1170 return -1;
1171 }
1172
1173 return 0;
1174 }
1175
PyC_FlagSet_ToBitfield(PyC_FlagSet * items,PyObject * value,int * r_value,const char * error_prefix)1176 int PyC_FlagSet_ToBitfield(PyC_FlagSet *items,
1177 PyObject *value,
1178 int *r_value,
1179 const char *error_prefix)
1180 {
1181 /* set of enum items, concatenate all values with OR */
1182 int ret, flag = 0;
1183
1184 /* set looping */
1185 Py_ssize_t pos = 0;
1186 Py_ssize_t hash = 0;
1187 PyObject *key;
1188
1189 if (!PySet_Check(value)) {
1190 PyErr_Format(PyExc_TypeError,
1191 "%.200s expected a set, not %.200s",
1192 error_prefix,
1193 Py_TYPE(value)->tp_name);
1194 return -1;
1195 }
1196
1197 *r_value = 0;
1198
1199 while (_PySet_NextEntry(value, &pos, &key, &hash)) {
1200 const char *param = _PyUnicode_AsString(key);
1201
1202 if (param == NULL) {
1203 PyErr_Format(PyExc_TypeError,
1204 "%.200s set must contain strings, not %.200s",
1205 error_prefix,
1206 Py_TYPE(key)->tp_name);
1207 return -1;
1208 }
1209
1210 if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) {
1211 return -1;
1212 }
1213
1214 flag |= ret;
1215 }
1216
1217 *r_value = flag;
1218 return 0;
1219 }
1220
PyC_FlagSet_FromBitfield(PyC_FlagSet * items,int flag)1221 PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
1222 {
1223 PyObject *ret = PySet_New(NULL);
1224 PyObject *pystr;
1225
1226 for (; items->identifier; items++) {
1227 if (items->value & flag) {
1228 pystr = PyUnicode_FromString(items->identifier);
1229 PySet_Add(ret, pystr);
1230 Py_DECREF(pystr);
1231 }
1232 }
1233
1234 return ret;
1235 }
1236
1237 /** \} */
1238
1239 /* -------------------------------------------------------------------- */
1240 /** \name Run String (Evaluate to Primitive Types)
1241 * \{ */
1242
1243 /**
1244 * \return success
1245 *
1246 * \note it is caller's responsibility to acquire & release GIL!
1247 */
PyC_RunString_AsNumber(const char * imports[],const char * expr,const char * filename,double * r_value)1248 bool PyC_RunString_AsNumber(const char *imports[],
1249 const char *expr,
1250 const char *filename,
1251 double *r_value)
1252 {
1253 PyObject *py_dict, *mod, *retval;
1254 bool ok = true;
1255 PyObject *main_mod = NULL;
1256
1257 PyC_MainModule_Backup(&main_mod);
1258
1259 py_dict = PyC_DefaultNameSpace(filename);
1260
1261 mod = PyImport_ImportModule("math");
1262 if (mod) {
1263 PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
1264 Py_DECREF(mod);
1265 }
1266 else { /* highly unlikely but possibly */
1267 PyErr_Print();
1268 PyErr_Clear();
1269 }
1270
1271 if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1272 ok = false;
1273 }
1274 else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1275 ok = false;
1276 }
1277 else {
1278 double val;
1279
1280 if (PyTuple_Check(retval)) {
1281 /* Users my have typed in 10km, 2m
1282 * add up all values */
1283 int i;
1284 val = 0.0;
1285
1286 for (i = 0; i < PyTuple_GET_SIZE(retval); i++) {
1287 const double val_item = PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i));
1288 if (val_item == -1 && PyErr_Occurred()) {
1289 val = -1;
1290 break;
1291 }
1292 val += val_item;
1293 }
1294 }
1295 else {
1296 val = PyFloat_AsDouble(retval);
1297 }
1298 Py_DECREF(retval);
1299
1300 if (val == -1 && PyErr_Occurred()) {
1301 ok = false;
1302 }
1303 else if (!isfinite(val)) {
1304 *r_value = 0.0;
1305 }
1306 else {
1307 *r_value = val;
1308 }
1309 }
1310
1311 PyC_MainModule_Restore(main_mod);
1312
1313 return ok;
1314 }
1315
PyC_RunString_AsIntPtr(const char * imports[],const char * expr,const char * filename,intptr_t * r_value)1316 bool PyC_RunString_AsIntPtr(const char *imports[],
1317 const char *expr,
1318 const char *filename,
1319 intptr_t *r_value)
1320 {
1321 PyObject *py_dict, *retval;
1322 bool ok = true;
1323 PyObject *main_mod = NULL;
1324
1325 PyC_MainModule_Backup(&main_mod);
1326
1327 py_dict = PyC_DefaultNameSpace(filename);
1328
1329 if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1330 ok = false;
1331 }
1332 else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1333 ok = false;
1334 }
1335 else {
1336 intptr_t val;
1337
1338 val = (intptr_t)PyLong_AsVoidPtr(retval);
1339 if (val == 0 && PyErr_Occurred()) {
1340 ok = false;
1341 }
1342 else {
1343 *r_value = val;
1344 }
1345
1346 Py_DECREF(retval);
1347 }
1348
1349 PyC_MainModule_Restore(main_mod);
1350
1351 return ok;
1352 }
1353
PyC_RunString_AsStringAndSize(const char * imports[],const char * expr,const char * filename,char ** r_value,size_t * r_value_size)1354 bool PyC_RunString_AsStringAndSize(const char *imports[],
1355 const char *expr,
1356 const char *filename,
1357 char **r_value,
1358 size_t *r_value_size)
1359 {
1360 PyObject *py_dict, *retval;
1361 bool ok = true;
1362 PyObject *main_mod = NULL;
1363
1364 PyC_MainModule_Backup(&main_mod);
1365
1366 py_dict = PyC_DefaultNameSpace(filename);
1367
1368 if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
1369 ok = false;
1370 }
1371 else if ((retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict)) == NULL) {
1372 ok = false;
1373 }
1374 else {
1375 const char *val;
1376 Py_ssize_t val_len;
1377
1378 val = _PyUnicode_AsStringAndSize(retval, &val_len);
1379 if (val == NULL && PyErr_Occurred()) {
1380 ok = false;
1381 }
1382 else {
1383 char *val_alloc = MEM_mallocN(val_len + 1, __func__);
1384 memcpy(val_alloc, val, val_len + 1);
1385 *r_value = val_alloc;
1386 *r_value_size = val_len;
1387 }
1388
1389 Py_DECREF(retval);
1390 }
1391
1392 PyC_MainModule_Restore(main_mod);
1393
1394 return ok;
1395 }
1396
PyC_RunString_AsString(const char * imports[],const char * expr,const char * filename,char ** r_value)1397 bool PyC_RunString_AsString(const char *imports[],
1398 const char *expr,
1399 const char *filename,
1400 char **r_value)
1401 {
1402 size_t value_size;
1403 return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
1404 }
1405
1406 /** \} */
1407
1408 #endif /* #ifndef MATH_STANDALONE */
1409
1410 /* -------------------------------------------------------------------- */
1411 /** \name Int Conversion
1412 *
1413 * \note Python doesn't provide overflow checks for specific bit-widths.
1414 *
1415 * \{ */
1416
1417 /* Compiler optimizes out redundant checks. */
1418 #ifdef __GNUC__
1419 # pragma warning(push)
1420 # pragma GCC diagnostic ignored "-Wtype-limits"
1421 #endif
1422
1423 /**
1424 * Don't use `bool` return type, so -1 can be used as an error value.
1425 */
PyC_Long_AsBool(PyObject * value)1426 int PyC_Long_AsBool(PyObject *value)
1427 {
1428 const int test = _PyLong_AsInt(value);
1429 if (UNLIKELY((uint)test > 1)) {
1430 PyErr_SetString(PyExc_TypeError, "Python number not a bool (0/1)");
1431 return -1;
1432 }
1433 return test;
1434 }
1435
PyC_Long_AsI8(PyObject * value)1436 int8_t PyC_Long_AsI8(PyObject *value)
1437 {
1438 const int test = _PyLong_AsInt(value);
1439 if (UNLIKELY(test < INT8_MIN || test > INT8_MAX)) {
1440 PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int8");
1441 return -1;
1442 }
1443 return (int8_t)test;
1444 }
1445
PyC_Long_AsI16(PyObject * value)1446 int16_t PyC_Long_AsI16(PyObject *value)
1447 {
1448 const int test = _PyLong_AsInt(value);
1449 if (UNLIKELY(test < INT16_MIN || test > INT16_MAX)) {
1450 PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int16");
1451 return -1;
1452 }
1453 return (int16_t)test;
1454 }
1455
1456 /* Inlined in header:
1457 * PyC_Long_AsI32
1458 * PyC_Long_AsI64
1459 */
1460
PyC_Long_AsU8(PyObject * value)1461 uint8_t PyC_Long_AsU8(PyObject *value)
1462 {
1463 const ulong test = PyLong_AsUnsignedLong(value);
1464 if (UNLIKELY(test > UINT8_MAX)) {
1465 PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint8");
1466 return (uint8_t)-1;
1467 }
1468 return (uint8_t)test;
1469 }
1470
PyC_Long_AsU16(PyObject * value)1471 uint16_t PyC_Long_AsU16(PyObject *value)
1472 {
1473 const ulong test = PyLong_AsUnsignedLong(value);
1474 if (UNLIKELY(test > UINT16_MAX)) {
1475 PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint16");
1476 return (uint16_t)-1;
1477 }
1478 return (uint16_t)test;
1479 }
1480
PyC_Long_AsU32(PyObject * value)1481 uint32_t PyC_Long_AsU32(PyObject *value)
1482 {
1483 const ulong test = PyLong_AsUnsignedLong(value);
1484 if (UNLIKELY(test > UINT32_MAX)) {
1485 PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint32");
1486 return (uint32_t)-1;
1487 }
1488 return (uint32_t)test;
1489 }
1490
1491 /* Inlined in header:
1492 * PyC_Long_AsU64
1493 */
1494
1495 #ifdef __GNUC__
1496 # pragma warning(pop)
1497 #endif
1498
1499 /** \} */
1500
1501 /* -------------------------------------------------------------------- */
1502 /** \name Py_buffer Utils
1503 *
1504 * \{ */
1505
PyC_StructFmt_type_from_str(const char * typestr)1506 char PyC_StructFmt_type_from_str(const char *typestr)
1507 {
1508 switch (typestr[0]) {
1509 case '!':
1510 case '<':
1511 case '=':
1512 case '>':
1513 case '@':
1514 return typestr[1];
1515 default:
1516 return typestr[0];
1517 }
1518 }
1519
PyC_StructFmt_type_is_float_any(char format)1520 bool PyC_StructFmt_type_is_float_any(char format)
1521 {
1522 switch (format) {
1523 case 'f':
1524 case 'd':
1525 case 'e':
1526 return true;
1527 default:
1528 return false;
1529 }
1530 }
1531
PyC_StructFmt_type_is_int_any(char format)1532 bool PyC_StructFmt_type_is_int_any(char format)
1533 {
1534 switch (format) {
1535 case 'i':
1536 case 'I':
1537 case 'l':
1538 case 'L':
1539 case 'h':
1540 case 'H':
1541 case 'b':
1542 case 'B':
1543 case 'q':
1544 case 'Q':
1545 case 'n':
1546 case 'N':
1547 case 'P':
1548 return true;
1549 default:
1550 return false;
1551 }
1552 }
1553
PyC_StructFmt_type_is_byte(char format)1554 bool PyC_StructFmt_type_is_byte(char format)
1555 {
1556 switch (format) {
1557 case 'c':
1558 case 's':
1559 case 'p':
1560 return true;
1561 default:
1562 return false;
1563 }
1564 }
1565
PyC_StructFmt_type_is_bool(char format)1566 bool PyC_StructFmt_type_is_bool(char format)
1567 {
1568 switch (format) {
1569 case '?':
1570 return true;
1571 default:
1572 return false;
1573 }
1574 }
1575
1576 /** \} */
1577