Blender V5.0
bpy_driver.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <Python.h>
14
15#include "DNA_anim_types.h"
16
17#include "BLI_listbase.h"
18#include "BLI_string_utf8.h"
19
20#include "BKE_animsys.h"
21#include "BKE_fcurve_driver.h"
22#include "BKE_global.hh"
23#include "BKE_idtype.hh"
24
25#include "RNA_access.hh"
26#include "RNA_prototypes.hh"
27
28#include "bpy_rna_driver.hh" /* For #pyrna_driver_get_variable_value. */
29
30#include "bpy_intern_string.hh"
31
32#include "bpy_driver.hh"
33#include "bpy_rna.hh"
34
35#include "BPY_extern.hh"
36
37#define USE_RNA_AS_PYOBJECT
38
39#define USE_BYTECODE_WHITELIST
40
41#ifdef USE_BYTECODE_WHITELIST
42# include <opcode.h>
43#endif
44
45#if PY_VERSION_HEX >= 0x030d0000 /* >=3.13 */
46/* WARNING(@ideasman42): Using `Py_BUILD_CORE` is a last resort,
47 * the alternative would be not to inspect OP-CODES at all. */
48# define Py_BUILD_CORE
49# include <internal/pycore_code.h>
50#endif
51
52PyObject *bpy_pydriver_Dict = nullptr;
53
54#ifdef USE_BYTECODE_WHITELIST
55static PyObject *bpy_pydriver_Dict__whitelist = nullptr;
56#endif
57
59{
60 PyObject *d, *mod;
61
62 /* Validate name-space for driver evaluation. */
64 return -1;
65 }
66
67 d = PyDict_New();
68 if (d == nullptr) {
69 return -1;
70 }
71
73
74 /* Import some modules: `builtins`, `bpy`, `math`, `mathutils.noise`. */
75 PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
76
77 mod = PyImport_ImportModule("math");
78 if (mod) {
79 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
81 }
82#ifdef USE_BYTECODE_WHITELIST
83 PyObject *mod_math = mod;
84#endif
85
86 /* Add `bpy` to global name-space. */
87 mod = PyImport_ImportModuleLevel("bpy", nullptr, nullptr, nullptr, 0);
88 if (mod) {
89 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
91 }
92
93 /* Add noise to global name-space. */
94 mod = PyImport_ImportModuleLevel("mathutils", nullptr, nullptr, nullptr, 0);
95 if (mod) {
96 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise");
97 PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub);
99 }
100
101 /* Add math utility functions. */
102 mod = PyImport_ImportModuleLevel("bl_math", nullptr, nullptr, nullptr, 0);
103 if (mod) {
104 static const char *names[] = {"clamp", "lerp", "smoothstep", nullptr};
105
106 for (const char **pname = names; *pname; ++pname) {
107 PyObject *func = PyDict_GetItemString(PyModule_GetDict(mod), *pname);
108 PyDict_SetItemString(bpy_pydriver_Dict, *pname, func);
109 }
110
111 Py_DECREF(mod);
112 }
113
114#ifdef USE_BYTECODE_WHITELIST
115 /* Setup the whitelist. */
116 {
117 bpy_pydriver_Dict__whitelist = PyDict_New();
118 const char *whitelist[] = {
119 /* builtins (basic) */
120 "all",
121 "any",
122 "len",
123 /* builtins (numeric) */
124 "max",
125 "min",
126 "pow",
127 "round",
128 "sum",
129 /* types */
130 "bool",
131 "float",
132 "int",
133 /* bl_math */
134 "clamp",
135 "lerp",
136 "smoothstep",
137
138 nullptr,
139 };
140
141 for (int i = 0; whitelist[i]; i++) {
142 PyDict_SetItemString(bpy_pydriver_Dict__whitelist, whitelist[i], Py_None);
143 }
144
145 /* Add all of `math` functions. */
146 if (mod_math != nullptr) {
147 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
148 PyObject *arg_key, *arg_value;
149 Py_ssize_t arg_pos = 0;
150 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
151 const char *arg_str = PyUnicode_AsUTF8(arg_key);
152 if (arg_str[0] && arg_str[1] != '_') {
153 PyDict_SetItem(bpy_pydriver_Dict__whitelist, arg_key, Py_None);
154 }
155 }
156 }
157 }
158#endif /* USE_BYTECODE_WHITELIST */
159
160 return 0;
161}
162
167static struct {
169
170 /* Borrowed reference to the `self` in `bpy_pydriver_Dict`
171 * keep for as long as the same self is used. */
172 PyObject *self = nullptr;
175
177{
178 if (g_pydriver_state_prev.evaltime != evaltime) {
179 PyObject *item = PyFloat_FromDouble(evaltime);
180 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_frame, item);
181 Py_DECREF(item);
182
184 }
185}
186
188{
189 if ((g_pydriver_state_prev.self == nullptr) ||
190 (pyrna_driver_is_equal_anim_rna(anim_rna, g_pydriver_state_prev.self) == false))
191 {
192 PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
193 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
194 Py_DECREF(item);
195
196 g_pydriver_state_prev.self = item;
197 }
198}
199
201{
202 if (g_pydriver_state_prev.self) {
203 PyDict_DelItem(bpy_pydriver_Dict, bpy_intern_str_self);
204
205 g_pydriver_state_prev.self = nullptr;
206 }
207}
208
210{
211 PointerRNA depsgraph_ptr = RNA_pointer_create_discrete(nullptr, &RNA_Depsgraph, depsgraph);
212 return pyrna_struct_CreatePyObject(&depsgraph_ptr);
213}
214
220{
221 /* This should never happen, but it's probably better to have None in Python
222 * than a nullptr-wrapping Depsgraph Python struct. */
223 BLI_assert(depsgraph != nullptr);
224 if (UNLIKELY(depsgraph == nullptr)) {
225 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, Py_None);
226 g_pydriver_state_prev.depsgraph = nullptr;
227 return;
228 }
229
230 if ((g_pydriver_state_prev.depsgraph == nullptr) ||
231 (depsgraph != g_pydriver_state_prev.depsgraph->ptr->data))
232 {
234 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, item);
235 Py_DECREF(item);
236
237 g_pydriver_state_prev.depsgraph = (BPy_StructRNA *)item;
238 }
239}
240
242{
243 if (bpy_pydriver_Dict) { /* Free the global dict used by python-drivers. */
244 PyDict_Clear(bpy_pydriver_Dict);
246 bpy_pydriver_Dict = nullptr;
247 }
248
249#ifdef USE_BYTECODE_WHITELIST
251 PyDict_Clear(bpy_pydriver_Dict__whitelist);
254 }
255#endif
256
258
259 /* Freed when clearing driver dictionary. */
260 g_pydriver_state_prev.self = nullptr;
261 g_pydriver_state_prev.depsgraph = nullptr;
262}
263
265{
266 PyGILState_STATE gilstate;
267 const bool use_gil = true; /* !PyC_IsInterpreterActive(); */
268 if (use_gil) {
269 gilstate = PyGILState_Ensure();
270 }
271
272 /* Currently exit/reset are practically the same besides the GIL check. */
274
275 if (use_gil) {
276 PyGILState_Release(gilstate);
277 }
278}
279
285static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
286{
287 driver->flag |= DRIVER_FLAG_INVALID; /* Python expression failed. */
288
289 const char *null_str = "<null>";
290 const ID *id = anim_rna->ptr.owner_id;
291 fprintf(stderr,
292 "\n"
293 "Error in PyDriver: expression failed: %s\n"
294 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
295 "\n",
296 driver->expression,
297 id ? BKE_idtype_idcode_to_name(GS(id->name)) : null_str,
298 id ? id->name + 2 : null_str,
299 anim_rna->prop ? RNA_property_identifier(anim_rna->prop) : null_str,
300 anim_rna->prop_index);
301
302 // BPy_errors_to_report(nullptr); /* TODO: reports. */
303 PyErr_Print();
304}
305
306#ifdef USE_BYTECODE_WHITELIST
307
308static bool is_opcode_secure(const int opcode)
309{
310 /* TODO(@ideasman42): Handle intrinsic opcodes (`CALL_INTRINSIC_1` & `CALL_INTRINSIC_2`).
311 * For Python 3.12. */
312
313# define OK_OP(op) \
314 case op: \
315 return true;
316
317 switch (opcode) {
318 OK_OP(CACHE)
319 OK_OP(POP_TOP)
320 OK_OP(PUSH_NULL)
321 OK_OP(NOP)
322# if PY_VERSION_HEX < 0x030c0000
323 OK_OP(UNARY_POSITIVE)
324# endif
325 OK_OP(UNARY_NEGATIVE)
326 OK_OP(UNARY_NOT)
327 OK_OP(UNARY_INVERT)
328# if PY_VERSION_HEX < 0x030e0000
329 OK_OP(BINARY_SUBSCR) /* Replaced with existing `BINARY_OP`. */
330# endif
331 OK_OP(GET_LEN)
332# if PY_VERSION_HEX < 0x030c0000
333 OK_OP(LIST_TO_TUPLE)
334# endif
335 OK_OP(RETURN_VALUE)
336 OK_OP(SWAP)
337 OK_OP(BUILD_TUPLE)
338 OK_OP(BUILD_LIST)
339 OK_OP(BUILD_SET)
340 OK_OP(BUILD_MAP)
341 OK_OP(COMPARE_OP)
342 OK_OP(JUMP_FORWARD)
343# if PY_VERSION_HEX < 0x030c0000
344 OK_OP(JUMP_IF_FALSE_OR_POP)
345 OK_OP(JUMP_IF_TRUE_OR_POP)
346 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
347 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
348# endif
349 OK_OP(LOAD_GLOBAL)
350 OK_OP(IS_OP)
351 OK_OP(CONTAINS_OP)
352 OK_OP(BINARY_OP)
353 OK_OP(LOAD_FAST)
354 OK_OP(STORE_FAST)
355 OK_OP(DELETE_FAST)
356# if PY_VERSION_HEX < 0x030c0000
357 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
358 OK_OP(POP_JUMP_FORWARD_IF_NONE)
359# endif
360 OK_OP(BUILD_SLICE)
361 OK_OP(LOAD_DEREF)
362 OK_OP(STORE_DEREF)
363 OK_OP(RESUME)
364 OK_OP(LIST_EXTEND)
365 OK_OP(SET_UPDATE)
366/* NOTE(@ideasman42): Don't enable dict manipulation, unless we can prove there is not way it
367 * can be used to manipulate the name-space (potentially allowing malicious code). */
368# if 0
369 OK_OP(DICT_MERGE)
370 OK_OP(DICT_UPDATE)
371# endif
372
373# if PY_VERSION_HEX < 0x030c0000
374 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
375 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
376 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
377 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
378# endif
379
380 /* Special cases. */
381 OK_OP(LOAD_CONST) /* Ok because constants are accepted. */
382 OK_OP(LOAD_NAME) /* Ok, because `PyCodeObject.names` is checked. */
383 OK_OP(CALL) /* Ok, because we check its "name" before calling. */
384# if PY_VERSION_HEX >= 0x030d0000
385 OK_OP(CALL_KW) /* Ok, because it's used for calling functions with keyword arguments. */
386
387 OK_OP(CALL_FUNCTION_EX);
388
389 /* OK because the names are checked. */
390 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
391 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
392 OK_OP(CALL_BOUND_METHOD_GENERAL)
393 OK_OP(CALL_BUILTIN_CLASS)
394 OK_OP(CALL_BUILTIN_FAST)
395 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
396 OK_OP(CALL_BUILTIN_O)
397 OK_OP(CALL_ISINSTANCE)
398 OK_OP(CALL_LEN)
399 OK_OP(CALL_LIST_APPEND)
400 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
401 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
402 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
403 OK_OP(CALL_METHOD_DESCRIPTOR_O)
404 OK_OP(CALL_NON_PY_GENERAL)
405 OK_OP(CALL_PY_EXACT_ARGS)
406 OK_OP(CALL_PY_GENERAL)
407 OK_OP(CALL_STR_1)
408 OK_OP(CALL_TUPLE_1)
409 OK_OP(CALL_TYPE_1)
410# else
411 OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */
412# endif
413
414# if PY_VERSION_HEX < 0x030c0000
415 OK_OP(PRECALL) /* Ok, because it's used for calling. */
416# endif
417 }
418
419# undef OK_OP
420 return false;
421}
422
423bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code,
424 PyObject *py_namespace_array[],
425 const bool verbose,
426 const char *error_prefix)
427{
428 PyCodeObject *py_code = (PyCodeObject *)expr_code;
429
430 /* Check names. */
431 {
432 for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
433 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
434 const char *name_str = PyUnicode_AsUTF8(name);
435 bool contains_name = false;
436 for (int j = 0; py_namespace_array[j]; j++) {
437 if (PyDict_Contains(py_namespace_array[j], name)) {
438 contains_name = true;
439 break;
440 }
441 }
442
443 if ((contains_name == false) || (name_str[0] == '_')) {
444 if (verbose) {
445 fprintf(stderr,
446 "\t%s: restricted access disallows name '%s', "
447 "enable auto-execution to support\n",
448 error_prefix,
449 name_str);
450 }
451 return false;
452 }
453 }
454 }
455
456 /* Check opcodes. */
457 {
458 const _Py_CODEUNIT *codestr;
459 Py_ssize_t code_len;
460
461 PyObject *co_code;
462
463 co_code = PyCode_GetCode(py_code);
464 if (UNLIKELY(!co_code)) {
465 PyErr_Print();
466 return false;
467 }
468
469 PyBytes_AsStringAndSize(co_code, (char **)&codestr, &code_len);
470 code_len /= sizeof(*codestr);
471 bool ok = true;
472
473 /* Loop over op-code's, the op-code arguments are ignored. */
474 for (Py_ssize_t i = 0; i < code_len; i++) {
475 const int opcode = _Py_OPCODE(codestr[i]);
476 if (!is_opcode_secure(opcode)) {
477 if (verbose) {
478 fprintf(stderr,
479 "\t%s: restricted access disallows opcode '%d', "
480 "enable auto-execution to support\n",
481 error_prefix,
482 opcode);
483 }
484 ok = false;
485 break;
486 }
487 }
488
489 Py_DECREF(co_code);
490 if (!ok) {
491 return false;
492 }
493 }
494
495 return true;
496}
497
498bool BPY_driver_secure_bytecode_test(PyObject *expr_code,
499 PyObject *py_namespace,
500 const bool verbose)
501{
502
503 if (!bpy_pydriver_Dict) {
504 if (bpy_pydriver_create_dict() != 0) {
505 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
506 return false;
507 }
508 }
509 PyObject *py_namespaces[] = {
510 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, py_namespace, nullptr};
511 return BPY_driver_secure_bytecode_test_ex(expr_code, py_namespaces, verbose, __func__);
512}
513
514#endif /* USE_BYTECODE_WHITELIST */
516 ChannelDriver *driver,
517 ChannelDriver *driver_orig,
518 const AnimationEvalContext *anim_eval_context)
519{
520 /* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
521 * the bake operator which intern starts a thread which calls scene update
522 * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
523 * if #PyGILState_Ensure() is needed, see #27683.
524 *
525 * (new) NOTE: checking if python is running is not thread-safe #28114
526 * now release the GIL on python operator execution instead, using
527 * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
528 *
529 * For copy-on-evaluation we always cache expressions and write errors in the
530 * original driver, otherwise these would get freed while editing.
531 * Due to the GIL this is thread-safe. */
532
533 PyObject *driver_vars = nullptr;
534 PyObject *retval = nullptr;
535
536 /* Speed up by pre-hashing string & avoids re-converting unicode strings for every execution. */
537 PyObject *expr_vars;
538
539 PyObject *expr_code;
540 PyGILState_STATE gilstate;
541 bool use_gil;
542
543 DriverVar *dvar;
544 double result = 0.0; /* Default return. */
545 const char *expr;
546 bool targets_ok = true;
547 int i;
548
549 /* Get the python expression to be evaluated. */
550 expr = driver_orig->expression;
551 if (expr[0] == '\0') {
552 return 0.0f;
553 }
554
555#ifndef USE_BYTECODE_WHITELIST
556 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
559 SNPRINTF_UTF8(G.autoexec_fail, "Driver '%s'", expr);
560
561 printf("skipping driver '%s', automatic scripts are disabled\n", expr);
562 }
563 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
564 return 0.0f;
565 }
566#else
567 bool is_recompile = false;
568#endif
569
570 use_gil = true; /* !PyC_IsInterpreterActive(); */
571
572 if (use_gil) {
573 gilstate = PyGILState_Ensure();
574 }
575
576 /* Needed since drivers are updated directly after undo where `main` is re-allocated #28807. */
578
579 /* Initialize global dictionary for Python driver evaluation settings. */
580 if (!bpy_pydriver_Dict) {
581 if (bpy_pydriver_create_dict() != 0) {
582 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
583 if (use_gil) {
584 PyGILState_Release(gilstate);
585 }
586 return 0.0f;
587 }
588 }
589
590 /* Update global name-space. */
592
593 if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
595 }
596 else {
598 }
599
601
602 if (driver_orig->expr_comp == nullptr) {
603 driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
604 }
605
606 /* Compile the expression first if it hasn't been compiled or needs to be rebuilt. */
607 if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
608 Py_XDECREF(driver_orig->expr_comp);
609 driver_orig->expr_comp = PyTuple_New(2);
610
611 expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
612 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
613
614 driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
615
616 /* Maybe this can be removed but for now best keep until were sure. */
617 driver_orig->flag |= DRIVER_FLAG_RENAMEVAR;
618 driver_orig->flag &= ~DRIVER_FLAG_PYTHON_BLOCKED;
619
620#ifdef USE_BYTECODE_WHITELIST
621 is_recompile = true;
622#endif
623 }
624 else {
625 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
626 }
627
628 if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
629 /* May not be set. */
630 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
631 Py_XDECREF(expr_vars);
632
633 expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
634 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
635
636 for (dvar = static_cast<DriverVar *>(driver_orig->variables.first), i = 0; dvar;
637 dvar = dvar->next)
638 {
639 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
640 }
641
642 driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
643 }
644 else {
645 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
646 }
647
648 /* Add target values to a dict that will be used as `__locals__` dict. */
649 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
650 for (dvar = static_cast<DriverVar *>(driver->variables.first), i = 0; dvar; dvar = dvar->next) {
651 PyObject *driver_arg = nullptr;
652
653/* Support for any RNA data. */
654#ifdef USE_RNA_AS_PYOBJECT
655 if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
657 anim_eval_context, driver, dvar, &dvar->targets[0]);
658
659 if (driver_arg == nullptr) {
660 driver_arg = PyFloat_FromDouble(0.0);
661 dvar->curval = 0.0f;
662 }
663 else {
664 /* No need to worry about overflow here, values from RNA are within limits. */
665 if (PyFloat_CheckExact(driver_arg)) {
666 dvar->curval = float(PyFloat_AsDouble(driver_arg));
667 }
668 else if (PyLong_CheckExact(driver_arg)) {
669 dvar->curval = float(PyLong_AsLong(driver_arg));
670 }
671 else if (PyBool_Check(driver_arg)) {
672 dvar->curval = float(driver_arg == Py_True);
673 }
674 else {
675 dvar->curval = 0.0f;
676 }
677 }
678 }
679 else
680#endif
681 {
682 /* Try to get variable value. */
683 const float tval = driver_get_variable_value(anim_eval_context, driver, dvar);
684 driver_arg = PyFloat_FromDouble(double(tval));
685 }
686
687 /* Try to add to dictionary. */
688 /* `if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) {` */
689 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
690 /* Pass. */
691 }
692 else {
693 /* This target failed - bad name. */
694 if (targets_ok) {
695 /* First one, print some extra info for easier identification. */
696 fprintf(stderr, "\n%s: Error while evaluating PyDriver:\n", __func__);
697 targets_ok = false;
698 }
699
700 fprintf(stderr, "\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->name);
701 // BPy_errors_to_report(nullptr); /* TODO: reports. */
702 PyErr_Print();
703 }
704 Py_DECREF(driver_arg);
705 }
706
707#ifdef USE_BYTECODE_WHITELIST
708 if (is_recompile && expr_code) {
709 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
710 PyObject *py_namespaces[] = {
711 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, driver_vars, nullptr};
713 expr_code,
714 py_namespaces,
715 /* Always be verbose since this can give hints to why evaluation fails. */
716 true,
717 __func__))
718 {
721 SNPRINTF_UTF8(G.autoexec_fail, "Driver '%s'", expr);
722 }
723
724 Py_DECREF(expr_code);
725 expr_code = nullptr;
726 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, nullptr);
727 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
728 }
729 }
730 }
731#endif /* USE_BYTECODE_WHITELIST */
732
733#if 0 /* slow, with this can avoid all Py_CompileString above. */
734 /* execute expression to get a value */
735 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
736#else
737 /* Evaluate the compiled expression. */
738 if (expr_code) {
739 retval = PyEval_EvalCode(
740 static_cast<PyObject *>((void *)expr_code), bpy_pydriver_Dict, driver_vars);
741 }
742#endif
743
744 /* Decref the driver variables first. */
745 Py_DECREF(driver_vars);
746
747 /* Process the result. */
748 if (retval == nullptr) {
749 pydriver_error(driver, anim_rna);
750 }
751 else {
752 if (UNLIKELY((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
753 pydriver_error(driver, anim_rna);
754 result = 0.0;
755 }
756 else {
757 /* All fine, make sure the "invalid expression" flag is cleared. */
758 driver->flag &= ~DRIVER_FLAG_INVALID;
759 }
760 Py_DECREF(retval);
761 }
762
763 if (use_gil) {
764 PyGILState_Release(gilstate);
765 }
766
767 if (UNLIKELY(!isfinite(result))) {
768 fprintf(stderr, "\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->expression, result);
769 return 0.0f;
770 }
771
772 return float(result);
773}
float driver_get_variable_value(const struct AnimationEvalContext *anim_eval_context, struct ChannelDriver *driver, struct DriverVar *dvar)
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
@ G_FLAG_SCRIPT_AUTOEXEC
const char * BKE_idtype_idcode_to_name(short idcode)
Definition idtype.cc:164
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
#define SNPRINTF_UTF8(dst, format,...)
#define SWAP(type, a, b)
#define UNLIKELY(x)
@ DVAR_TYPE_SINGLE_PROP
@ DRIVER_FLAG_INVALID
@ DRIVER_FLAG_PYTHON_BLOCKED
@ DRIVER_FLAG_RECOMPILE
@ DRIVER_FLAG_USE_SELF
@ DRIVER_FLAG_RENAMEVAR
static PyObject * bpy_pydriver_Dict__whitelist
Definition bpy_driver.cc:55
static bool is_opcode_secure(const int opcode)
PyObject * bpy_pydriver_Dict
Definition bpy_driver.cc:52
static struct @227352076010261012140035020175267314002332116034 g_pydriver_state_prev
static void bpy_pydriver_namespace_update_depsgraph(Depsgraph *depsgraph)
PyObject * self
static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
static void bpy_pydriver_namespace_update_self(PathResolvedRNA *anim_rna)
float BPY_driver_exec(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
float evaltime
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
#define OK_OP(op)
int bpy_pydriver_create_dict()
Definition bpy_driver.cc:58
bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code, PyObject *py_namespace_array[], const bool verbose, const char *error_prefix)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(Depsgraph *depsgraph)
void BPY_driver_reset()
static void bpy_pydriver_namespace_clear_self()
void BPY_driver_exit()
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *py_namespace, const bool verbose)
PyObject * bpy_intern_str_depsgraph
PyObject * bpy_intern_str_self
PyObject * bpy_intern_str_frame
void BPY_update_rna_module()
Definition bpy_rna.cc:8715
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:8496
PyObject * pyrna_driver_get_variable_value(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar)
PyObject * pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
static int verbose
Definition cineonlib.cc:30
nullptr float
#define GS(x)
#define printf(...)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
#define G(x, y, z)
Py_DECREF(oname)
const char * name
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
#define FLT_MAX
Definition stdcycles.h:14
struct Depsgraph * depsgraph
Definition BKE_animsys.h:37
char expression[256]
struct DriverVar * next
DriverTarget targets[8]
char name[64]
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
void * first
PointerRNA ptr
Definition RNA_types.hh:153
PropertyRNA * prop
Definition RNA_types.hh:154
ID * owner_id
Definition RNA_types.hh:51
i
Definition text_draw.cc:230