/** * Called from Python with the codeObject and line number of the currently executing line * @param codeObject A pointer to the code object whose line is executing * @param lineNo The line number that the code is currently executing, note that * this will be relative to the top of the code that was executed */ void PythonScript::lineNumberChanged(PyObject *codeObject, int lineNo) { if(codeObject == m_CodeFileObject) { sendLineChangeSignal(getRealLineNo(lineNo), false); } }
/** * Constructs a string error message from a syntax exception value object * @param syntaxError An instance of PyExc_SyntaxError */ QString PythonScript::constructSyntaxErrorStr(PyObject *syntaxError) { QString exceptionAsStr = m_pythonEnv->toString(syntaxError); exceptionAsStr = exceptionAsStr.section("(", 0, 0).trimmed(); const QString filename = m_pythonEnv->toString(PyObject_GetAttrString(syntaxError, "filename"), true); int lineno = static_cast<int>(m_pythonEnv->toLong(PyObject_GetAttrString(syntaxError, "lineno"))); #if PY_VERSION_HEX < 0x02070000 // Syntax errors generated by earlier versions seem to have a line number off by 1 lineno -= 1; #endif QString msg; // If the text attribute is not None then an offset in the code can be shown using a ^ character PyObject *textObject = PyObject_GetAttrString(syntaxError, "text"); if(textObject != Py_None) { QString text = m_pythonEnv->toString(textObject, true).trimmed(); int offset = static_cast<int>(m_pythonEnv->toLong(PyObject_GetAttrString(syntaxError, "offset"))); QString offsetMarker = QString(offset-1, ' ') + "^"; msg = "File \"%1\", line %2\n" " %3\n" " %4\n" "SyntaxError: %5"; msg = msg.arg(filename); msg = msg.arg(lineno); msg = msg.arg(text, offsetMarker, exceptionAsStr); } else { msg = "File \"%1\", line %2\n" "SyntaxError: %3"; msg = msg.arg(filename); msg = msg.arg(lineno); msg = msg.arg(exceptionAsStr); } if(filename == identifier().c_str()) { sendLineChangeSignal(lineno, true); } return msg; }
/** * Form a traceback * @param msg The reference to the textstream to accumulate the message * @param traceback A traceback object * @param root If true then this is the root of the traceback */ void PythonScript::tracebackToMsg(QTextStream &msgStream, PyTracebackObject *traceback, bool root) { if (traceback == nullptr) return; msgStream << "\n "; if (root) msgStream << "at"; else msgStream << "caused by"; int lineno = traceback->tb_lineno; QString filename = QString::fromAscii(TO_CSTRING(traceback->tb_frame->f_code->co_filename)); if (filename == identifier().c_str()) { lineno = getRealLineNo(lineno); sendLineChangeSignal(lineno, true); } msgStream << " line " << lineno << " in \'" << filename << "\'"; tracebackToMsg(msgStream, traceback->tb_next, false); }