| 56 | } |
| 57 | |
| 58 | static char *py_get_string_attr(PyObject *py_obj, const char *attr) |
| 59 | { |
| 60 | PyObject *py_str, *py_bytes; |
| 61 | char *str = NULL; |
| 62 | |
| 63 | /* Note: Caller already ran PyGILState_Ensure(). */ |
| 64 | |
| 65 | if (!py_obj) |
| 66 | return NULL; |
| 67 | |
| 68 | py_str = PyObject_GetAttrString(py_obj, attr); |
| 69 | if (!py_str || !PyUnicode_Check(py_str)) |
| 70 | goto cleanup; |
| 71 | |
| 72 | py_bytes = PyUnicode_AsUTF8String(py_str); |
| 73 | if (!py_bytes) |
| 74 | goto cleanup; |
| 75 | |
| 76 | str = g_strdup(PyBytes_AsString(py_bytes)); |
| 77 | Py_DECREF(py_bytes); |
| 78 | |
| 79 | cleanup: |
| 80 | Py_XDECREF(py_str); |
| 81 | if (!str) { |
| 82 | PyErr_Clear(); |
| 83 | srd_err("Failed to get object attribute %s.", attr); |
| 84 | } |
| 85 | |
| 86 | return str; |
| 87 | } |
| 88 | |
| 89 | /** @private */ |
| 90 | SRD_PRIV void srd_exception_catch(char **error, const char *format, ...) |
no outgoing calls
no test coverage detected