Blender V4.5
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.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 */
80 Py_DECREF(mod);
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);
90 Py_DECREF(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);
98 Py_DECREF(mod);
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);
245 Py_DECREF(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 PyErr_Clear();
305}
306
307#ifdef USE_BYTECODE_WHITELIST
308
309static bool is_opcode_secure(const int opcode)
310{
311 /* TODO(@ideasman42): Handle intrinsic opcodes (`CALL_INTRINSIC_1` & `CALL_INTRINSIC_2`).
312 * For Python 3.12. */
313
314# define OK_OP(op) \
315 case op: \
316 return true;
317
318 switch (opcode) {
319 OK_OP(CACHE)
320 OK_OP(POP_TOP)
321 OK_OP(PUSH_NULL)
322 OK_OP(NOP)
323# if PY_VERSION_HEX < 0x030c0000
324 OK_OP(UNARY_POSITIVE)
325# endif
326 OK_OP(UNARY_NEGATIVE)
327 OK_OP(UNARY_NOT)
328 OK_OP(UNARY_INVERT)
329# if PY_VERSION_HEX < 0x030e0000
330 OK_OP(BINARY_SUBSCR) /* Replaced with existing `BINARY_OP`. */
331# endif
332 OK_OP(GET_LEN)
333# if PY_VERSION_HEX < 0x030c0000
334 OK_OP(LIST_TO_TUPLE)
335# endif
336 OK_OP(RETURN_VALUE)
337 OK_OP(SWAP)
338 OK_OP(BUILD_TUPLE)
339 OK_OP(BUILD_LIST)
340 OK_OP(BUILD_SET)
341 OK_OP(BUILD_MAP)
342 OK_OP(COMPARE_OP)
343 OK_OP(JUMP_FORWARD)
344# if PY_VERSION_HEX < 0x030c0000
345 OK_OP(JUMP_IF_FALSE_OR_POP)
346 OK_OP(JUMP_IF_TRUE_OR_POP)
347 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
348 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
349# endif
350 OK_OP(LOAD_GLOBAL)
351 OK_OP(IS_OP)
352 OK_OP(CONTAINS_OP)
353 OK_OP(BINARY_OP)
354 OK_OP(LOAD_FAST)
355 OK_OP(STORE_FAST)
356 OK_OP(DELETE_FAST)
357# if PY_VERSION_HEX < 0x030c0000
358 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
359 OK_OP(POP_JUMP_FORWARD_IF_NONE)
360# endif
361 OK_OP(BUILD_SLICE)
362 OK_OP(LOAD_DEREF)
363 OK_OP(STORE_DEREF)
364 OK_OP(RESUME)
365 OK_OP(LIST_EXTEND)
366 OK_OP(SET_UPDATE)
367/* NOTE(@ideasman42): Don't enable dict manipulation, unless we can prove there is not way it
368 * can be used to manipulate the name-space (potentially allowing malicious code). */
369# if 0
370 OK_OP(DICT_MERGE)
371 OK_OP(DICT_UPDATE)
372# endif
373
374# if PY_VERSION_HEX < 0x030c0000
375 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
376 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
377 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
378 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
379# endif
380
381 /* Special cases. */
382 OK_OP(LOAD_CONST) /* Ok because constants are accepted. */
383 OK_OP(LOAD_NAME) /* Ok, because `PyCodeObject.names` is checked. */
384 OK_OP(CALL) /* Ok, because we check its "name" before calling. */
385# if PY_VERSION_HEX >= 0x030d0000
386 OK_OP(CALL_KW) /* Ok, because it's used for calling functions with keyword arguments. */
387
388 OK_OP(CALL_FUNCTION_EX);
389
390 /* OK because the names are checked. */
391 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
392 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
393 OK_OP(CALL_BOUND_METHOD_GENERAL)
394 OK_OP(CALL_BUILTIN_CLASS)
395 OK_OP(CALL_BUILTIN_FAST)
396 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
397 OK_OP(CALL_BUILTIN_O)
398 OK_OP(CALL_ISINSTANCE)
399 OK_OP(CALL_LEN)
400 OK_OP(CALL_LIST_APPEND)
401 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
402 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
403 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
404 OK_OP(CALL_METHOD_DESCRIPTOR_O)
405 OK_OP(CALL_NON_PY_GENERAL)
406 OK_OP(CALL_PY_EXACT_ARGS)
407 OK_OP(CALL_PY_GENERAL)
408 OK_OP(CALL_STR_1)
409 OK_OP(CALL_TUPLE_1)
410 OK_OP(CALL_TYPE_1)
411# else
412 OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */
413# endif
414
415# if PY_VERSION_HEX < 0x030c0000
416 OK_OP(PRECALL) /* Ok, because it's used for calling. */
417# endif
418 }
419
420# undef OK_OP
421 return false;
422}
423
424bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code,
425 PyObject *py_namespace_array[],
426 const bool verbose,
427 const char *error_prefix)
428{
429 PyCodeObject *py_code = (PyCodeObject *)expr_code;
430
431 /* Check names. */
432 {
433 for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
434 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
435 const char *name_str = PyUnicode_AsUTF8(name);
436 bool contains_name = false;
437 for (int j = 0; py_namespace_array[j]; j++) {
438 if (PyDict_Contains(py_namespace_array[j], name)) {
439 contains_name = true;
440 break;
441 }
442 }
443
444 if ((contains_name == false) || (name_str[0] == '_')) {
445 if (verbose) {
446 fprintf(stderr,
447 "\t%s: restricted access disallows name '%s', "
448 "enable auto-execution to support\n",
449 error_prefix,
450 name_str);
451 }
452 return false;
453 }
454 }
455 }
456
457 /* Check opcodes. */
458 {
459 const _Py_CODEUNIT *codestr;
460 Py_ssize_t code_len;
461
462 PyObject *co_code;
463
464 co_code = PyCode_GetCode(py_code);
465 if (UNLIKELY(!co_code)) {
466 PyErr_Print();
467 PyErr_Clear();
468 return false;
469 }
470
471 PyBytes_AsStringAndSize(co_code, (char **)&codestr, &code_len);
472 code_len /= sizeof(*codestr);
473 bool ok = true;
474
475 /* Loop over op-code's, the op-code arguments are ignored. */
476 for (Py_ssize_t i = 0; i < code_len; i++) {
477 const int opcode = _Py_OPCODE(codestr[i]);
478 if (!is_opcode_secure(opcode)) {
479 if (verbose) {
480 fprintf(stderr,
481 "\t%s: restricted access disallows opcode '%d', "
482 "enable auto-execution to support\n",
483 error_prefix,
484 opcode);
485 }
486 ok = false;
487 break;
488 }
489 }
490
491 Py_DECREF(co_code);
492 if (!ok) {
493 return false;
494 }
495 }
496
497 return true;
498}
499
500bool BPY_driver_secure_bytecode_test(PyObject *expr_code,
501 PyObject *py_namespace,
502 const bool verbose)
503{
504
505 if (!bpy_pydriver_Dict) {
506 if (bpy_pydriver_create_dict() != 0) {
507 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
508 return false;
509 }
510 }
511 PyObject *py_namespaces[] = {
512 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, py_namespace, nullptr};
513 return BPY_driver_secure_bytecode_test_ex(expr_code, py_namespaces, verbose, __func__);
514}
515
516#endif /* USE_BYTECODE_WHITELIST */
518 ChannelDriver *driver,
519 ChannelDriver *driver_orig,
520 const AnimationEvalContext *anim_eval_context)
521{
522 /* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
523 * the bake operator which intern starts a thread which calls scene update
524 * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
525 * if #PyGILState_Ensure() is needed, see #27683.
526 *
527 * (new) NOTE: checking if python is running is not thread-safe #28114
528 * now release the GIL on python operator execution instead, using
529 * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
530 *
531 * For copy-on-evaluation we always cache expressions and write errors in the
532 * original driver, otherwise these would get freed while editing.
533 * Due to the GIL this is thread-safe. */
534
535 PyObject *driver_vars = nullptr;
536 PyObject *retval = nullptr;
537
538 /* Speed up by pre-hashing string & avoids re-converting unicode strings for every execution. */
539 PyObject *expr_vars;
540
541 PyObject *expr_code;
542 PyGILState_STATE gilstate;
543 bool use_gil;
544
545 DriverVar *dvar;
546 double result = 0.0; /* Default return. */
547 const char *expr;
548 bool targets_ok = true;
549 int i;
550
551 /* Get the python expression to be evaluated. */
552 expr = driver_orig->expression;
553 if (expr[0] == '\0') {
554 return 0.0f;
555 }
556
557#ifndef USE_BYTECODE_WHITELIST
558 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
561 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
562
563 printf("skipping driver '%s', automatic scripts are disabled\n", expr);
564 }
565 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
566 return 0.0f;
567 }
568#else
569 bool is_recompile = false;
570#endif
571
572 use_gil = true; /* !PyC_IsInterpreterActive(); */
573
574 if (use_gil) {
575 gilstate = PyGILState_Ensure();
576 }
577
578 /* Needed since drivers are updated directly after undo where `main` is re-allocated #28807. */
580
581 /* Initialize global dictionary for Python driver evaluation settings. */
582 if (!bpy_pydriver_Dict) {
583 if (bpy_pydriver_create_dict() != 0) {
584 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
585 if (use_gil) {
586 PyGILState_Release(gilstate);
587 }
588 return 0.0f;
589 }
590 }
591
592 /* Update global name-space. */
594
595 if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
597 }
598 else {
600 }
601
603
604 if (driver_orig->expr_comp == nullptr) {
605 driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
606 }
607
608 /* Compile the expression first if it hasn't been compiled or needs to be rebuilt. */
609 if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
610 Py_XDECREF(driver_orig->expr_comp);
611 driver_orig->expr_comp = PyTuple_New(2);
612
613 expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
614 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
615
616 driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
617
618 /* Maybe this can be removed but for now best keep until were sure. */
619 driver_orig->flag |= DRIVER_FLAG_RENAMEVAR;
620 driver_orig->flag &= ~DRIVER_FLAG_PYTHON_BLOCKED;
621
622#ifdef USE_BYTECODE_WHITELIST
623 is_recompile = true;
624#endif
625 }
626 else {
627 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
628 }
629
630 if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
631 /* May not be set. */
632 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
633 Py_XDECREF(expr_vars);
634
635 expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
636 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
637
638 for (dvar = static_cast<DriverVar *>(driver_orig->variables.first), i = 0; dvar;
639 dvar = dvar->next)
640 {
641 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
642 }
643
644 driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
645 }
646 else {
647 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
648 }
649
650 /* Add target values to a dict that will be used as `__locals__` dict. */
651 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
652 for (dvar = static_cast<DriverVar *>(driver->variables.first), i = 0; dvar; dvar = dvar->next) {
653 PyObject *driver_arg = nullptr;
654
655/* Support for any RNA data. */
656#ifdef USE_RNA_AS_PYOBJECT
657 if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
659 anim_eval_context, driver, dvar, &dvar->targets[0]);
660
661 if (driver_arg == nullptr) {
662 driver_arg = PyFloat_FromDouble(0.0);
663 dvar->curval = 0.0f;
664 }
665 else {
666 /* No need to worry about overflow here, values from RNA are within limits. */
667 if (PyFloat_CheckExact(driver_arg)) {
668 dvar->curval = float(PyFloat_AsDouble(driver_arg));
669 }
670 else if (PyLong_CheckExact(driver_arg)) {
671 dvar->curval = float(PyLong_AsLong(driver_arg));
672 }
673 else if (PyBool_Check(driver_arg)) {
674 dvar->curval = float(driver_arg == Py_True);
675 }
676 else {
677 dvar->curval = 0.0f;
678 }
679 }
680 }
681 else
682#endif
683 {
684 /* Try to get variable value. */
685 const float tval = driver_get_variable_value(anim_eval_context, driver, dvar);
686 driver_arg = PyFloat_FromDouble(double(tval));
687 }
688
689 /* Try to add to dictionary. */
690 /* `if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) {` */
691 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
692 /* Pass. */
693 }
694 else {
695 /* This target failed - bad name. */
696 if (targets_ok) {
697 /* First one, print some extra info for easier identification. */
698 fprintf(stderr, "\n%s: Error while evaluating PyDriver:\n", __func__);
699 targets_ok = false;
700 }
701
702 fprintf(stderr, "\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->name);
703 // BPy_errors_to_report(nullptr); /* TODO: reports. */
704 PyErr_Print();
705 PyErr_Clear();
706 }
707 Py_DECREF(driver_arg);
708 }
709
710#ifdef USE_BYTECODE_WHITELIST
711 if (is_recompile && expr_code) {
712 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
713 PyObject *py_namespaces[] = {
714 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, driver_vars, nullptr};
716 expr_code,
717 py_namespaces,
718 /* Always be verbose since this can give hints to why evaluation fails. */
719 true,
720 __func__))
721 {
724 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
725 }
726
727 Py_DECREF(expr_code);
728 expr_code = nullptr;
729 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, nullptr);
730 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
731 }
732 }
733 }
734#endif /* USE_BYTECODE_WHITELIST */
735
736#if 0 /* slow, with this can avoid all Py_CompileString above. */
737 /* execute expression to get a value */
738 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
739#else
740 /* Evaluate the compiled expression. */
741 if (expr_code) {
742 retval = PyEval_EvalCode(
743 static_cast<PyObject *>((void *)expr_code), bpy_pydriver_Dict, driver_vars);
744 }
745#endif
746
747 /* Decref the driver variables first. */
748 Py_DECREF(driver_vars);
749
750 /* Process the result. */
751 if (retval == nullptr) {
752 pydriver_error(driver, anim_rna);
753 }
754 else {
755 if (UNLIKELY((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
756 pydriver_error(driver, anim_rna);
757 result = 0.0;
758 }
759 else {
760 /* All fine, make sure the "invalid expression" flag is cleared. */
761 driver->flag &= ~DRIVER_FLAG_INVALID;
762 }
763 Py_DECREF(retval);
764 }
765
766 if (use_gil) {
767 PyGILState_Release(gilstate);
768 }
769
770 if (UNLIKELY(!isfinite(result))) {
771 fprintf(stderr, "\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->expression, result);
772 return 0.0f;
773 }
774
775 return float(result);
776}
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:165
#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(dst, format,...)
Definition BLI_string.h:599
#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
#define arg_str(...)
Definition bgl.cc:413
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 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
static struct @324011374074271332033343051256216376352075220253 g_pydriver_state_prev
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:8603
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:8384
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
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
#define printf(...)
#define GS(a)
#define G(x, y, z)
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:404
char name[66]
Definition DNA_ID.h:415
void * first
PointerRNA ptr
Definition RNA_types.hh:141
PropertyRNA * prop
Definition RNA_types.hh:142
ID * owner_id
Definition RNA_types.hh:51
i
Definition text_draw.cc:230