change to codeload fix python 3.10 plugin loading and usage Signed-off-by: Lucian Cristian <lucian.cristian@gmail.com>
175 lines
6.4 KiB
Diff
175 lines
6.4 KiB
Diff
From a9df45497dc79023ed1864dd9b8e435935220171 Mon Sep 17 00:00:00 2001
|
|
From: dnpwwo <kendel.boul@gmail.com>
|
|
Date: Tue, 1 Mar 2022 13:09:01 +1100
|
|
Subject: [PATCH] BugFix: Linux crash when formating Python exceptions Other:
|
|
Continue code cleanup
|
|
|
|
---
|
|
hardware/plugins/Plugins.cpp | 45 +++++++++++-------------------------
|
|
hardware/plugins/Plugins.h | 3 ++-
|
|
main/EventsPythonModule.cpp | 6 ++---
|
|
3 files changed, 18 insertions(+), 36 deletions(-)
|
|
|
|
--- a/hardware/plugins/Plugins.cpp
|
|
+++ b/hardware/plugins/Plugins.cpp
|
|
@@ -724,13 +724,7 @@ namespace Plugins
|
|
}
|
|
else
|
|
{
|
|
- std::string sTypeText("Unknown");
|
|
- if (pExcept)
|
|
- {
|
|
- PyTypeObject* TypeName = (PyTypeObject*)pExcept;
|
|
- PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
|
|
- sTypeText = (std::string)pName;
|
|
- }
|
|
+ std::string sTypeText("Unknown Error");
|
|
|
|
/* See if we can get a full traceback */
|
|
PyNewRef pModule = PyImport_ImportModule("traceback");
|
|
@@ -738,7 +732,7 @@ namespace Plugins
|
|
{
|
|
PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
|
|
if (pFunc && PyCallable_Check(pFunc)) {
|
|
- PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
|
|
+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, (PyObject*)pExcept, (PyObject*)pValue, (PyObject*)pTraceback, NULL);
|
|
if (pList)
|
|
{
|
|
for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
|
|
@@ -756,16 +750,19 @@ namespace Plugins
|
|
}
|
|
else
|
|
{
|
|
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
|
|
Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
|
|
Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
|
|
Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
|
|
}
|
|
}
|
|
@@ -1950,7 +1947,7 @@ namespace Plugins
|
|
}
|
|
}
|
|
|
|
- void CPlugin::Callback(PyObject *pTarget, const std::string &sHandler, PyObject *pParams)
|
|
+ void CPlugin::Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams)
|
|
{
|
|
try
|
|
{
|
|
@@ -1966,19 +1963,8 @@ namespace Plugins
|
|
PyNewRef pFunc = PyObject_GetAttrString(pTarget, sHandler.c_str());
|
|
if (pFunc && PyCallable_Check(pFunc))
|
|
{
|
|
- module_state *pModState = nullptr;
|
|
- PyBorrowedRef brModule = PyState_FindModule(&DomoticzModuleDef);
|
|
- if (!brModule)
|
|
- {
|
|
- brModule = PyState_FindModule(&DomoticzExModuleDef);
|
|
- }
|
|
-
|
|
- if (brModule)
|
|
- {
|
|
- pModState = ((struct module_state *)PyModule_GetState(brModule));
|
|
- }
|
|
-
|
|
// Store the callback object so the Dump function has context if invoked
|
|
+ module_state* pModState = FindModule();
|
|
if (pModState)
|
|
{
|
|
pModState->lastCallback = pTarget;
|
|
@@ -1986,14 +1972,12 @@ namespace Plugins
|
|
|
|
if (m_bDebug & PDM_QUEUE)
|
|
{
|
|
- PyNewRef pName = PyObject_GetAttrString((PyObject*)(pTarget->ob_type), "__name__");
|
|
- if (pName)
|
|
- Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), (std::string(pName).c_str()));
|
|
+ Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), pTarget.Type().c_str());
|
|
}
|
|
|
|
PyErr_Clear();
|
|
|
|
- // Invokde the callback function
|
|
+ // Invoke the callback function
|
|
PyNewRef pReturnValue = PyObject_CallObject(pFunc, pParams);
|
|
|
|
if (pModState)
|
|
@@ -2020,17 +2004,14 @@ namespace Plugins
|
|
std::string sAttrName = pItem;
|
|
if (sAttrName.substr(0, 2) != "__") // ignore system stuff
|
|
{
|
|
- if (PyObject_HasAttrString(pTarget, sAttrName.c_str()))
|
|
+ std::string strValue = pTarget.Attribute(sAttrName);
|
|
+ if (strValue.length())
|
|
{
|
|
PyNewRef pValue = PyObject_GetAttrString(pTarget, sAttrName.c_str());
|
|
if (!PyCallable_Check(pValue)) // Filter out methods
|
|
{
|
|
- std::string strValue = pValue;
|
|
- if (strValue.length())
|
|
- {
|
|
- std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
|
|
- Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
|
|
- }
|
|
+ std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
|
|
+ Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
|
|
}
|
|
}
|
|
}
|
|
--- a/hardware/plugins/Plugins.h
|
|
+++ b/hardware/plugins/Plugins.h
|
|
@@ -92,7 +92,7 @@ namespace Plugins {
|
|
void ConnectionWrite(CDirectiveBase *);
|
|
void ConnectionDisconnect(CDirectiveBase *);
|
|
void DisconnectEvent(CEventBase *);
|
|
- void Callback(PyObject* pTarget, const std::string &sHandler, PyObject *pParams);
|
|
+ void Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams);
|
|
void RestoreThread();
|
|
void ReleaseThread();
|
|
void Stop();
|
|
@@ -157,6 +157,7 @@ namespace Plugins {
|
|
m_pObject = pObject;
|
|
};
|
|
std::string Attribute(const char* name);
|
|
+ std::string Attribute(std::string& name) { return Attribute(name.c_str()); };
|
|
std::string Type();
|
|
bool IsDict() { return TypeCheck(Py_TPFLAGS_DICT_SUBCLASS); };
|
|
bool IsList() { return TypeCheck(Py_TPFLAGS_LIST_SUBCLASS); };
|
|
--- a/main/EventsPythonModule.cpp
|
|
+++ b/main/EventsPythonModule.cpp
|
|
@@ -297,7 +297,7 @@ namespace Plugins
|
|
PyBorrowedRef pModule = PythonEventsGetModule();
|
|
if (pModule)
|
|
{
|
|
- PyBorrowedRef pModuleDict = Plugins::PyModule_GetDict(pModule);
|
|
+ PyBorrowedRef pModuleDict = PyModule_GetDict(pModule);
|
|
if (!pModuleDict)
|
|
{
|
|
_log.Log(LOG_ERROR, "Python EventSystem: Failed to open module dictionary.");
|
|
@@ -312,7 +312,7 @@ namespace Plugins
|
|
return;
|
|
}
|
|
|
|
- PyNewRef pDeviceDict = Plugins::PyDict_New();
|
|
+ PyNewRef pDeviceDict = PyDict_New();
|
|
if (PyDict_SetItemString(pModuleDict, "Devices", pDeviceDict) == -1)
|
|
{
|
|
_log.Log(LOG_ERROR, "Python EventSystem: Failed to add Device dictionary.");
|
|
@@ -320,7 +320,7 @@ namespace Plugins
|
|
return;
|
|
}
|
|
|
|
- if (PyType_Ready((PyTypeObject*)Plugins::PDeviceType) < 0)
|
|
+ if (PyType_Ready((PyTypeObject*)PDeviceType) < 0)
|
|
{
|
|
_log.Log(LOG_ERROR, "Python EventSystem: Unable to ready DeviceType Object.");
|
|
PyEval_SaveThread();
|