Skip to content

Commit cd99272

Browse files
committed
1 parent 933f383 commit cd99272

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

Source/PythonEngine.pas

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ TPythonInterface=class(TDynamicDll)
13341334
PyErr_BadInternalCall: procedure; cdecl;
13351335
PyErr_CheckSignals: function: integer; cdecl;
13361336
PyErr_Clear: procedure; cdecl;
1337-
PyErr_Fetch: procedure( errtype, errvalue, errtraceback: PPPyObject); cdecl;
1337+
PyErr_Fetch: procedure(out errtype, errvalue, errtraceback: PPyObject); cdecl;
13381338
PyErr_NoMemory: function: PPyObject; cdecl;
13391339
PyErr_Occurred: function: PPyObject; cdecl;
13401340
PyErr_Print: procedure; cdecl;
@@ -1732,7 +1732,7 @@ TPythonTraceback = class
17321732
destructor Destroy; override;
17331733

17341734
procedure Clear;
1735-
procedure Refresh;
1735+
procedure Refresh(pytraceback: PPyObject = nil);
17361736
procedure AddItem(const Context, FileName: string; LineNo: Integer);
17371737

17381738
property ItemCount : Integer read GetItemCount;
@@ -2740,6 +2740,8 @@ implementation
27402740
(*******************************************************)
27412741
resourcestring
27422742
SPyConvertionError = 'Conversion Error: %s expects a %s Python object';
2743+
SPyExcStopIteration = 'Stop Iteration';
2744+
SPyExcSystemError = 'Unhandled SystemExit exception. Code: %s';
27432745

27442746
(*******************************************************)
27452747
(** **)
@@ -3853,7 +3855,7 @@ procedure TPythonTraceback.Clear;
38533855
* simply use the method CheckError wich will call PyErr_Print,
38543856
* Traceback.Refresh and RaiseError for you.
38553857
}
3856-
procedure TPythonTraceback.Refresh;
3858+
procedure TPythonTraceback.Refresh(pytraceback: PPyObject);
38573859
var
38583860
tb, tb1 : PPyObject;
38593861
obj : PPyObject;
@@ -3872,7 +3874,9 @@ procedure TPythonTraceback.Refresh;
38723874
limitv := PySys_GetObject('tracebacklimit');
38733875
if Assigned(limitv) and PyLong_Check(limitv) then
38743876
alimit := PyLong_AsLong(limitv);
3875-
tb := PySys_GetObject('last_traceback');
3877+
tb := pytraceback;
3878+
if tb = nil then
3879+
tb := PySys_GetObject('last_traceback');
38763880
tb1 := tb;
38773881
Py_XIncRef(tb1);
38783882
depth := 0;
@@ -4466,10 +4470,9 @@ function TPythonEngine.EvalPyFunction(pyfunc, pyargs:PPyObject): Variant;
44664470
presult := PyEval_CallObjectWithKeywords(pyfunc,pyargs, nil);
44674471
CheckError(False);
44684472
if presult = nil then
4469-
begin
4470-
PyErr_Print;
4471-
RaiseError;
4472-
end
4473+
// should not happen since an exception would have been raised
4474+
// in that case by CheckError
4475+
Result := Null
44734476
else
44744477
begin
44754478
try
@@ -5774,14 +5777,32 @@ procedure TPythonEngine.ListToSet( List : PPyObject; data : Pointer; size : Inte
57745777
end;
57755778

57765779
procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
5780+
procedure ProcessSystemExit;
5781+
var
5782+
errtype, errvalue, errtraceback: PPyObject;
5783+
SErrValue: string;
5784+
begin
5785+
PyErr_Fetch(errtype, errvalue, errtraceback);
5786+
Traceback.Refresh(errtraceback);
5787+
SErrValue := PyObjectAsString(errvalue);
5788+
PyErr_Clear;
5789+
raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]);
5790+
end;
5791+
5792+
var
5793+
PyException: PPyObject;
57775794
begin
5778-
if PyErr_Occurred <> nil then
5795+
PyException := PyErr_Occurred;
5796+
if PyException <> nil then
57795797
begin
5780-
if ACatchStopEx and (PyErr_GivenExceptionMatches(PyErr_Occurred, PyExc_StopIteration^) <> 0) then
5798+
if ACatchStopEx and (PyErr_GivenExceptionMatches(PyException, PyExc_StopIteration^) <> 0) then
57815799
begin
57825800
PyErr_Clear;
5783-
raise EPyStopIteration.Create('Stop iteration');
5801+
raise EPyStopIteration.CreateRes(@SPyExcStopIteration);
57845802
end
5803+
else if PyErr_GivenExceptionMatches(PyException, PyExc_SystemExit^) <> 0 then
5804+
// Special treatment for SystemExit. Calling PyErr_Print would terminate the process
5805+
ProcessSystemExit
57855806
else
57865807
begin
57875808
PyErr_Print;

0 commit comments

Comments
 (0)