555aec00b2c9488df805c9f3cefd9a60b813d83f
[blender.git] / source / blender / python / intern / bpy_operator.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_operator.c
24  *  \ingroup pythonintern
25  *
26  * This file defines '_bpy.ops', an internal python module which gives python
27  * the ability to inspect and call both C and Python defined operators.
28  *
29  * \note
30  * This module is exposed to the user via 'release/scripts/modules/bpy/ops.py'
31  * which fakes exposing operators as modules/functions using its own classes.
32  */
33
34 #include <Python.h>
35
36 #include "RNA_types.h"
37
38 #include "BLI_utildefines.h"
39 #include "BLI_listbase.h"
40 #include "BLI_string.h"
41
42 #include "BPY_extern.h"
43 #include "bpy_operator.h"
44 #include "bpy_operator_wrap.h"
45 #include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
46 #include "bpy_capi_utils.h"
47 #include "../generic/bpy_internal_import.h"
48 #include "../generic/py_capi_utils.h"
49 #include "../generic/python_utildefines.h"
50
51 #include "RNA_access.h"
52 #include "RNA_enum_types.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "MEM_guardedalloc.h"
58
59 #include "BLI_ghash.h"
60
61 #include "BKE_report.h"
62 #include "BKE_context.h"
63
64 /* so operators called can spawn threads which acquire the GIL */
65 #define BPY_RELEASE_GIL
66
67 static wmOperatorType *ot_lookup_from_py_string(PyObject *value, const char *py_fn_id)
68 {
69         const char *opname = _PyUnicode_AsString(value);
70         if (opname == NULL) {
71                 PyErr_Format(PyExc_TypeError, "%s() expects a string argument", py_fn_id);
72                 return NULL;
73         }
74
75         wmOperatorType *ot = WM_operatortype_find(opname, true);
76         if (ot == NULL) {
77                 PyErr_Format(PyExc_KeyError, "%s(\"%s\") not found", py_fn_id, opname);
78                 return NULL;
79         }
80         return ot;
81 }
82
83 static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
84 {
85         wmOperatorType *ot;
86         const char *opname;
87         PyObject *context_dict = NULL; /* optional args */
88         PyObject *context_dict_back;
89         const char *context_str = NULL;
90         PyObject *ret;
91
92         int context = WM_OP_EXEC_DEFAULT;
93
94         /* XXX Todo, work out a better solution for passing on context,
95          * could make a tuple from self and pack the name and Context into it... */
96         bContext *C = (bContext *)BPy_GetContext();
97
98         if (C == NULL) {
99                 PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
100                 return NULL;
101         }
102
103         if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
104                 return NULL;
105
106         ot = WM_operatortype_find(opname, true);
107
108         if (ot == NULL) {
109                 PyErr_Format(PyExc_AttributeError,
110                              "Polling operator \"bpy.ops.%s\" error, "
111                              "could not be found", opname);
112                 return NULL;
113         }
114
115         if (context_str) {
116                 if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
117                         char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
118                         PyErr_Format(PyExc_TypeError,
119                                      "Calling operator \"bpy.ops.%s.poll\" error, "
120                                      "expected a string enum in (%s)",
121                                      opname, enum_str);
122                         MEM_freeN(enum_str);
123                         return NULL;
124                 }
125         }
126
127         if (context_dict == NULL || context_dict == Py_None) {
128                 context_dict = NULL;
129         }
130         else if (!PyDict_Check(context_dict)) {
131                 PyErr_Format(PyExc_TypeError,
132                              "Calling operator \"bpy.ops.%s.poll\" error, "
133                              "custom context expected a dict or None, got a %.200s",
134                              opname, Py_TYPE(context_dict)->tp_name);
135                 return NULL;
136         }
137
138         context_dict_back = CTX_py_dict_get(C);
139         CTX_py_dict_set(C, (void *)context_dict);
140         Py_XINCREF(context_dict); /* so we done loose it */
141
142         /* main purpose of this function */
143         ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
144
145         /* restore with original context dict, probably NULL but need this for nested operator calls */
146         Py_XDECREF(context_dict);
147         CTX_py_dict_set(C, (void *)context_dict_back);
148
149         return Py_INCREF_RET(ret);
150 }
151
152 static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
153 {
154         wmOperatorType *ot;
155         int error_val = 0;
156         PointerRNA ptr;
157         int operator_ret = OPERATOR_CANCELLED;
158
159         const char *opname;
160         const char *context_str = NULL;
161         PyObject *kw = NULL; /* optional args */
162         PyObject *context_dict = NULL; /* optional args */
163         PyObject *context_dict_back;
164
165         /* note that context is an int, python does the conversion in this case */
166         int context = WM_OP_EXEC_DEFAULT;
167         int is_undo = false;
168
169         /* XXX Todo, work out a better solution for passing on context,
170          * could make a tuple from self and pack the name and Context into it... */
171         bContext *C = (bContext *)BPy_GetContext();
172
173         if (C == NULL) {
174                 PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
175                 return NULL;
176         }
177
178         if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
179                               &opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
180         {
181                 return NULL;
182         }
183
184         ot = WM_operatortype_find(opname, true);
185
186         if (ot == NULL) {
187                 PyErr_Format(PyExc_AttributeError,
188                              "Calling operator \"bpy.ops.%s\" error, "
189                              "could not be found", opname);
190                 return NULL;
191         }
192
193         if (!pyrna_write_check()) {
194                 PyErr_Format(PyExc_RuntimeError,
195                              "Calling operator \"bpy.ops.%s\" error, "
196                              "can't modify blend data in this state (drawing/rendering)",
197                              opname);
198                 return NULL;
199         }
200
201         if (context_str) {
202                 if (RNA_enum_value_from_id(rna_enum_operator_context_items, context_str, &context) == 0) {
203                         char *enum_str = BPy_enum_as_string(rna_enum_operator_context_items);
204                         PyErr_Format(PyExc_TypeError,
205                                      "Calling operator \"bpy.ops.%s\" error, "
206                                      "expected a string enum in (%s)",
207                                      opname, enum_str);
208                         MEM_freeN(enum_str);
209                         return NULL;
210                 }
211         }
212
213         if (context_dict == NULL || context_dict == Py_None) {
214                 context_dict = NULL;
215         }
216         else if (!PyDict_Check(context_dict)) {
217                 PyErr_Format(PyExc_TypeError,
218                              "Calling operator \"bpy.ops.%s\" error, "
219                              "custom context expected a dict or None, got a %.200s",
220                              opname, Py_TYPE(context_dict)->tp_name);
221                 return NULL;
222         }
223
224         context_dict_back = CTX_py_dict_get(C);
225
226         CTX_py_dict_set(C, (void *)context_dict);
227         Py_XINCREF(context_dict); /* so we done loose it */
228
229         if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
230                 const char *msg = CTX_wm_operator_poll_msg_get(C);
231                 PyErr_Format(PyExc_RuntimeError,
232                              "Operator bpy.ops.%.200s.poll() %.200s",
233                              opname, msg ? msg : "failed, context is incorrect");
234                 CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
235                 error_val = -1;
236         }
237         else {
238                 WM_operator_properties_create_ptr(&ptr, ot);
239                 WM_operator_properties_sanitize(&ptr, 0);
240
241                 if (kw && PyDict_Size(kw)) {
242                         error_val = pyrna_pydict_to_props(&ptr, kw, false, "Converting py args to operator properties: ");
243                 }
244
245                 if (error_val == 0) {
246                         ReportList *reports;
247
248                         reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
249                         BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */
250
251 #ifdef BPY_RELEASE_GIL
252                         /* release GIL, since a thread could be started from an operator
253                          * that updates a driver */
254                         /* note: I have not seen any examples of code that does this
255                          * so it may not be officially supported but seems to work ok. */
256                         {
257                                 PyThreadState *ts = PyEval_SaveThread();
258 #endif
259
260                                 operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);
261
262 #ifdef BPY_RELEASE_GIL
263                                 /* regain GIL */
264                                 PyEval_RestoreThread(ts);
265                         }
266 #endif
267
268                         error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
269
270                         /* operator output is nice to have in the terminal/console too */
271                         if (!BLI_listbase_is_empty(&reports->list)) {
272                                 Report *report;
273                                 for (report = reports->list.first; report; report = report->next) {
274                                         PySys_WriteStdout("%s: %s\n", report->typestr, report->message);
275                                 }
276                         }
277
278                         BKE_reports_clear(reports);
279                         if ((reports->flag & RPT_FREE) == 0) {
280                                 MEM_freeN(reports);
281                         }
282                         else {
283                                 /* The WM is now responsible for running the modal operator,
284                                  * show reports in the info window. */
285                                 reports->flag &= ~RPT_OP_HOLD;
286                         }
287                 }
288
289                 WM_operator_properties_free(&ptr);
290
291 #if 0
292                 /* if there is some way to know an operator takes args we should use this */
293                 {
294                         /* no props */
295                         if (kw != NULL) {
296                                 PyErr_Format(PyExc_AttributeError,
297                                              "Operator \"%s\" does not take any args",
298                                              opname);
299                                 return NULL;
300                         }
301
302                         WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
303                 }
304 #endif
305         }
306
307         /* restore with original context dict, probably NULL but need this for nested operator calls */
308         Py_XDECREF(context_dict);
309         CTX_py_dict_set(C, (void *)context_dict_back);
310
311         if (error_val == -1) {
312                 return NULL;
313         }
314
315         /* when calling  bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
316          * further access will crash blender. setting context is not needed in this case, only calling because this
317          * function corrects bpy.data (internal Main pointer) */
318         BPY_modules_update(C);
319
320         /* needed for when WM_OT_read_factory_settings us called from within a script */
321         bpy_import_main_set(CTX_data_main(C));
322
323         /* return operator_ret as a bpy enum */
324         return pyrna_enum_bitfield_to_py(rna_enum_operator_return_items, operator_ret);
325
326 }
327
328 static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
329 {
330         wmOperatorType *ot;
331         PointerRNA ptr;
332
333         const char *opname;
334         PyObject *kw = NULL; /* optional args */
335         bool all_args = true;
336         bool macro_args = true;
337         int error_val = 0;
338
339         char *buf = NULL;
340         PyObject *pybuf;
341
342         bContext *C = (bContext *)BPy_GetContext();
343
344         if (C == NULL) {
345                 PyErr_SetString(PyExc_RuntimeError, "Context is None, cant get the string representation of this object.");
346                 return NULL;
347         }
348
349         if (!PyArg_ParseTuple(
350                 args, "s|O!O&O&:_bpy.ops.as_string",
351                 &opname, &PyDict_Type, &kw,
352                 PyC_ParseBool, &all_args,
353                 PyC_ParseBool, &macro_args))
354         {
355                 return NULL;
356         }
357
358         ot = WM_operatortype_find(opname, true);
359
360         if (ot == NULL) {
361                 PyErr_Format(PyExc_AttributeError,
362                              "_bpy.ops.as_string: operator \"%.200s\" "
363                              "could not be found", opname);
364                 return NULL;
365         }
366
367         /* WM_operator_properties_create(&ptr, opname); */
368         /* Save another lookup */
369         RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
370
371         if (kw && PyDict_Size(kw)) {
372                 error_val = pyrna_pydict_to_props(&ptr, kw, false, "Converting py args to operator properties: ");
373         }
374
375         if (error_val == 0)
376                 buf = WM_operator_pystring_ex(C, NULL, all_args, macro_args, ot, &ptr);
377
378         WM_operator_properties_free(&ptr);
379
380         if (error_val == -1) {
381                 return NULL;
382         }
383
384         if (buf) {
385                 pybuf = PyUnicode_FromString(buf);
386                 MEM_freeN(buf);
387         }
388         else {
389                 pybuf = PyUnicode_FromString("");
390         }
391
392         return pybuf;
393 }
394
395 static PyObject *pyop_dir(PyObject *UNUSED(self))
396 {
397         GHashIterator iter;
398         PyObject *list;
399         int i;
400
401         WM_operatortype_iter(&iter);
402         list = PyList_New(BLI_ghash_len(iter.gh));
403
404         for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
405                 wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
406                 PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname));
407         }
408
409         return list;
410 }
411
412 static PyObject *pyop_getrna_type(PyObject *UNUSED(self), PyObject *value)
413 {
414         wmOperatorType *ot;
415         if ((ot = ot_lookup_from_py_string(value, "get_rna_type")) == NULL) {
416                 return NULL;
417         }
418
419         PointerRNA ptr;
420         RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
421         BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
422         return (PyObject *)pyrna;
423 }
424
425 static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
426 {
427         wmOperatorType *ot;
428
429         if ((ot = ot_lookup_from_py_string(value, "getrna")) == NULL) {
430                 return NULL;
431         }
432
433         /* type */
434         //RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
435
436         /* XXX - should call WM_operator_properties_free */
437         PointerRNA ptr;
438         WM_operator_properties_create_ptr(&ptr, ot);
439         WM_operator_properties_sanitize(&ptr, 0);
440
441         BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
442 #ifdef PYRNA_FREE_SUPPORT
443         pyrna->freeptr = true;
444 #endif
445         return (PyObject *)pyrna;
446 }
447
448 static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
449 {
450         wmOperatorType *ot;
451         if ((ot = ot_lookup_from_py_string(value, "get_instance")) == NULL) {
452                 return NULL;
453         }
454
455         wmOperator *op;
456 #ifdef PYRNA_FREE_SUPPORT
457         op = MEM_callocN(sizeof(wmOperator), __func__);
458 #else
459         op = PyMem_MALLOC(sizeof(wmOperator));
460         memset(op, 0, sizeof(wmOperator));
461 #endif
462         BLI_strncpy(op->idname, ot->idname, sizeof(op->idname)); /* in case its needed */
463         op->type = ot;
464
465         PointerRNA ptr;
466         RNA_pointer_create(NULL, &RNA_Operator, op, &ptr);
467
468         BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
469 #ifdef PYRNA_FREE_SUPPORT
470         pyrna->freeptr = true;
471 #endif
472         op->ptr = &pyrna->ptr;
473
474         return (PyObject *)pyrna;
475 }
476
477 static struct PyMethodDef bpy_ops_methods[] = {
478         {"poll", (PyCFunction) pyop_poll, METH_VARARGS, NULL},
479         {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL},
480         {"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL},
481         {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL},
482         {"get_rna_type", (PyCFunction) pyop_getrna_type, METH_O, NULL},
483         {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL},           /* only for introspection, leaks memory */
484         {"get_instance", (PyCFunction) pyop_getinstance, METH_O, NULL}, /* only for introspection, leaks memory */
485         {"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL},
486         {NULL, NULL, 0, NULL}
487 };
488
489 static struct PyModuleDef bpy_ops_module = {
490         PyModuleDef_HEAD_INIT,
491         "_bpy.ops",
492         NULL,
493         -1, /* multiple "initialization" just copies the module dict. */
494         bpy_ops_methods,
495         NULL, NULL, NULL, NULL
496 };
497
498 PyObject *BPY_operator_module(void)
499 {
500         PyObject *submodule;
501
502         submodule = PyModule_Create(&bpy_ops_module);
503
504         return submodule;
505 }