Skip to content

Commit ee67b85

Browse files
committed
When we hit an exception, pass the line number of the top-of-stack
* This allows us to update the current line highlight before stopping.
1 parent 87ef595 commit ee67b85

File tree

5 files changed

+36
-19
lines changed

5 files changed

+36
-19
lines changed

qrenderdoc/Code/pyrenderdoc/PythonContext.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static PyMethodDef OutputRedirector_methods[] = {
149149

150150
PyObject *PythonContext::main_dict = NULL;
151151

152-
void FetchException(QString &typeStr, QString &valueStr, QList<QString> &frames)
152+
void FetchException(QString &typeStr, QString &valueStr, int &finalLine, QList<QString> &frames)
153153
{
154154
PyObject *exObj = NULL, *valueObj = NULL, *tracebackObj = NULL;
155155

@@ -184,14 +184,21 @@ void FetchException(QString &typeStr, QString &valueStr, QList<QString> &frames)
184184
PyObject *args = Py_BuildValue("(N)", tracebackObj);
185185
PyObject *formattedTB = PyObject_CallObject(func, args);
186186

187+
PyTracebackObject *tb = (PyTracebackObject *)tracebackObj;
188+
189+
while(tb->tb_next)
190+
tb = tb->tb_next;
191+
192+
finalLine = tb->tb_lineno;
193+
187194
if(formattedTB)
188195
{
189196
Py_ssize_t size = PyList_Size(formattedTB);
190197
for(Py_ssize_t i = 0; i < size; i++)
191198
{
192199
PyObject *el = PyList_GetItem(formattedTB, i);
193200

194-
frames << ToQStr(el);
201+
frames << ToQStr(el).trimmed();
195202
}
196203

197204
Py_DecRef(formattedTB);
@@ -473,7 +480,8 @@ void PythonContext::executeString(const QString &filename, const QString &source
473480
{
474481
emit exception(
475482
lit("SystemError"),
476-
tr("Python integration failed to initialise, see diagnostic log for more information."), {});
483+
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
484+
{});
477485
return;
478486
}
479487

@@ -519,18 +527,19 @@ void PythonContext::executeString(const QString &filename, const QString &source
519527

520528
QString typeStr;
521529
QString valueStr;
530+
int finalLine = -1;
522531
QList<QString> frames;
523532
bool caughtException = (ret == NULL);
524533

525534
if(caughtException)
526-
FetchException(typeStr, valueStr, frames);
535+
FetchException(typeStr, valueStr, finalLine, frames);
527536

528537
Py_XDECREF(ret);
529538

530539
PyGILState_Release(gil);
531540

532541
if(caughtException)
533-
emit exception(typeStr, valueStr, frames);
542+
emit exception(typeStr, valueStr, finalLine, frames);
534543
}
535544

536545
void PythonContext::executeString(const QString &source, bool interactive)
@@ -544,7 +553,8 @@ void PythonContext::executeFile(const QString &filename)
544553

545554
if(!f.exists())
546555
{
547-
emit exception(lit("FileNotFoundError"), tr("No such file or directory: %1").arg(filename), {});
556+
emit exception(lit("FileNotFoundError"), tr("No such file or directory: %1").arg(filename), -1,
557+
{});
548558
return;
549559
}
550560

@@ -556,7 +566,7 @@ void PythonContext::executeFile(const QString &filename)
556566
}
557567
else
558568
{
559-
emit exception(lit("IOError"), QFormatStr("%1: %2").arg(f.errorString()).arg(filename), {});
569+
emit exception(lit("IOError"), QFormatStr("%1: %2").arg(f.errorString()).arg(filename), -1, {});
560570
}
561571
}
562572

@@ -566,7 +576,8 @@ void PythonContext::setGlobal(const char *varName, const char *typeName, void *o
566576
{
567577
emit exception(
568578
lit("SystemError"),
569-
tr("Python integration failed to initialise, see diagnostic log for more information."), {});
579+
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
580+
{});
570581
return;
571582
}
572583

@@ -587,7 +598,7 @@ void PythonContext::setGlobal(const char *varName, const char *typeName, void *o
587598
emit exception(lit("RuntimeError"), tr("Failed to set variable '%1' of type '%2'")
588599
.arg(QString::fromUtf8(varName))
589600
.arg(QString::fromUtf8(typeName)),
590-
{});
601+
-1, {});
591602
return;
592603
}
593604

