Selaa lähdekoodia

pstats: Fix exception when `__module__` is a descriptor

This comes up when using metaclasses

Fixes #1505
rdb 2 vuotta sitten
vanhempi
sitoutus
94ebd7c953
1 muutettua tiedostoa jossa 16 lisäystä ja 3 poistoa
  1. 16 3
      panda/src/pstatclient/pStatClient_ext.cxx

+ 16 - 3
panda/src/pstatclient/pStatClient_ext.cxx

@@ -181,10 +181,23 @@ make_c_function_collector(PyCFunctionObject *meth) {
     } else {
     } else {
       // If there's no module name, we need to get it from __module__.
       // If there's no module name, we need to get it from __module__.
       PyObject *py_mod_name = cls->tp_dict ? PyDict_GetItemString(cls->tp_dict, "__module__") : nullptr;
       PyObject *py_mod_name = cls->tp_dict ? PyDict_GetItemString(cls->tp_dict, "__module__") : nullptr;
-      const char *mod_name;
+      const char *mod_name = nullptr;
       if (py_mod_name != nullptr) {
       if (py_mod_name != nullptr) {
-        mod_name = PyUnicode_AsUTF8(py_mod_name);
-      } else {
+        if (PyUnicode_Check(py_mod_name)) {
+          mod_name = PyUnicode_AsUTF8(py_mod_name);
+        } else {
+          // Might be a descriptor.
+          py_mod_name = PyObject_GetAttrString(meth->m_self, "__module__");
+          if (py_mod_name != nullptr) {
+            if (PyUnicode_Check(py_mod_name)) {
+              mod_name = PyUnicode_AsUTF8(py_mod_name);
+            }
+            Py_DECREF(py_mod_name);
+          }
+          else PyErr_Clear();
+        }
+      }
+      if (mod_name == nullptr) {
         // Is it a built-in, like int or dict?
         // Is it a built-in, like int or dict?
         PyObject *builtins = PyEval_GetBuiltins();
         PyObject *builtins = PyEval_GetBuiltins();
         if (PyDict_GetItemString(builtins, cls->tp_name) == (PyObject *)cls) {
         if (PyDict_GetItemString(builtins, cls->tp_name) == (PyObject *)cls) {