Add a helper to dump objects with dir() and bypass swig's repr

This commit is contained in:
baldurk
2020-04-17 17:32:57 +01:00
parent 2980742a3a
commit 91de355955
+81
View File
@@ -258,6 +258,12 @@ TEMPLATE_ARRAY_DECLARE(rdcarray);
%rename("%s") count;
}
%inline %{
extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj);
%}
%extend SDObject {
%feature("docstring") R"(Interprets the object as an integer and returns its value.
Invalid if the object is not actually an integer.
@@ -395,6 +401,81 @@ PyObject *PassNewObjectToPython(const char *type, void *obj)
return SWIG_InternalNewPointerObj(obj, t, SWIG_POINTER_OWN);
}
extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj)
{
void *resptr = NULL;
// for basic types, return the repr directly
if(obj == (PyObject *)&_Py_TrueStruct ||
obj == (PyObject *)&_Py_FalseStruct ||
PyObject_IsInstance(obj, (PyObject*)&_PyNone_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyFloat_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyLong_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyBytes_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyUnicode_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyList_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyDict_Type) ||
PyObject_IsInstance(obj, (PyObject*)&PyTuple_Type))
{
return PyObject_Repr(obj);
}
// also for ResourceId
if(SWIG_ConvertPtr(obj, &resptr, SWIGTYPE_p_ResourceId, 0))
{
return PyObject_Repr(obj);
}
PyObject *ret = PyDict_New();
// otherwise iterate over the dir
PyObject *dir = PyObject_Dir(obj);
Py_ssize_t size = PyList_Size(dir);
for(Py_ssize_t i = 0; i < size; i++)
{
PyObject *member = PyList_GetItem(dir, i);
PyObject *bytes = PyUnicode_AsUTF8String(member);
if(!bytes)
continue;
char *buf = NULL;
Py_ssize_t size = 0;
if(PyBytes_AsStringAndSize(bytes, &buf, &size) == 0)
{
rdcstr name;
name.assign(buf, size);
if(name.beginsWith("__") || name == "this" || name == "thisown" || name == "acquire")
{
// skip this member, it's internal
}
else
{
PyObject *child = PyObject_GetAttr(obj, member);
// don't add callables
if(PyCallable_Check(child) == 0)
{
PyObject *childDump = RENDERDOC_DumpObject(child);
PyDict_SetItem(ret, member, childDump);
Py_XDECREF(childDump);
}
}
}
Py_XDECREF(bytes);
}
Py_XDECREF(dir);
return ret;
}
%}
///////////////////////////////////////////////////////////////////////////////////////////