@@ -694,7 +705,8 @@ void PythonContext::setPyGlobal(const char *varName, PyObject *obj)
694705
{
695706
emit exception(
696707
lit("SystemError"),
697-
tr("Python integration failed to initialise, see diagnostic log for more information."), {});
708+
tr("Python integration failed to initialise, see diagnostic log for more information."), -1,
709+
{});
698710
return;
699711
}
700712

@@ -711,7 +723,7 @@ void PythonContext::setPyGlobal(const char *varName, PyObject *obj)
711723
return;
712724

713725
emit exception(lit("RuntimeError"),
714-
tr("Failed to set variable '%1'").arg(QString::fromUtf8(varName)), {});
726+
tr("Failed to set variable '%1'").arg(QString::fromUtf8(varName)), -1, {});
715727
}
716728

717729
void PythonContext::outstream_del(PyObject *self)
@@ -821,13 +833,14 @@ extern "C" void HandleException(PyObject *global_handle)
821833
{
822834
QString typeStr;
823835
QString valueStr;
836+
int finalLine = -1;
824837
QList<QString> frames;
825838

826-
FetchException(typeStr, valueStr, frames);
839+
FetchException(typeStr, valueStr, finalLine, frames);
827840

828841
OutputRedirector *redirector = (OutputRedirector *)global_handle;
829-
if(redirector->context)
830-
emit redirector->context->exception(typeStr, valueStr, frames);
842+
if(redirector && redirector->context)
843+
emit redirector->context->exception(typeStr, valueStr, finalLine, frames);
831844
}
832845

833846
extern "C" bool IsThreadBlocking(PyObject *global_handle)

qrenderdoc/Code/pyrenderdoc/PythonContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class PythonContext : public QObject
8080
emit exception(lit("RuntimeError"), tr("Failed to set variable '%1' of type '%2'")
8181
.arg(QString::fromUtf8(varName))
8282
.arg(QString::fromUtf8(typeName)),
83-
{});
83+
-1, {});
8484
}
8585

8686
static PyObject *QWidgetToPy(PyObject *self, QWidget *widget)
@@ -97,7 +97,7 @@ class PythonContext : public QObject
9797
int currentLine() { return location.line; }
9898
signals:
9999
void traceLine(const QString &file, int line);
100-
void exception(const QString &type, const QString &value, QList<QString> frames);
100+
void exception(const QString &type, const QString &value, int finalLine, QList<QString> frames);
101101
void textOutput(bool isStdError, const QString &output);
102102

103103
public slots:

qrenderdoc/Code/qrenderdoc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ int main(int argc, char *argv[])
190190
py.ctx().setGlobal("pyrenderdoc", (ICaptureContext *)&ctx);
191191

192192
QObject::connect(&py.ctx(), &PythonContext::exception,
193-
[](const QString &type, const QString &value, QList<QString> frames) {
193+
[](const QString &type, const QString &value, int, QList<QString> frames) {
194194

195195
QString exString;
196196

qrenderdoc/Windows/PythonShell.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,14 +569,18 @@ void PythonShell::traceLine(const QString &file, int line)
569569
scriptEditor->markerAdd(line > 0 ? line - 1 : 0, CURRENT_MARKER + 1);
570570
}
571571

572-
void PythonShell::exception(const QString &type, const QString &value, QList<QString> frames)
572+
void PythonShell::exception(const QString &type, const QString &value, int finalLine,
573+
QList<QString> frames)
573574
{
574575
QTextEdit *out = ui->scriptOutput;
575576
if(QObject::sender() == (QObject *)interactiveContext)
576577
out = ui->interactiveOutput;
577578

578579
QString exString;
579580

581+
if(finalLine >= 0)
582+
traceLine(QString(), finalLine);
583+
580584
if(!out->toPlainText().endsWith(QLatin1Char('\n')))
581585
exString = lit("\n");
582586
if(!frames.isEmpty())

qrenderdoc/Windows/PythonShell.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private slots:
6262
// manual slots
6363
void interactive_keypress(QKeyEvent *e);
6464
void traceLine(const QString &file, int line);
65-
void exception(const QString &type, const QString &value, QList<QString> frames);
65+
void exception(const QString &type, const QString &value, int finalLine, QList<QString> frames);
6666
void textOutput(bool isStdError, const QString &output);
6767

6868
private:

0 commit comments

Comments
 (0)