Skip to content

Commit

Permalink
Py: make FreeCAD 0.v20 to compile with Py3.11
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Aug 30, 2022
1 parent 882ba47 commit 6395465
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/Base/ConsoleObserver.cpp
Expand Up @@ -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]) {
Expand Down
56 changes: 56 additions & 0 deletions src/Base/Interpreter.cpp
Expand Up @@ -524,6 +524,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()) {
Expand Down Expand Up @@ -566,6 +567,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()
{
Expand Down
4 changes: 4 additions & 0 deletions src/Base/PyObjectBase.cpp
Expand Up @@ -60,7 +60,11 @@ PyObjectBase::PyObjectBase(void* p,PyTypeObject *T)
, baseProxy(nullptr)
, attrDict(nullptr)
{
#if PY_VERSION_HEX < 0x030b0000
Py_TYPE(this) = T;
#else
this->ob_type = T;
#endif
_Py_NewReference(this);
#ifdef FC_LOGPYOBJECTS
Base::Console().Log("PyO+: %s (%p)\n",T->tp_name, this);
Expand Down
10 changes: 9 additions & 1 deletion src/Base/PyTools.c
Expand Up @@ -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


/*****************************************************************************
Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/Gui/Command.cpp
Expand Up @@ -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) {
Expand Down
17 changes: 15 additions & 2 deletions src/Gui/PythonDebugger.cpp
Expand Up @@ -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
Expand All @@ -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++;
Expand All @@ -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);
Expand Down

0 comments on commit 6395465

Please sign in to comment.