Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-08-12 04:59:16 +0300
committerHans Goudey <h.goudey@me.com>2020-08-12 04:59:16 +0300
commitef11238c743e6985fe325280fb13e05d6ec27378 (patch)
tree1dd2605a676bee52296535825b99f000a9c255eb /source/blender/python/generic/py_capi_utils.c
parent1f768bbe4145daed111636ca09dd53b25b8d29b5 (diff)
parentec5f39208785c1bbe723054ffe69e1ac2ab470dd (diff)
Merge branch 'master' into property-search-uiproperty-search-ui
Diffstat (limited to 'source/blender/python/generic/py_capi_utils.c')
-rw-r--r--source/blender/python/generic/py_capi_utils.c204
1 files changed, 153 insertions, 51 deletions
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 406dbdafe22..caae5c4e122 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -51,6 +51,10 @@
# include "BLI_math_base.h" /* isfinite() */
#endif
+/* -------------------------------------------------------------------- */
+/** \name Fast Python to C Array Conversion for Primitive Types
+ * \{ */
+
/* array utility function */
int PyC_AsArray_FAST(void *array,
PyObject *value_fast,
@@ -137,11 +141,12 @@ int PyC_AsArray(void *array,
return ret;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Typed Tuple Packing
*
* \note See #PyC_Tuple_Pack_* macros that take multiple arguments.
- *
* \{ */
/* array utility function */
@@ -192,6 +197,10 @@ PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Tuple/List Filling
+ * \{ */
+
/**
* Caller needs to ensure tuple is uninitialized.
* Handy for filling a tuple with None for eg.
@@ -218,6 +227,12 @@ void PyC_List_Fill(PyObject *list, PyObject *value)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Bool/Enum Argument Parsing
+ * \{ */
+
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*
@@ -274,8 +289,16 @@ int PyC_CheckArgs_DeepCopy(PyObject *args)
return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
}
+/** \} */
+
#ifndef MATH_STANDALONE
+/* -------------------------------------------------------------------- */
+/** \name Simple Printing (for debugging)
+ *
+ * These are useful to run directly from a debugger to be able to inspect the state.
+ * \{ */
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
{
@@ -352,14 +375,33 @@ void PyC_StackSpit(void)
fprintf(stderr, "python line lookup failed, interpreter inactive\n");
return;
}
- else {
- /* lame but handy */
- PyGILState_STATE gilstate = PyGILState_Ensure();
- PyRun_SimpleString("__import__('traceback').print_stack()");
- PyGILState_Release(gilstate);
+
+ /* lame but handy */
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+ PyRun_SimpleString("__import__('traceback').print_stack()");
+ PyGILState_Release(gilstate);
+}
+
+void PyC_StackPrint(/* FILE */ void *fp)
+{
+ PyThreadState *tstate = PyGILState_GetThisThreadState();
+ if (tstate != NULL && tstate->frame != NULL) {
+ PyFrameObject *frame = tstate->frame;
+ do {
+ const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
+ const char *filename = _PyUnicode_AsString(frame->f_code->co_filename);
+ const char *funcname = _PyUnicode_AsString(frame->f_code->co_name);
+ fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname);
+ } while ((frame = frame->f_back));
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Access Current Frame File Name & Line Number
+ * \{ */
+
void PyC_FileAndNum(const char **r_filename, int *r_lineno)
{
PyFrameObject *frame;
@@ -419,6 +461,12 @@ void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
PyC_FileAndNum(r_filename, r_lineno);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Object Access Utilities
+ * \{ */
+
/* Would be nice if python had this built in */
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
{
@@ -447,6 +495,12 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
return item;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Frozen Set Creation
+ * \{ */
+
PyObject *PyC_FrozenSetFromStrings(const char **strings)
{
const char **str;
@@ -463,6 +517,12 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Utilities
+ * \{ */
+
/**
* Similar to #PyErr_Format(),
*
@@ -528,6 +588,12 @@ void PyC_Err_PrintWithFunc(PyObject *py_func)
_PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Buffer Access
+ * \{ */
+
/* returns the exception string as a new PyUnicode object, depends on external traceback module */
# if 0
@@ -673,6 +739,14 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
return string_io_buf;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Unicode Conversion
+ *
+ * In some cases we need to coerce strings, avoid doing this inline.
+ * \{ */
+
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
{
@@ -685,22 +759,20 @@ const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObjec
* chars since blender doesn't limit this */
return result;
}
- else {
- PyErr_Clear();
- if (PyBytes_Check(py_str)) {
- *size = PyBytes_GET_SIZE(py_str);
- return PyBytes_AS_STRING(py_str);
- }
- else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- *size = PyBytes_GET_SIZE(*coerce);
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* leave error raised from EncodeFS */
- return NULL;
- }
+ PyErr_Clear();
+
+ if (PyBytes_Check(py_str)) {
+ *size = PyBytes_GET_SIZE(py_str);
+ return PyBytes_AS_STRING(py_str);
+ }
+ if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ *size = PyBytes_GET_SIZE(*coerce);
+ return PyBytes_AS_STRING(*coerce);
}
+
+ /* leave error raised from EncodeFS */
+ return NULL;
}
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
@@ -714,20 +786,18 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
* chars since blender doesn't limit this. */
return result;
}
- else {
- PyErr_Clear();
- if (PyBytes_Check(py_str)) {
- return PyBytes_AS_STRING(py_str);
- }
- else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* leave error raised from EncodeFS */
- return NULL;
- }
+ PyErr_Clear();
+
+ if (PyBytes_Check(py_str)) {
+ return PyBytes_AS_STRING(py_str);
}
+ if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ return PyBytes_AS_STRING(*coerce);
+ }
+
+ /* leave error raised from EncodeFS */
+ return NULL;
}
PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
@@ -738,12 +808,11 @@ PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
* chars since blender doesn't limit this */
return result;
}
- else {
- PyErr_Clear();
- /* this means paths will always be accessible once converted, on all OS's */
- result = PyUnicode_DecodeFSDefaultAndSize(str, size);
- return result;
- }
+
+ PyErr_Clear();
+ /* this means paths will always be accessible once converted, on all OS's */
+ result = PyUnicode_DecodeFSDefaultAndSize(str, size);
+ return result;
}
PyObject *PyC_UnicodeFromByte(const char *str)
@@ -751,6 +820,12 @@ PyObject *PyC_UnicodeFromByte(const char *str)
return PyC_UnicodeFromByteAndSize(str, strlen(str));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Name Space Creation/Manipulation
+ * \{ */
+
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
@@ -816,6 +891,12 @@ void PyC_MainModule_Restore(PyObject *main_mod)
Py_XDECREF(main_mod);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
/**
* - Must be called before #Py_Initialize.
* - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`.
@@ -867,6 +948,12 @@ bool PyC_IsInterpreterActive(void)
return (PyThreadState_GetDict() != NULL);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
/* Would be nice if python had this built in
* See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
*/
@@ -1043,15 +1130,22 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
return result;
}
- else {
- PyErr_Format(PyExc_TypeError,
- "expected '%.200s' type found '%.200s' instead",
- type_name,
- Py_TYPE(value)->tp_name);
- return NULL;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "expected '%.200s' type found '%.200s' instead",
+ type_name,
+ Py_TYPE(value)->tp_name);
+ return NULL;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Flag Set Utilities (#PyC_FlagSet)
+ *
+ * Convert to/from Python set of strings to an int flag.
+ * \{ */
+
PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item)
{
PyObject *py_items = PyList_New(0);
@@ -1152,6 +1246,12 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run String (Evaluate to Primitive Types)
+ * \{ */
+
/**
* \return success
*
@@ -1315,6 +1415,8 @@ bool PyC_RunString_AsString(const char *imports[],
return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
}
+/** \} */
+
#endif /* #ifndef MATH_STANDALONE */
/* -------------------------------------------------------------------- */
@@ -1402,6 +1504,12 @@ uint32_t PyC_Long_AsU32(PyObject *value)
* PyC_Long_AsU64
*/
+#ifdef __GNUC__
+# pragma warning(pop)
+#endif
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Py_buffer Utils
*
@@ -1478,9 +1586,3 @@ bool PyC_StructFmt_type_is_bool(char format)
}
/** \} */
-
-#ifdef __GNUC__
-# pragma warning(pop)
-#endif
-
-/** \} */