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_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# if PY_VERSION_HEX >= 0x030c0000
382 OK_OP(RETURN_CONST)
383 OK_OP(POP_JUMP_IF_FALSE)
384 OK_OP(CALL_INTRINSIC_1)
385# endif
386 /* Special cases. */
387 OK_OP(LOAD_CONST) /* Ok because constants are accepted. */
388 OK_OP(LOAD_NAME) /* Ok, because `PyCodeObject.names` is checked. */
389 OK_OP(CALL) /* Ok, because we check its "name" before calling. */
390# if PY_VERSION_HEX >= 0x030d0000
391 OK_OP(CALL_KW) /* Ok, because it's used for calling functions with keyword arguments. */
392
393 OK_OP(CALL_FUNCTION_EX);
394
395 /* OK because the names are checked. */
396 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
397 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
398 OK_OP(CALL_BOUND_METHOD_GENERAL)
399 OK_OP(CALL_BUILTIN_CLASS)
400 OK_OP(CALL_BUILTIN_FAST)
401 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
402 OK_OP(CALL_BUILTIN_O)
403 OK_OP(CALL_ISINSTANCE)
404 OK_OP(CALL_LEN)
405 OK_OP(CALL_LIST_APPEND)
406 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
407 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
408 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
409 OK_OP(CALL_METHOD_DESCRIPTOR_O)
410 OK_OP(CALL_NON_PY_GENERAL)
411 OK_OP(CALL_PY_EXACT_ARGS)
412 OK_OP(CALL_PY_GENERAL)
413 OK_OP(CALL_STR_1)
414 OK_OP(CALL_TUPLE_1)
415 OK_OP(CALL_TYPE_1)
416# else
417 OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */
418# endif
419
420# if PY_VERSION_HEX < 0x030c0000
421 OK_OP(PRECALL) /* Ok, because it's used for calling. */
422# endif
423 }
424
425# undef OK_OP
426 return false;
427}
428
429bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code,
430 PyObject *py_namespace_array[],
431 const bool verbose,
432 const char *error_prefix)
433{
434 PyCodeObject *py_code = (PyCodeObject *)expr_code;
435
436 /* Check names. */
437 {
438 for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
439 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
440 const char *name_str = PyUnicode_AsUTF8(name);
441 bool contains_name = false;
442 for (int j = 0; py_namespace_array[j]; j++) {
443 if (PyDict_Contains(py_namespace_array[j], name)) {
444 contains_name = true;
445 break;
446 }
447 }
448
449 if ((contains_name == false) || (name_str[0] == '_')) {
450 if (verbose) {
451 fprintf(stderr,
452 "\t%s: restricted access disallows name '%s', "
453 "enable auto-execution to support\n",
454 error_prefix,
455 name_str);
456 }
457 return false;
458 }
459 }
460 }
461
462 /* Check opcodes. */
463 {
464 const _Py_CODEUNIT *codestr;
465 Py_ssize_t code_len;
466
467 PyObject *co_code;
468
469 co_code = PyCode_GetCode(py_code);
470 if (UNLIKELY(!co_code)) {
471 PyErr_Print();
472 PyErr_Clear();
473 return false;
474 }
475
476 PyBytes_AsStringAndSize(co_code, (char **)&codestr, &code_len);
477 code_len /= sizeof(*codestr);
478 bool ok = true;
479
480 /* Loop over op-code's, the op-code arguments are ignored. */
481 for (Py_ssize_t i = 0; i < code_len; i++) {
482 const int opcode = _Py_OPCODE(codestr[i]);
483 if (!is_opcode_secure(opcode)) {
484 if (verbose) {
485 fprintf(stderr,
486 "\t%s: restricted access disallows opcode '%d', "
487 "enable auto-execution to support\n",
488 error_prefix,
489 opcode);
490 }
491 ok = false;
492 break;
493 }
494 }
495
496 Py_DECREF(co_code);
497 if (!ok) {
498 return false;
499 }
500 }
501
502 return true;
503}
504
505bool BPY_driver_secure_bytecode_test(PyObject *expr_code,
506 PyObject *py_namespace,
507 const bool verbose)
508{
509
510 if (!bpy_pydriver_Dict) {
511 if (bpy_pydriver_create_dict() != 0) {
512 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
513 return false;
514 }
515 }
516 PyObject *py_namespaces[] = {
517 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, py_namespace, nullptr};
518 return BPY_driver_secure_bytecode_test_ex(expr_code, py_namespaces, verbose, __func__);
519}
520
521#endif /* USE_BYTECODE_WHITELIST */
523 ChannelDriver *driver,
524 ChannelDriver *driver_orig,
525 const AnimationEvalContext *anim_eval_context)
526{
527 /* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
528 * the bake operator which intern starts a thread which calls scene update
529 * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
530 * if #PyGILState_Ensure() is needed, see #27683.
531 *
532 * (new) NOTE: checking if python is running is not thread-safe #28114
533 * now release the GIL on python operator execution instead, using
534 * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
535 *
536 * For copy-on-evaluation we always cache expressions and write errors in the
537 * original driver, otherwise these would get freed while editing.
538 * Due to the GIL this is thread-safe. */
539
540 PyObject *driver_vars = nullptr;
541 PyObject *retval = nullptr;
542
543 /* Speed up by pre-hashing string & avoids re-converting unicode strings for every execution. */
544 PyObject *expr_vars;
545
546 PyObject *expr_code;
547 PyGILState_STATE gilstate;
548 bool use_gil;
549
550 DriverVar *dvar;
551 double result = 0.0; /* Default return. */
552 const char *expr;
553 bool targets_ok = true;
554 int i;
555
556 /* Get the python expression to be evaluated. */
557 expr = driver_orig->expression;
558 if (expr[0] == '\0') {
559 return 0.0f;
560 }
561
562#ifndef USE_BYTECODE_WHITELIST
563 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
566 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
567
568 printf("skipping driver '%s', automatic scripts are disabled\n", expr);
569 }
570 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
571 return 0.0f;
572 }
573#else
574 bool is_recompile = false;
575#endif
576
577 use_gil = true; /* !PyC_IsInterpreterActive(); */
578
579 if (use_gil) {
580 gilstate = PyGILState_Ensure();
581 }
582
583 /* Needed since drivers are updated directly after undo where `main` is re-allocated #28807. */
585
586 /* Initialize global dictionary for Python driver evaluation settings. */
587 if (!bpy_pydriver_Dict) {
588 if (bpy_pydriver_create_dict() != 0) {
589 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
590 if (use_gil) {
591 PyGILState_Release(gilstate);
592 }
593 return 0.0f;
594 }
595 }
596
597 /* Update global name-space. */
599
600 if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
602 }
603 else {
605 }
606
608
609 if (driver_orig->expr_comp == nullptr) {
610 driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
611 }
612
613 /* Compile the expression first if it hasn't been compiled or needs to be rebuilt. */
614 if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
615 Py_XDECREF(driver_orig->expr_comp);
616 driver_orig->expr_comp = PyTuple_New(2);
617
618 expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
619 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
620
621 driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
622
623 /* Maybe this can be removed but for now best keep until were sure. */
624 driver_orig->flag |= DRIVER_FLAG_RENAMEVAR;
625 driver_orig->flag &= ~DRIVER_FLAG_PYTHON_BLOCKED;
626
627#ifdef USE_BYTECODE_WHITELIST
628 is_recompile = true;
629#endif
630 }
631 else {
632 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
633 }
634
635 if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
636 /* May not be set. */
637 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
638 Py_XDECREF(expr_vars);
639
640 expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
641 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
642
643 for (dvar = static_cast<DriverVar *>(driver_orig->variables.first), i = 0; dvar;
644 dvar = dvar->next)
645 {
646 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
647 }
648
649 driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
650 }
651 else {
652 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
653 }
654
655 /* Add target values to a dict that will be used as `__locals__` dict. */
656 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
657 for (dvar = static_cast<DriverVar *>(driver->variables.first), i = 0; dvar; dvar = dvar->next) {
658 PyObject *driver_arg = nullptr;
659
660/* Support for any RNA data. */
661#ifdef USE_RNA_AS_PYOBJECT
662 if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
664 anim_eval_context, driver, dvar, &dvar->targets[0]);
665
666 if (driver_arg == nullptr) {
667 driver_arg = PyFloat_FromDouble(0.0);
668 dvar->curval = 0.0f;
669 }
670 else {
671 /* No need to worry about overflow here, values from RNA are within limits. */
672 if (PyFloat_CheckExact(driver_arg)) {
673 dvar->curval = float(PyFloat_AsDouble(driver_arg));
674 }
675 else if (PyLong_CheckExact(driver_arg)) {
676 dvar->curval = float(PyLong_AsLong(driver_arg));
677 }
678 else if (PyBool_Check(driver_arg)) {
679 dvar->curval = float(driver_arg == Py_True);
680 }
681 else {
682 dvar->curval = 0.0f;
683 }
684 }
685 }
686 else
687#endif
688 {
689 /* Try to get variable value. */
690 const float tval = driver_get_variable_value(anim_eval_context, driver, dvar);
691 driver_arg = PyFloat_FromDouble(double(tval));
692 }
693
694 /* Try to add to dictionary. */
695 /* `if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) {` */
696 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
697 /* Pass. */
698 }
699 else {
700 /* This target failed - bad name. */
701 if (targets_ok) {
702 /* First one, print some extra info for easier identification. */
703 fprintf(stderr, "\n%s: Error while evaluating PyDriver:\n", __func__);
704 targets_ok = false;
705 }
706
707 fprintf(stderr, "\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->name);
708 // BPy_errors_to_report(nullptr); /* TODO: reports. */
709 PyErr_Print();
710 PyErr_Clear();
711 }
712 Py_DECREF(driver_arg);
713 }
714
715#ifdef USE_BYTECODE_WHITELIST
716 if (is_recompile && expr_code) {
717 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
718 PyObject *py_namespaces[] = {
719 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, driver_vars, nullptr};
721 expr_code,
722 py_namespaces,
723 /* Always be verbose since this can give hints to why evaluation fails. */
724 true,
725 __func__))
726 {
729 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
730 }
731
732 Py_DECREF(expr_code);
733 expr_code = nullptr;
734 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, nullptr);
735 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
736 }
737 }
738 }
739#endif /* USE_BYTECODE_WHITELIST */
740
741#if 0 /* slow, with this can avoid all Py_CompileString above. */
742 /* execute expression to get a value */
743 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
744#else
745 /* Evaluate the compiled expression. */
746 if (expr_code) {
747 retval = PyEval_EvalCode(
748 static_cast<PyObject *>((void *)expr_code), bpy_pydriver_Dict, driver_vars);
749 }
750#endif
751
752 /* Decref the driver variables first. */
753 Py_DECREF(driver_vars);
754
755 /* Process the result. */
756 if (retval == nullptr) {
757 pydriver_error(driver, anim_rna);
758 }
759 else {
760 if (UNLIKELY((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
761 pydriver_error(driver, anim_rna);
762 result = 0.0;
763 }
764 else {
765 /* All fine, make sure the "invalid expression" flag is cleared. */
766 driver->flag &= ~DRIVER_FLAG_INVALID;
767 }
768 Py_DECREF(retval);
769 }
770
771 if (use_gil) {
772 PyGILState_Release(gilstate);
773 }
774
775 if (UNLIKELY(!isfinite(result))) {
776 fprintf(stderr, "\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->expression, result);
777 return 0.0f;
778 }
779
780 return float(result);
781}
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
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
static struct @206166051352076163221226375034341047277250336243 g_pydriver_state_prev
#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:8605
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:8386
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