237 lines
8.3 KiB
Diff
237 lines
8.3 KiB
Diff
|
From 1ae55905ba7e89278bf656ebcc57ea1088e8fa44 Mon Sep 17 00:00:00 2001
|
||
|
From: wmayer <wmayer@users.sourceforge.net>
|
||
|
Date: Fri, 1 Jul 2022 17:54:50 +0200
|
||
|
Subject: [PATCH] Py: make FreeCAD to compile with Py3.11
|
||
|
|
||
|
---
|
||
|
src/Base/ConsoleObserver.cpp | 6 ++++
|
||
|
src/Base/Interpreter.cpp | 56 ++++++++++++++++++++++++++++++++++++
|
||
|
src/Base/PyObjectBase.cpp | 4 +++
|
||
|
src/Base/PyTools.c | 10 ++++++-
|
||
|
src/Gui/Command.cpp | 7 +++++
|
||
|
src/Gui/PythonDebugger.cpp | 17 +++++++++--
|
||
|
6 files changed, 97 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/src/Base/ConsoleObserver.cpp b/src/Base/ConsoleObserver.cpp
|
||
|
index c6428a7f18be..ab3b3e9157b1 100644
|
||
|
--- a/src/Base/ConsoleObserver.cpp
|
||
|
+++ b/src/Base/ConsoleObserver.cpp
|
||
|
@@ -266,7 +266,13 @@ std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int
|
||
|
PyFrameObject* frame = PyEval_GetFrame();
|
||
|
if (frame) {
|
||
|
line = PyFrame_GetLineNumber(frame);
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
src = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||
|
+#else
|
||
|
+ PyCodeObject* code = PyFrame_GetCode(frame);
|
||
|
+ src = PyUnicode_AsUTF8(code->co_filename);
|
||
|
+ Py_DECREF(code);
|
||
|
+#endif
|
||
|
}
|
||
|
}
|
||
|
if (print_src && src && src[0]) {
|
||
|
diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp
|
||
|
index 2bacea30cbb7..5a476094b749 100644
|
||
|
--- a/src/Base/Interpreter.cpp
|
||
|
+++ b/src/Base/Interpreter.cpp
|
||
|
@@ -523,6 +523,7 @@ void InterpreterSingleton::addPythonPath(const char* Path)
|
||
|
list.append(Py::String(Path));
|
||
|
}
|
||
|
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
const char* InterpreterSingleton::init(int argc,char *argv[])
|
||
|
{
|
||
|
if (!Py_IsInitialized()) {
|
||
|
@@ -565,6 +566,61 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
|
||
|
PyGILStateLocker lock;
|
||
|
return Py_EncodeLocale(Py_GetPath(),nullptr);
|
||
|
}
|
||
|
+#else
|
||
|
+namespace {
|
||
|
+void initInterpreter(int argc,char *argv[])
|
||
|
+{
|
||
|
+ PyStatus status;
|
||
|
+ PyConfig config;
|
||
|
+ PyConfig_InitPythonConfig(&config);
|
||
|
+
|
||
|
+ status = PyConfig_SetBytesArgv(&config, argc, argv);
|
||
|
+ if (PyStatus_Exception(status)) {
|
||
|
+ throw Base::RuntimeError("Failed to set config");
|
||
|
+ }
|
||
|
+
|
||
|
+ status = Py_InitializeFromConfig(&config);
|
||
|
+ if (PyStatus_Exception(status)) {
|
||
|
+ throw Base::RuntimeError("Failed to init from config");
|
||
|
+ }
|
||
|
+
|
||
|
+ PyConfig_Clear(&config);
|
||
|
+
|
||
|
+ Py_Initialize();
|
||
|
+ const char* virtualenv = getenv("VIRTUAL_ENV");
|
||
|
+ if (virtualenv) {
|
||
|
+ PyRun_SimpleString(
|
||
|
+ "# Check for virtualenv, and activate if present.\n"
|
||
|
+ "# See https://virtualenv.pypa.io/en/latest/userguide/#using-virtualenv-without-bin-python\n"
|
||
|
+ "import os\n"
|
||
|
+ "import sys\n"
|
||
|
+ "base_path = os.getenv(\"VIRTUAL_ENV\")\n"
|
||
|
+ "if not base_path is None:\n"
|
||
|
+ " activate_this = os.path.join(base_path, \"bin\", \"activate_this.py\")\n"
|
||
|
+ " exec(open(activate_this).read(), {'__file__':activate_this})\n"
|
||
|
+ );
|
||
|
+ }
|
||
|
+}
|
||
|
+}
|
||
|
+const char* InterpreterSingleton::init(int argc,char *argv[])
|
||
|
+{
|
||
|
+ try {
|
||
|
+ if (!Py_IsInitialized()) {
|
||
|
+ initInterpreter(argc, argv);
|
||
|
+
|
||
|
+ PythonStdOutput::init_type();
|
||
|
+ this->_global = PyEval_SaveThread();
|
||
|
+ }
|
||
|
+
|
||
|
+ PyGILStateLocker lock;
|
||
|
+ return Py_EncodeLocale(Py_GetPath(),nullptr);
|
||
|
+ }
|
||
|
+ catch (const Base::Exception& e) {
|
||
|
+ e.ReportException();
|
||
|
+ throw;
|
||
|
+ }
|
||
|
+}
|
||
|
+#endif
|
||
|
|
||
|
void InterpreterSingleton::replaceStdOutput()
|
||
|
{
|
||
|
diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp
|
||
|
index 773a61b259b3..343ab26999f6 100644
|
||
|
--- a/src/Base/PyObjectBase.cpp
|
||
|
+++ b/src/Base/PyObjectBase.cpp
|
||
|
@@ -60,7 +60,11 @@ PyObjectBase::PyObjectBase(void* p,PyTypeObject *T)
|
||
|
, baseProxy(nullptr)
|
||
|
, attrDict(nullptr)
|
||
|
{
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
Py_TYPE(this) = T;
|
||
|
+#else
|
||
|
+ Py_SET_TYPE(this, T);
|
||
|
+#endif
|
||
|
_Py_NewReference(this);
|
||
|
#ifdef FC_LOGPYOBJECTS
|
||
|
Base::Console().Log("PyO+: %s (%p)\n",T->tp_name, this);
|
||
|
diff --git a/src/Base/PyTools.c b/src/Base/PyTools.c
|
||
|
index 71569e26a200..492d0c8563a4 100644
|
||
|
--- a/src/Base/PyTools.c
|
||
|
+++ b/src/Base/PyTools.c
|
||
|
@@ -15,8 +15,10 @@ is provided on an as is basis, without warranties of any kind.
|
||
|
#include <string.h>
|
||
|
#include <assert.h>
|
||
|
#include <compile.h>
|
||
|
-#include <eval.h>
|
||
|
#include <frameobject.h>
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
+#include <eval.h>
|
||
|
+#endif
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
@@ -310,7 +312,13 @@ void PP_Fetch_Error_Text()
|
||
|
if(!frame)
|
||
|
return;
|
||
|
int line = PyFrame_GetLineNumber(frame);
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
const char *file = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||
|
+#else
|
||
|
+ PyCodeObject* code = PyFrame_GetCode(frame);
|
||
|
+ const char *file = PyUnicode_AsUTF8(code->co_filename);
|
||
|
+ Py_DECREF(code);
|
||
|
+#endif
|
||
|
#ifdef FC_OS_WIN32
|
||
|
const char *_f = strstr(file, "\\src\\");
|
||
|
#else
|
||
|
diff --git a/src/Gui/Command.cpp b/src/Gui/Command.cpp
|
||
|
index c9568e8f0e69..cf555439fcd2 100644
|
||
|
--- a/src/Gui/Command.cpp
|
||
|
+++ b/src/Gui/Command.cpp
|
||
|
@@ -657,8 +657,15 @@ void Command::printPyCaller() {
|
||
|
if(!frame)
|
||
|
return;
|
||
|
int line = PyFrame_GetLineNumber(frame);
|
||
|
+#if PY_VERSION_HEX < 0x030b0000
|
||
|
const char *file = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||
|
printCaller(file?file:"<no file>",line);
|
||
|
+#else
|
||
|
+ PyCodeObject* code = PyFrame_GetCode(frame);
|
||
|
+ const char* file = PyUnicode_AsUTF8(code->co_filename);
|
||
|
+ printCaller(file?file:"<no file>",line);
|
||
|
+ Py_DECREF(code);
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
void Command::printCaller(const char *file, int line) {
|
||
|
diff --git a/src/Gui/PythonDebugger.cpp b/src/Gui/PythonDebugger.cpp
|
||
|
index 7e731a9dd6af..cd44e9b1c233 100644
|
||
|
--- a/src/Gui/PythonDebugger.cpp
|
||
|
+++ b/src/Gui/PythonDebugger.cpp
|
||
|
@@ -563,6 +563,14 @@ void PythonDebugger::hideDebugMarker(const QString& fn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+#if PY_VERSION_HEX < 0x030900B1
|
||
|
+static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
|
||
|
+{
|
||
|
+ Py_INCREF(frame->f_code);
|
||
|
+ return frame->f_code;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
// http://www.koders.com/cpp/fidBA6CD8A0FE5F41F1464D74733D9A711DA257D20B.aspx?s=PyEval_SetTrace
|
||
|
// http://code.google.com/p/idapython/source/browse/trunk/python.cpp
|
||
|
// http://www.koders.com/cpp/fid191F7B13CF73133935A7A2E18B7BF43ACC6D1784.aspx?s=PyEval_SetTrace
|
||
|
@@ -578,7 +586,9 @@ int PythonDebugger::tracer_callback(PyObject *obj, PyFrameObject *frame, int wha
|
||
|
|
||
|
//no = frame->f_tstate->recursion_depth;
|
||
|
//std::string funcname = PyString_AsString(frame->f_code->co_name);
|
||
|
- QString file = QString::fromUtf8(PyUnicode_AsUTF8(frame->f_code->co_filename));
|
||
|
+ PyCodeObject* code = PyFrame_GetCode(frame);
|
||
|
+ QString file = QString::fromUtf8(PyUnicode_AsUTF8(code->co_filename));
|
||
|
+ Py_DECREF(code);
|
||
|
switch (what) {
|
||
|
case PyTrace_CALL:
|
||
|
self->depth++;
|
||
|
@@ -592,7 +602,10 @@ int PythonDebugger::tracer_callback(PyObject *obj, PyFrameObject *frame, int wha
|
||
|
//PyObject *str;
|
||
|
//str = PyObject_Str(frame->f_code->co_filename);
|
||
|
//no = frame->f_lineno;
|
||
|
- int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
|
||
|
+ PyCodeObject* f_code = PyFrame_GetCode(frame);
|
||
|
+ int f_lasti = PyFrame_GetLineNumber(frame);
|
||
|
+ int line = PyCode_Addr2Line(f_code, f_lasti);
|
||
|
+ Py_DECREF(f_code);
|
||
|
//if (str) {
|
||
|
// Base::Console().Message("PROFILING: %s:%d\n", PyString_AsString(str), frame->f_lineno);
|
||
|
// Py_DECREF(str);
|
||
|
From 6820e0a9ec85203a6f342ca72a2ff8fd417beaf1 Mon Sep 17 00:00:00 2001
|
||
|
From: wmayer <wmayer@users.sourceforge.net>
|
||
|
Date: Sat, 2 Jul 2022 19:36:27 +0200
|
||
|
Subject: [PATCH] Py3: properly port to Py3.11
|
||
|
|
||
|
---
|
||
|
src/Base/PyObjectBase.cpp | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp
|
||
|
index 343ab26999f6..a8e1b327809b 100644
|
||
|
--- a/src/Base/PyObjectBase.cpp
|
||
|
+++ b/src/Base/PyObjectBase.cpp
|
||
|
@@ -63,7 +63,7 @@ PyObjectBase::PyObjectBase(void* p,PyTypeObject *T)
|
||
|
#if PY_VERSION_HEX < 0x030b0000
|
||
|
Py_TYPE(this) = T;
|
||
|
#else
|
||
|
- Py_SET_TYPE(this, T);
|
||
|
+ this->ob_type = T;
|
||
|
#endif
|
||
|
_Py_NewReference(this);
|
||
|
#ifdef FC_LOGPYOBJECTS
|