PyAPI: remove context override argument from bpy.ops

Remove deprecated context override argument to operator execution and
poll() method in favor of context.temp_override().
This commit is contained in:
2023-05-23 14:34:09 +10:00
parent ab5fc46872
commit ac263a9bce
8 changed files with 79 additions and 164 deletions

View File

@@ -60,29 +60,10 @@ static wmOperatorType *ot_lookup_from_py_string(PyObject *value, const char *py_
return ot;
}
static void op_context_override_deprecated_warning(const char *action, const char *opname)
{
if (PyErr_WarnFormat(
PyExc_DeprecationWarning,
/* Use stack level 2 as this call is wrapped by `scripts/modules/bpy/ops.py`,
* An extra stack level is needed to show the warning in the authors script. */
2,
"Passing in context overrides is deprecated in favor of "
"Context.temp_override(..), %s \"%s\"",
action,
opname) < 0)
{
/* The function has no return value, the exception cannot
* be reported to the caller, so just log it. */
PyErr_WriteUnraisable(NULL);
}
}
static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
{
wmOperatorType *ot;
const char *opname;
PyObject *context_dict = NULL; /* optional args */
const char *context_str = NULL;
PyObject *ret;
@@ -97,7 +78,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) {
if (!PyArg_ParseTuple(args, "s|s:_bpy.ops.poll", &opname, &context_str)) {
return NULL;
}
@@ -128,41 +109,9 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
context = context_int;
}
if (ELEM(context_dict, NULL, Py_None)) {
context_dict = NULL;
}
else if (PyDict_Check(context_dict)) {
op_context_override_deprecated_warning("polling", opname);
}
else {
PyErr_Format(PyExc_TypeError,
"Calling operator \"bpy.ops.%s.poll\" error, "
"custom context expected a dict or None, got a %.200s",
opname,
Py_TYPE(context_dict)->tp_name);
return NULL;
}
struct bContext_PyState context_py_state;
if (context_dict != NULL) {
CTX_py_state_push(C, &context_py_state, (void *)context_dict);
Py_INCREF(context_dict); /* so we don't lose it */
}
/* main purpose of this function */
ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
if (context_dict != NULL) {
PyObject *context_dict_test = CTX_py_dict_get(C);
if (context_dict_test != context_dict) {
Py_DECREF(context_dict_test);
}
/* Restore with original context dict,
* probably NULL but need this for nested operator calls. */
Py_DECREF(context_dict);
CTX_py_state_pop(C, &context_py_state);
}
return Py_INCREF_RET(ret);
}
@@ -175,8 +124,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
const char *opname;
const char *context_str = NULL;
PyObject *kw = NULL; /* optional args */
PyObject *context_dict = NULL; /* optional args */
PyObject *kw = NULL; /* optional args */
wmOperatorCallContext context = WM_OP_EXEC_DEFAULT;
int is_undo = false;
@@ -190,14 +138,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
if (!PyArg_ParseTuple(args,
"sO|O!si:_bpy.ops.call",
&opname,
&context_dict,
&PyDict_Type,
&kw,
&context_str,
&is_undo))
if (!PyArg_ParseTuple(
args, "s|O!si:_bpy.ops.call", &opname, &PyDict_Type, &kw, &context_str, &is_undo))
{
return NULL;
}
@@ -237,32 +179,6 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
context = context_int;
}
if (ELEM(context_dict, NULL, Py_None)) {
context_dict = NULL;
}
else if (PyDict_Check(context_dict)) {
op_context_override_deprecated_warning("calling", opname);
}
else {
PyErr_Format(PyExc_TypeError,
"Calling operator \"bpy.ops.%s\" error, "
"custom context expected a dict or None, got a %.200s",
opname,
Py_TYPE(context_dict)->tp_name);
return NULL;
}
/**
* It might be that there is already a Python context override. We don't want to remove that
* except when this operator call sets a new override explicitly. This is necessary so that
* called operator runs in the same context as the calling code by default.
*/
struct bContext_PyState context_py_state;
if (context_dict != NULL) {
CTX_py_state_push(C, &context_py_state, (void *)context_dict);
Py_INCREF(context_dict); /* so we don't lose it */
}
if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
bool msg_free = false;
const char *msg = CTX_wm_operator_poll_msg_get(C, &msg_free);
@@ -344,17 +260,6 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
#endif
}
if (context_dict != NULL) {
PyObject *context_dict_test = CTX_py_dict_get(C);
if (context_dict_test != context_dict) {
Py_DECREF(context_dict_test);
}
/* Restore with original context dict,
* probably NULL but need this for nested operator calls. */
Py_DECREF(context_dict);
CTX_py_state_pop(C, &context_py_state);
}
if (error_val == -1) {
return NULL;
}