Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cd581ae

Browse files
committedApr 13, 2018
Removed PYTHON23
PyInterpreterState and PyThreadState stuctures changed in recent Python versions Improved TPythonThread and updated Demos 11 and 33 TGUIPythonInputOutput should now work with threads if DelayWrites is set. Fixed complilation of PythonVersions.pas
1 parent 11e07af commit cd581ae

File tree

9 files changed

+351
-267
lines changed

9 files changed

+351
-267
lines changed
 

‎PythonForDelphi/Components/Sources/Core/Definition.Inc

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@
2626
// modify the default Python version below, in the Python versions section.
2727
/////////////////////////////////////////////////////////////////////////////
2828

29-
//{$DEFINE PYTHON23}
3029
//{$DEFINE PYTHON24}
31-
{$DEFINE PYTHON25}
32-
//{$DEFINE PYTHON26}
30+
//{$DEFINE PYTHON25}
31+
{$DEFINE PYTHON26`}
3332
//{$DEFINE PYTHON27}
3433
//{$DEFINE PYTHON30}
3534
//{$DEFINE PYTHON31}
@@ -406,11 +405,9 @@
406405
{$IFNDEF PYTHON26}
407406
{$IFNDEF PYTHON25}
408407
{$IFNDEF PYTHON24}
409-
{$IFNDEF PYTHON23}
410408
{---<START OF DEFAULT PYTHON VERSION>---}
411409
{$DEFINE PYTHON27}
412410
{---<END OF DEFAULT PYTHON VERSION>---}
413-
{$ENDIF}
414411
{$ENDIF}
415412
{$ENDIF}
416413
{$ENDIF}
@@ -425,41 +422,32 @@
425422
{$ENDIF}
426423

427424

428-
{$IFDEF PYTHON23}
429-
{$DEFINE PYTHON23_OR_HIGHER}
430-
{$ENDIF}
431425
{$IFDEF PYTHON24}
432-
{$DEFINE PYTHON23_OR_HIGHER}
433426
{$DEFINE PYTHON24_OR_HIGHER}
434427
{$ENDIF}
435428
{$IFDEF PYTHON25}
436-
{$DEFINE PYTHON23_OR_HIGHER}
437429
{$DEFINE PYTHON24_OR_HIGHER}
438430
{$DEFINE PYTHON25_OR_HIGHER}
439431
{$ENDIF}
440432
{$IFDEF PYTHON26}
441-
{$DEFINE PYTHON23_OR_HIGHER}
442433
{$DEFINE PYTHON24_OR_HIGHER}
443434
{$DEFINE PYTHON25_OR_HIGHER}
444435
{$DEFINE PYTHON26_OR_HIGHER}
445436
{$ENDIF}
446437
{$IFDEF PYTHON27}
447-
{$DEFINE PYTHON23_OR_HIGHER}
448438
{$DEFINE PYTHON24_OR_HIGHER}
449439
{$DEFINE PYTHON25_OR_HIGHER}
450440
{$DEFINE PYTHON26_OR_HIGHER}
451441
{$DEFINE PYTHON27_OR_HIGHER}
452442
{$ENDIF}
453443
{$IFDEF PYTHON30}
454-
{$DEFINE PYTHON23_OR_HIGHER}
455444
{$DEFINE PYTHON24_OR_HIGHER}
456445
{$DEFINE PYTHON25_OR_HIGHER}
457446
{$DEFINE PYTHON26_OR_HIGHER}
458447
{$DEFINE PYTHON27_OR_HIGHER}
459448
{$DEFINE PYTHON30_OR_HIGHER}
460449
{$ENDIF}
461450
{$IFDEF PYTHON31}
462-
{$DEFINE PYTHON23_OR_HIGHER}
463451
{$DEFINE PYTHON24_OR_HIGHER}
464452
{$DEFINE PYTHON25_OR_HIGHER}
465453
{$DEFINE PYTHON26_OR_HIGHER}
@@ -468,7 +456,6 @@
468456
{$DEFINE PYTHON31_OR_HIGHER}
469457
{$ENDIF}
470458
{$IFDEF PYTHON32}
471-
{$DEFINE PYTHON23_OR_HIGHER}
472459
{$DEFINE PYTHON24_OR_HIGHER}
473460
{$DEFINE PYTHON25_OR_HIGHER}
474461
{$DEFINE PYTHON26_OR_HIGHER}
@@ -478,7 +465,6 @@
478465
{$DEFINE PYTHON32_OR_HIGHER}
479466
{$ENDIF}
480467
{$IFDEF PYTHON33}
481-
{$DEFINE PYTHON23_OR_HIGHER}
482468
{$DEFINE PYTHON24_OR_HIGHER}
483469
{$DEFINE PYTHON25_OR_HIGHER}
484470
{$DEFINE PYTHON26_OR_HIGHER}
@@ -489,7 +475,6 @@
489475
{$DEFINE PYTHON33_OR_HIGHER}
490476
{$ENDIF}
491477
{$IFDEF PYTHON34}
492-
{$DEFINE PYTHON23_OR_HIGHER}
493478
{$DEFINE PYTHON24_OR_HIGHER}
494479
{$DEFINE PYTHON25_OR_HIGHER}
495480
{$DEFINE PYTHON26_OR_HIGHER}
@@ -501,7 +486,6 @@
501486
{$DEFINE PYTHON34_OR_HIGHER}
502487
{$ENDIF}
503488
{$IFDEF PYTHON35}
504-
{$DEFINE PYTHON23_OR_HIGHER}
505489
{$DEFINE PYTHON24_OR_HIGHER}
506490
{$DEFINE PYTHON25_OR_HIGHER}
507491
{$DEFINE PYTHON26_OR_HIGHER}
@@ -514,7 +498,6 @@
514498
{$DEFINE PYTHON35_OR_HIGHER}
515499
{$ENDIF}
516500
{$IFDEF PYTHON36}
517-
{$DEFINE PYTHON23_OR_HIGHER}
518501
{$DEFINE PYTHON24_OR_HIGHER}
519502
{$DEFINE PYTHON25_OR_HIGHER}
520503
{$DEFINE PYTHON26_OR_HIGHER}
@@ -528,7 +511,6 @@
528511
{$DEFINE PYTHON36_OR_HIGHER}
529512
{$ENDIF}
530513
{$IFDEF PYTHON37}
531-
{$DEFINE PYTHON23_OR_HIGHER}
532514
{$DEFINE PYTHON24_OR_HIGHER}
533515
{$DEFINE PYTHON25_OR_HIGHER}
534516
{$DEFINE PYTHON26_OR_HIGHER}

‎PythonForDelphi/Components/Sources/Core/PythonEngine.pas

Lines changed: 101 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ interface
121121
PNativeInt = ^NativeInt;
122122
{$ENDIF}
123123

124-
125-
126124
TPythonVersionProp = packed record
127125
DllName : String;
128126
RegVersion : String;
@@ -131,9 +129,8 @@ interface
131129
end;
132130
const
133131
{$IFDEF MSWINDOWS}
134-
PYTHON_KNOWN_VERSIONS: array[1..13] of TPythonVersionProp =
135-
( (DllName: 'python23.dll'; RegVersion: '2.3'; APIVersion: 1012; CanUseLatest: True),
136-
(DllName: 'python24.dll'; RegVersion: '2.4'; APIVersion: 1012; CanUseLatest: True),
132+
PYTHON_KNOWN_VERSIONS: array[1..12] of TPythonVersionProp =
133+
( (DllName: 'python24.dll'; RegVersion: '2.4'; APIVersion: 1012; CanUseLatest: True),
137134
(DllName: 'python25.dll'; RegVersion: '2.5'; APIVersion: 1013; CanUseLatest: True),
138135
(DllName: 'python26.dll'; RegVersion: '2.6'; APIVersion: 1013; CanUseLatest: True),
139136
(DllName: 'python27.dll'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True),
@@ -147,9 +144,8 @@ interface
147144
(DllName: 'python37.dll'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True) );
148145
{$ENDIF}
149146
{$IFDEF LINUX}
150-
PYTHON_KNOWN_VERSIONS: array[1..13] of TPythonVersionProp =
151-
( (DllName: 'libpython2.3.so'; RegVersion: '2.3'; APIVersion: 1012; CanUseLatest: True),
152-
(DllName: 'libpython2.4.so'; RegVersion: '2.4'; APIVersion: 1012; CanUseLatest: True),
147+
PYTHON_KNOWN_VERSIONS: array[1..12] of TPythonVersionProp =
148+
( (DllName: 'libpython2.4.so'; RegVersion: '2.4'; APIVersion: 1012; CanUseLatest: True),
153149
(DllName: 'libpython2.5.so'; RegVersion: '2.5'; APIVersion: 1013; CanUseLatest: True),
154150
(DllName: 'libpython2.6.so'; RegVersion: '2.6'; APIVersion: 1013; CanUseLatest: True),
155151
(DllName: 'libpython2.7.so'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True),
@@ -162,44 +158,41 @@ interface
162158
(DllName: 'libpython3.6.so'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True)
163159
(DllName: 'libpython3.7.so'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True) );
164160
{$ENDIF}
165-
{$IFDEF PYTHON23}
166-
COMPILED_FOR_PYTHON_VERSION_INDEX = 1;
167-
{$ENDIF}
168161
{$IFDEF PYTHON24}
169-
COMPILED_FOR_PYTHON_VERSION_INDEX = 2;
162+
COMPILED_FOR_PYTHON_VERSION_INDEX = 1;
170163
{$ENDIF}
171164
{$IFDEF PYTHON25}
172-
COMPILED_FOR_PYTHON_VERSION_INDEX = 3;
165+
COMPILED_FOR_PYTHON_VERSION_INDEX = 2;
173166
{$ENDIF}
174167
{$IFDEF PYTHON26}
175-
COMPILED_FOR_PYTHON_VERSION_INDEX = 4;
168+
COMPILED_FOR_PYTHON_VERSION_INDEX = 3;
176169
{$ENDIF}
177170
{$IFDEF PYTHON27}
178-
COMPILED_FOR_PYTHON_VERSION_INDEX = 5;
171+
COMPILED_FOR_PYTHON_VERSION_INDEX = 4;
179172
{$ENDIF}
180173
{$IFDEF PYTHON30}
181-
COMPILED_FOR_PYTHON_VERSION_INDEX = 6;
174+
COMPILED_FOR_PYTHON_VERSION_INDEX = 5;
182175
{$ENDIF}
183176
{$IFDEF PYTHON31}
184-
COMPILED_FOR_PYTHON_VERSION_INDEX = 7;
177+
COMPILED_FOR_PYTHON_VERSION_INDEX = 6;
185178
{$ENDIF}
186179
{$IFDEF PYTHON32}
187-
COMPILED_FOR_PYTHON_VERSION_INDEX = 8;
180+
COMPILED_FOR_PYTHON_VERSION_INDEX = 7;
188181
{$ENDIF}
189182
{$IFDEF PYTHON33}
190-
COMPILED_FOR_PYTHON_VERSION_INDEX = 9;
183+
COMPILED_FOR_PYTHON_VERSION_INDEX = 8;
191184
{$ENDIF}
192185
{$IFDEF PYTHON34}
193-
COMPILED_FOR_PYTHON_VERSION_INDEX = 10;
186+
COMPILED_FOR_PYTHON_VERSION_INDEX = 9;
194187
{$ENDIF}
195188
{$IFDEF PYTHON35}
196-
COMPILED_FOR_PYTHON_VERSION_INDEX = 11;
189+
COMPILED_FOR_PYTHON_VERSION_INDEX = 10;
197190
{$ENDIF}
198191
{$IFDEF PYTHON36}
199-
COMPILED_FOR_PYTHON_VERSION_INDEX = 12;
192+
COMPILED_FOR_PYTHON_VERSION_INDEX = 11;
200193
{$ENDIF}
201194
{$IFDEF PYTHON37}
202-
COMPILED_FOR_PYTHON_VERSION_INDEX = 13;
195+
COMPILED_FOR_PYTHON_VERSION_INDEX = 12;
203196
{$ENDIF}
204197
PYT_METHOD_BUFFER_INCREASE = 10;
205198
PYT_MEMBER_BUFFER_INCREASE = 10;
@@ -936,42 +929,78 @@ interface
936929
next : PPyInterpreterState;
937930
tstate_head : PPyThreadState;
938931

939-
modules : PPyObject;
940-
sysdict : PPyObject;
941-
builtins : PPyObject;
932+
// The strucure has changed between versions beyond this point.
933+
// Not safe to use members
934+
// modules : PPyObject;
935+
// sysdict : PPyObject;
936+
// builtins : PPyObject;
942937

943-
checkinterval : integer;
938+
//Spares
939+
is_xxx1 : NativeInt;
940+
is_xxx2 : NativeInt;
941+
is_xxx3 : NativeInt;
942+
is_xxx4 : NativeInt;
943+
is_xxx5 : NativeInt;
944+
is_xxx6 : NativeInt;
945+
is_xxx7 : NativeInt;
946+
is_xxx8 : NativeInt;
947+
is_xxx9 : NativeInt;
944948
end;
945949

946950
// Thread specific information
947951
PyThreadState = {$IFNDEF CPUX64}packed{$ENDIF} record
952+
{prev : PPyThreadState; introduced in python 3.4}
948953
next : PPyThreadState;
949954
interp : PPyInterpreterState;
955+
interp34 : PPyInterpreterState;
950956

951-
frame : PPyFrameObject;
952-
recursion_depth: integer;
953-
ticker : integer;
954-
tracing : integer;
955-
956-
sys_profilefn : Pointer; // c-functions for profile/trace
957-
sys_tracefn : Pointer;
958-
sys_profilefunc: PPyObject;
959-
sys_tracefunc : PPyObject;
960-
961-
curexc_type : PPyObject;
962-
curexc_value : PPyObject;
963-
curexc_traceback: PPyObject;
964-
965-
exc_type : PPyObject;
966-
exc_value : PPyObject;
967-
exc_traceback : PPyObject;
968-
969-
dict : PPyObject;
970-
tick_counter :Integer;
971-
gilstate_counter :Integer;
972-
973-
async_exc :PPyObject; { Asynchronous exception to raise }
974-
thread_id :LongInt; { Thread id where this tstate was created }
957+
// The strucure has changed between versions beyond this point.
958+
// Not safe to use members
959+
//
960+
// frame : PPyFrameObject;
961+
// recursion_depth: integer;
962+
// ticker : integer;
963+
// tracing : integer;
964+
//
965+
// sys_profilefn : Pointer; // c-functions for profile/trace
966+
// sys_tracefn : Pointer;
967+
// sys_profilefunc: PPyObject;
968+
// sys_tracefunc : PPyObject;
969+
//
970+
// curexc_type : PPyObject;
971+
// curexc_value : PPyObject;
972+
// curexc_traceback: PPyObject;
973+
//
974+
// exc_type : PPyObject;
975+
// exc_value : PPyObject;
976+
// exc_traceback : PPyObject;
977+
//
978+
// dict : PPyObject;
979+
// tick_counter :Integer;
980+
// gilstate_counter :Integer;
981+
//
982+
// async_exc :PPyObject; { Asynchronous exception to raise }
983+
// thread_id :LongInt; { Thread id where this tstate was created }
984+
//Spares
985+
ts_xxx1 : NativeInt;
986+
ts_xxx2 : NativeInt;
987+
ts_xxx3 : NativeInt;
988+
ts_xxx4 : NativeInt;
989+
ts_xxx5 : NativeInt;
990+
ts_xxx6 : NativeInt;
991+
ts_xxx7 : NativeInt;
992+
ts_xxx8 : NativeInt;
993+
ts_xxx9 : NativeInt;
994+
ts_xxx10 : NativeInt;
995+
ts_xxx11 : NativeInt;
996+
ts_xxx12 : NativeInt;
997+
ts_xxx13 : NativeInt;
998+
ts_xxx14 : NativeInt;
999+
ts_xxx15 : NativeInt;
1000+
ts_xxx16 : NativeInt;
1001+
ts_xxx17 : NativeInt;
1002+
ts_xxx18 : NativeInt;
1003+
ts_xxx19 : NativeInt;
9751004

9761005
{ XXX signal handlers should also be here }
9771006
end;
@@ -3057,9 +3086,8 @@ TPyVar = class(TPyObject)
30573086
{$HINTS OFF}
30583087
TPythonThread = class(TThread)
30593088
private
3060-
f_savethreadstate: PPyThreadState;
3061-
fInterpreterState: PPyInterpreterState;
30623089
fThreadState: PPyThreadState;
3090+
f_savethreadstate: PPyThreadState;
30633091
fThreadExecMode: TThreadExecMode;
30643092

30653093
// Do not overwrite Execute! Use ExecuteWithPython instead!
@@ -3075,12 +3103,8 @@ TPythonThread = class(TThread)
30753103
procedure Py_Begin_Unblock_Threads;
30763104

30773105
public
3078-
property InterpreterState: PPyInterpreterState read fInterpreterState
3079-
write fInterpreterState
3080-
default nil;
3081-
property ThreadState: PPyThreadState read fThreadState
3082-
write fThreadState;
3083-
property ThreadExecMode: TThreadExecMode read fThreadExecMode;
3106+
property ThreadState : PPyThreadState read fThreadState;
3107+
property ThreadExecMode: TThreadExecMode read fThreadExecMode write fThreadExecMode;
30843108
end;
30853109
{$HINTS ON}
30863110

@@ -4863,10 +4887,17 @@ procedure TPythonEngine.SetInitScript(Value: TStrings);
48634887
function TPythonEngine.GetInterpreterState: PPyInterpreterState;
48644888
var
48654889
res: PPyThreadState;
4890+
MajorVersion : integer;
4891+
MinorVersion : integer;
48664892
begin
4893+
MajorVersion := StrToInt(RegVersion[1]);
4894+
MinorVersion := StrToInt(RegVersion[3]);
48674895
if Assigned(PyThreadState_Get) then begin
4868-
res:= PyThreadState_Get;
4869-
Result := res^.interp;
4896+
res:= PyThreadState_Get();
4897+
if (MajorVersion > 3) or ((MajorVersion = 3) and (MinorVersion >= 4)) then
4898+
Result := res^.interp34
4899+
else
4900+
Result := res^.interp;
48704901
end else
48714902
Result := nil;
48724903
end;
@@ -9404,29 +9435,22 @@ procedure TPyVar.SetValueFromVariant( const value : Variant );
94049435

94059436
procedure TPythonThread.Execute;
94069437
var
9407-
withinterp: Boolean;
94089438
global_state : PPyThreadState;
94099439
gilstate : PyGILState_STATE;
94109440
begin
9411-
withinterp := Assigned( fInterpreterState);
94129441
with GetPythonEngine do
94139442
begin
9414-
if withinterp then
9443+
if fThreadExecMode = emNewState then
94159444
begin
9416-
fThreadExecMode := emNewState;
9417-
fThreadState := PyThreadState_New( fInterpreterState);
9418-
if Assigned(fThreadState) then
9419-
begin
9420-
PyEval_AcquireThread(fThreadState);
9445+
gilstate := PyGILState_Ensure();
9446+
try
9447+
fThreadState := GetThreadState;
94219448
ExecuteWithPython;
9422-
PyEval_ReleaseThread( fThreadState);
9423-
PyThreadState_Clear( fThreadState);
9424-
PyThreadState_Delete( fThreadState);
9425-
end else
9426-
raise EPythonError.Create( 'Could not create a new thread state');
9427-
end else {withinterp}
9449+
finally
9450+
PyGILState_Release(gilstate);
9451+
end;
9452+
end else {fThreadExecMode}
94289453
begin
9429-
fThreadExecMode := emNewInterpreter;
94309454
gilstate := PyGILState_Ensure();
94319455
global_state := PyThreadState_Get;
94329456
PyThreadState_Swap(nil);
@@ -9488,7 +9512,7 @@ function pyio_write(self, args : PPyObject) : PPyObject;
94889512
if GetCurrentThreadId <> MainThreadId then
94899513
with GetPythonEngine do
94909514
begin
9491-
if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') then
9515+
if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') and not IO.DelayWrites then
94929516
begin
94939517
Result := GetPythonEngine.ReturnNone;
94949518
Exit;
@@ -9531,19 +9555,15 @@ function pyio_read(self, args : PPyObject) : PPyObject;
95319555
if Assigned(IO) then
95329556
if IO.UnicodeIO then begin
95339557
Widetxt := IO.ReceiveUniData;
9534-
// KV!!!!!!
95359558
if PyErr_Occurred <> nil then
95369559
Result := nil
95379560
else
9538-
// KV!!!!!!
95399561
Result := PyUnicode_FromWideString(PWideChar(Widetxt));
95409562
end else begin
95419563
txt := IO.ReceiveData;
9542-
// KV!!!!!!
95439564
if PyErr_Occurred <> nil then
95449565
Result := nil
95459566
else
9546-
// KV!!!!!!
95479567
Result := PyString_FromString(PAnsiChar(txt));
95489568
end
95499569
else

‎PythonForDelphi/Components/Sources/Core/PythonVersions.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ procedure TPythonVersion.AssignTo(PythonEngine: TPersistent);
114114

115115
function TPythonVersion.GetApiVersion: integer;
116116
begin
117-
if CompareVersions(SysVersion, 2.4) < 0 then
117+
if CompareVersions(SysVersion, '2.4') < 0 then
118118
Result := 1013
119119
else
120120
Result := 1012;

‎PythonForDelphi/Demos/Demo11/SortThds.pas

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ TSortThread = class(TPythonThread)
3838
public
3939
property value[i: integer]: integer read getvalue; default;
4040

41-
constructor Create( ainterp: PPyInterpreterState; script: TStrings;
41+
constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings;
4242
module: TPythonModule; apyfuncname: string;
4343
Box: TPaintBox; var SortArray: array of Integer);
4444

@@ -56,7 +56,7 @@ procedure PaintLine(Canvas: TCanvas; I, Len: Integer);
5656

5757
{ TSortThread }
5858

59-
constructor TSortThread.Create( ainterp: PPyInterpreterState; script: TStrings;
59+
constructor TSortThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings;
6060
module: TPythonModule; apyfuncname: string;
6161
Box: TPaintBox; var SortArray: array of Integer);
6262
begin
@@ -67,7 +67,7 @@ constructor TSortThread.Create( ainterp: PPyInterpreterState; script: TStrings;
6767
FSortArray := @SortArray;
6868
FSize := High(SortArray) - Low(SortArray) + 1;
6969
FreeOnTerminate := True;
70-
InterpreterState := ainterp;
70+
ThreadExecMode := AThreadExecMode;
7171
inherited Create(False);
7272
end;
7373

‎PythonForDelphi/Demos/Demo11/ThSort.pas

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ TThreadSortForm = class(TForm)
5050
ThreadsRunning: Integer;
5151
procedure RandomizeArrays;
5252
procedure ThreadDone(Sender: TObject);
53-
procedure InitThreads(interp: PPyInterpreterState; script: TStrings);
53+
procedure InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings);
5454

5555
function SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl;
5656
function SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl;
@@ -108,22 +108,21 @@ procedure TThreadSortForm.FormCreate(Sender: TObject);
108108
RandomizeArrays;
109109
end;
110110

111-
procedure TThreadSortForm.InitThreads(interp: PPyInterpreterState; script: TStrings);
111+
procedure TThreadSortForm.InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings);
112112
begin
113113
RandomizeArrays;
114114
ThreadsRunning := 3;
115115
with GetPythonEngine do
116116
begin
117-
OwnThreadState := PyThreadState_Get;
118-
PyEval_ReleaseThread(OwnThreadState);
117+
OwnThreadState := PyEval_SaveThread;
119118

120-
with TSortThread.Create( interp, script, SortModule, 'SortFunc1',
119+
with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc1',
121120
BubbleSortBox, BubbleSortArray) do
122121
OnTerminate := ThreadDone;
123-
with TSortThread.Create( interp, script, SortModule, 'SortFunc2',
122+
with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc2',
124123
SelectionSortBox, SelectionSortArray) do
125124
OnTerminate := ThreadDone;
126-
with TSortThread.Create( interp, script, SortModule, 'SortFunc3',
125+
with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc3',
127126
QuickSortBox, QuickSortArray) do
128127
OnTerminate := ThreadDone;
129128
end;
@@ -137,13 +136,13 @@ procedure TThreadSortForm.Start2BtnClick(Sender: TObject);
137136
with GetPythonEngine do
138137
begin
139138
ExecStrings(PythonMemo.Lines);
140-
self.InitThreads(PyThreadState_Get.interp,nil);
139+
self.InitThreads(emNewState,nil);
141140
end;
142141
end;
143142

144143
procedure TThreadSortForm.StartBtnClick(Sender: TObject);
145144
begin
146-
InitThreads(nil,PythonMemo.Lines);
145+
InitThreads(emNewInterpreter,PythonMemo.Lines);
147146
//PythonEngine1.ExecStrings(PythonMemo.Lines);
148147
end;
149148

@@ -180,7 +179,7 @@ procedure TThreadSortForm.ThreadDone(Sender: TObject);
180179
Dec(ThreadsRunning);
181180
if ThreadsRunning = 0 then
182181
begin
183-
GetPythonEngine.PyEval_AcquireThread(OwnThreadState);
182+
GetPythonEngine.PyEval_RestoreThread(OwnThreadState);
184183
StartBtn.Enabled := True;
185184
Start2Btn.Enabled := True;
186185
ArraysRandom := False;

‎PythonForDelphi/Demos/Demo25/fmMain.pas

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,12 @@ procedure TMain.btnTestIntegersClick(Sender: TObject);
270270
Assert( b+1 = big+1 );
271271
Assert( b*2 = big*2 );
272272
Assert( b div 2 = big div 2 );
273-
{$IFDEF PYTHON23_OR_HIGHER}
274273
c := VarPythonCreate(True);
275274
Assert(VarIsBool(c));
276275
Assert(VarIsTrue(c));
277276
c := VarPythonCreate(False);
278277
Assert(VarIsBool(c));
279278
Assert(not VarIsTrue(c));
280-
{$ENDIF}
281279

282280
// Done!
283281
Log('Integer test was Ok.');
@@ -828,9 +826,7 @@ procedure TMain.btnTestMappingsClick(Sender: TObject);
828826
procedure TMain.btnTestDatesClick(Sender: TObject);
829827
var
830828
a, b, _timeMod : Variant;
831-
{$IFDEF PYTHON23_OR_HIGHER}
832829
c : Variant;
833-
{$ENDIF}
834830
_date, _date2 : TDateTime;
835831
_year, _month, _day : Word;
836832
_year2, _month2, _day2 : Word;
@@ -876,7 +872,6 @@ procedure TMain.btnTestDatesClick(Sender: TObject);
876872
Assert( _min2 = _min );
877873
Assert( _sec2 = _sec );
878874

879-
{$IFDEF PYTHON23_OR_HIGHER}
880875
// test new datetime module
881876
_timeMod := Import('datetime'); // get the datetime module of Python
882877
//or _timeMod := DatetimeModule; // get the datetime module of Python
@@ -1003,7 +998,6 @@ procedure TMain.btnTestDatesClick(Sender: TObject);
1003998
finally
1004999
GetPythonEngine.DatetimeConversionMode := dcmToTuple;
10051000
end;
1006-
{$ENDIF}
10071001
// Done!
10081002
Log('Dates test was Ok.');
10091003
end;

‎PythonForDelphi/Demos/Demo33/SortThds.pas

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ interface
77
uses
88
Classes,
99
{$IFDEF MSWINDOWS}
10-
Graphics, ExtCtrls,
10+
Graphics, ExtCtrls, Forms,
1111
{$ENDIF}
1212
{$IFDEF LINUX}
13-
QGraphics, QExtCtrls,
13+
QGraphics, QExtCtrls, QForms,
1414
{$ENDIF}
1515
PythonEngine;
1616

@@ -40,7 +40,7 @@ TSortThread = class(TPythonThread)
4040
public
4141
property value[i: integer]: integer read getvalue; default;
4242

43-
constructor Create( ainterp: PPyInterpreterState; script: TStrings;
43+
constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings;
4444
module: TPythonModule; apyfuncname: string;
4545
Box: TPaintBox; var SortArray: array of Integer);
4646

@@ -59,7 +59,7 @@ procedure PaintLine(Canvas: TCanvas; I, Len: Integer);
5959

6060
{ TSortThread }
6161

62-
constructor TSortThread.Create( ainterp: PPyInterpreterState; script: TStrings;
62+
constructor TSortThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings;
6363
module: TPythonModule; apyfuncname: string;
6464
Box: TPaintBox; var SortArray: array of Integer);
6565
begin
@@ -70,7 +70,7 @@ constructor TSortThread.Create( ainterp: PPyInterpreterState; script: TStrings;
7070
FSortArray := @SortArray;
7171
FSize := High(SortArray) - Low(SortArray) + 1;
7272
FreeOnTerminate := True;
73-
InterpreterState := ainterp;
73+
ThreadExecMode := AThreadExecMode;
7474
inherited Create(False);
7575
end;
7676

@@ -88,6 +88,7 @@ procedure TSortThread.DoVisualSwap;
8888
var t: integer;
8989
pi,pj: pinteger;
9090
begin
91+
Application.ProcessMessages;
9192
with FBox do
9293
begin
9394
Canvas.Pen.Color := clBtnFace;
@@ -126,24 +127,25 @@ procedure TSortThread.ExecuteWithPython;
126127
var pyfunc: PPyObject;
127128
begin
128129
running := true;
129-
with GetPythonEngine do
130-
begin
131-
if Assigned(FModule) and (ThreadExecMode = emNewInterpreter) then
132-
FModule.InitializeForNewInterpreter;
133-
if Assigned(fScript) then
134-
ExecStrings(fScript);
135-
pyfunc := FindFunction( ExecModule, fpyfuncname);
136-
if Assigned(pyfunc) then
137-
try
138-
EvalFunction(pyfunc,[NativeInt(self),0,FSize]);
139-
except
140-
141-
end;
142-
143-
Py_DecRef(pyfunc);
144-
130+
try
131+
with GetPythonEngine do
132+
begin
133+
if Assigned(FModule) and (ThreadExecMode = emNewInterpreter) then
134+
FModule.InitializeForNewInterpreter;
135+
if Assigned(fScript) then
136+
ExecStrings(fScript);
137+
pyfunc := FindFunction( ExecModule, fpyfuncname);
138+
if Assigned(pyfunc) then
139+
try
140+
EvalFunction(pyfunc,[NativeInt(self),0,FSize]);
141+
except
142+
end;
143+
144+
Py_DecRef(pyfunc);
145+
end;
146+
finally
147+
running := false;
145148
end;
146-
running := false;
147149
end;
148150

149151
procedure TSortThread.Stop;

‎PythonForDelphi/Demos/Demo33/ThSort.pas

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ TThreadSortForm = class(TForm)
5252
ThreadsRunning: Integer;
5353
procedure RandomizeArrays;
5454
procedure ThreadDone(Sender: TObject);
55-
procedure InitThreads(interp: PPyInterpreterState; script: TStrings);
55+
procedure InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings);
5656

5757
function SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl;
5858
function SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl;
@@ -69,13 +69,11 @@ TThreadSortForm = class(TForm)
6969

7070
implementation
7171

72-
73-
7472
{$R *.dfm}
7573

7674
type
7775
PSortArray = ^TSortArray;
78-
TSortArray = array[0..176] of Integer;
76+
TSortArray = array[0..200] of Integer;
7977

8078
var
8179
ArraysRandom: Boolean;
@@ -114,24 +112,23 @@ procedure TThreadSortForm.FormCreate(Sender: TObject);
114112
RandomizeArrays;
115113
end;
116114

117-
procedure TThreadSortForm.InitThreads(interp: PPyInterpreterState; script: TStrings);
115+
procedure TThreadSortForm.InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings);
118116
begin
119117
RandomizeArrays;
120118
ThreadsRunning := 3;
121119
with GetPythonEngine do
122120
begin
123-
OwnThreadState := PyThreadState_Get;
124-
PyEval_ReleaseThread(OwnThreadState);
121+
OwnThreadState := PyEval_SaveThread;
125122

126-
Thread1 := TSortThread.Create( interp, script, SortModule, 'SortFunc1',
123+
Thread1 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc1',
127124
BubbleSortBox, BubbleSortArray);
128125
Thread1.OnTerminate := ThreadDone;
129126

130-
Thread2 := TSortThread.Create( interp, script, SortModule, 'SortFunc2',
127+
Thread2 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc2',
131128
SelectionSortBox, SelectionSortArray);
132129
Thread2.OnTerminate := ThreadDone;
133130

134-
Thread3 := TSortThread.Create( interp, script, SortModule, 'SortFunc3',
131+
Thread3 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc3',
135132
QuickSortBox, QuickSortArray);
136133
Thread3.OnTerminate := ThreadDone;
137134

@@ -146,13 +143,13 @@ procedure TThreadSortForm.Start2BtnClick(Sender: TObject);
146143
with GetPythonEngine do
147144
begin
148145
ExecStrings(PythonMemo.Lines);
149-
self.InitThreads(PyThreadState_Get.interp,nil);
146+
self.InitThreads(emNewState,nil);
150147
end;
151148
end;
152149

153150
procedure TThreadSortForm.StartBtnClick(Sender: TObject);
154151
begin
155-
InitThreads(nil,PythonMemo.Lines);
152+
InitThreads(emNewInterpreter,PythonMemo.Lines);
156153
//PythonEngine1.ExecStrings(PythonMemo.Lines);
157154
end;
158155

@@ -189,10 +186,13 @@ procedure TThreadSortForm.ThreadDone(Sender: TObject);
189186
Dec(ThreadsRunning);
190187
if ThreadsRunning = 0 then
191188
begin
192-
GetPythonEngine.PyEval_AcquireThread(OwnThreadState);
189+
GetPythonEngine.PyEval_RestoreThread(OwnThreadState);
193190
StartBtn.Enabled := True;
194191
Start2Btn.Enabled := True;
195192
ArraysRandom := False;
193+
Thread1 := nil;
194+
Thread2 := nil;
195+
Thread3 := nil;
196196
end;
197197
end;
198198

@@ -247,9 +247,9 @@ procedure TThreadSortForm.SortModuleInitialization(Sender: TObject);
247247

248248
procedure TThreadSortForm.Button1Click(Sender: TObject);
249249
begin
250-
Thread1.Stop();
251-
Thread2.Stop();
252-
Thread3.Stop();
250+
if Assigned(Thread1) and not Thread1.Finished then Thread1.Stop();
251+
if Assigned(Thread2) and not Thread2.Finished then Thread2.Stop();
252+
if Assigned(Thread3) and not Thread3.Finished then Thread3.Stop();
253253
end;
254254

255255
procedure TThreadSortForm.FormCloseQuery(Sender: TObject;

‎PythonForDelphi/Demos/Demo33/ThrdDemo.dproj

Lines changed: 195 additions & 108 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.