@@ -956,28 +956,35 @@ PyBufferProcs = record
956
956
957
957
// bytearrayobject.h
958
958
959
- // typedef struct {
960
- // PyObject_VAR_HEAD
961
- // Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */
962
- // char *ob_bytes; /* Physical backing buffer */
963
- // char *ob_start; /* Logical start inside ob_bytes */
964
- // Py_ssize_t ob_exports; /* How many buffer exports */
965
- // } PyByteArrayObject;
966
-
967
959
PyByteArrayObject = { $IFDEF CPUX86} packed { $ENDIF} record
968
- // Start of PyObject_VAR_HEAD
969
- // Start of the Head of an object
970
- ob_base: PyObject;
971
- ob_size: Py_ssize_t;
972
- // End of the Head of an object
960
+ ob_refcnt: NativeInt;
961
+ ob_type: PPyTypeObject;
962
+ ob_alloc: Py_ssize_t;
973
963
ob_bytes: PAnsiChar;
974
964
ob_start: PAnsiChar;
975
965
ob_exports: Py_ssize_t;
976
966
end ;
977
967
968
+ // initconfig.h
969
+
970
+ const
971
+ _PyStatus_TYPE_OK = 0 ;
972
+ _PyStatus_TYPE_ERROR = 1 ;
973
+ _PyStatus_TYPE_EXIT = 2 ;
974
+
975
+ type
976
+ TPyStatus_Type = Integer;
977
+
978
+ PyStatus = { $IFDEF CPUX86} packed { $ENDIF} record
979
+ _type: TPyStatus_Type;
980
+ func: PAnsiChar;
981
+ err_msg: PAnsiChar;
982
+ exitcode: Integer;
983
+ end ;
984
+
978
985
// #######################################################
979
986
// ## ##
980
- // ## GIL state ##
987
+ // ## GIL related ##
981
988
// ## ##
982
989
// #######################################################
983
990
const
@@ -986,12 +993,40 @@ PyBufferProcs = record
986
993
type
987
994
PyGILState_STATE = type Integer; // (PyGILState_LOCKED, PyGILState_UNLOCKED);
988
995
996
+ // Introduced in Python 12
997
+ const
998
+ PyInterpreterConfig_DEFAULT_GIL = 0 ;
999
+ PyInterpreterConfig_SHARED_GIL = 1 ;
1000
+ PyInterpreterConfig_OWN_GIL = 2 ;
1001
+
1002
+ type
1003
+ PPyInterpreterConfig = ^PyInterpreterConfig;
1004
+ PyInterpreterConfig = { $IFDEF CPUX86} packed { $ENDIF} record
1005
+ use_main_obmalloc: Integer;
1006
+ allow_fork: Integer;
1007
+ allow_exec: Integer;
1008
+ allow_threads: Integer;
1009
+ allow_daemon_threads: Integer;
1010
+ check_multi_interp_extensions: Integer;
1011
+ gil: Integer;
1012
+ end ;
1013
+
1014
+ const
1015
+ _PyInterpreterConfig_INIT: PyInterpreterConfig =
1016
+ ( use_main_obmalloc: 0 ;
1017
+ allow_fork: 0 ;
1018
+ allow_exec: 0 ;
1019
+ allow_threads: 1 ;
1020
+ allow_daemon_threads: 0 ;
1021
+ check_multi_interp_extensions: 1 ;
1022
+ gil: PyInterpreterConfig_OWN_GIL);
1023
+
989
1024
// #######################################################
990
1025
// ## ##
991
1026
// ## New exception classes ##
992
1027
// ## ##
993
1028
// #######################################################
994
-
1029
+ type
995
1030
// Components' exceptions
996
1031
EDLLLoadError = class (Exception);
997
1032
EDLLImportError = class (Exception)
@@ -1709,6 +1744,7 @@ TPythonInterface=class(TDynamicDll)
1709
1744
Py_IsInitialized : function : integer; cdecl;
1710
1745
Py_GetProgramFullPath : function : PAnsiChar; cdecl;
1711
1746
Py_NewInterpreter : function : PPyThreadState; cdecl;
1747
+ Py_NewInterpreterFromConfig : function( tstate: PPyThreadState; config: PPyInterpreterConfig): PyStatus; cdecl;
1712
1748
Py_EndInterpreter : procedure( tstate: PPyThreadState); cdecl;
1713
1749
PyEval_AcquireLock : procedure; cdecl;
1714
1750
PyEval_ReleaseLock : procedure; cdecl;
@@ -2798,7 +2834,7 @@ TPyVar = class(TPyObject)
2798
2834
// ## Thread Object with Python interpreter lock ##
2799
2835
// ## ##
2800
2836
// #######################################################
2801
- TThreadExecMode = (emNewState, emNewInterpreter);
2837
+ TThreadExecMode = (emNewState, emNewInterpreter, emNewInterpreterOwnGIL );
2802
2838
2803
2839
{ $HINTS OFF}
2804
2840
TPythonThread = class (TThread)
@@ -2813,6 +2849,7 @@ TPythonThread = class(TThread)
2813
2849
protected
2814
2850
procedure ExecuteWithPython ; virtual ; abstract ;
2815
2851
public
2852
+ InterpreterConfig: PyInterpreterConfig;
2816
2853
class procedure Py_Begin_Allow_Threads ;
2817
2854
class procedure Py_End_Allow_Threads ;
2818
2855
// The following procedures are redundant and only for
@@ -2863,6 +2900,7 @@ function SysVersionFromDLLName(const DLLFileName : string): string;
2863
2900
procedure PythonVersionFromDLLName (LibName: string; out MajorVersion, MinorVersion: integer);
2864
2901
function PythonVersionFromRegVersion (const ARegVersion: string;
2865
2902
out AMajorVersion, AMinorVersion: integer): boolean;
2903
+ function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
2866
2904
2867
2905
{ Helper functions}
2868
2906
(*
@@ -3950,6 +3988,8 @@ procedure TPythonInterface.MapDll;
3950
3988
Py_GetProgramFullPath := Import (' Py_GetProgramFullPath' );
3951
3989
Py_GetBuildInfo := Import (' Py_GetBuildInfo' );
3952
3990
Py_NewInterpreter := Import (' Py_NewInterpreter' );
3991
+ if (FMajorVersion > 3 ) or (FMinorVersion >= 12 ) then
3992
+ Py_NewInterpreterFromConfig := Import (' Py_NewInterpreterFromConfig' );
3953
3993
Py_EndInterpreter := Import (' Py_EndInterpreter' );
3954
3994
PyEval_AcquireLock := Import (' PyEval_AcquireLock' );
3955
3995
PyEval_ReleaseLock := Import (' PyEval_ReleaseLock' );
@@ -9237,8 +9277,9 @@ procedure TPyVar.SetValueFromVariant( const value : Variant );
9237
9277
9238
9278
procedure TPythonThread.Execute ;
9239
9279
var
9240
- global_state : PPyThreadState;
9241
- gilstate : PyGILState_STATE;
9280
+ global_state: PPyThreadState;
9281
+ gilstate: PyGILState_STATE;
9282
+ Status: PyStatus;
9242
9283
begin
9243
9284
with GetPythonEngine do
9244
9285
begin
@@ -9256,7 +9297,12 @@ procedure TPythonThread.Execute;
9256
9297
gilstate := PyGILState_Ensure();
9257
9298
global_state := PyThreadState_Get;
9258
9299
PyThreadState_Swap(nil );
9259
- fThreadState := Py_NewInterpreter;
9300
+
9301
+ if (fThreadExecMode = emNewInterpreter) or
9302
+ ((FMajorVersion = 3 ) and (FMinorVersion < 12 )) or
9303
+ PyStatus_Exception(Py_NewInterpreterFromConfig(@fThreadState, @InterpreterConfig))
9304
+ then
9305
+ fThreadState := Py_NewInterpreter;
9260
9306
9261
9307
if Assigned( fThreadState) then
9262
9308
begin
@@ -9705,5 +9751,10 @@ function PythonVersionFromRegVersion(const ARegVersion: string;
9705
9751
Result := (AMajorVersion > 0 ) and (AMinorVersion > 0 );
9706
9752
end ;
9707
9753
9754
+ function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
9755
+ begin
9756
+ Result := APyStatus._type <> _PyStatus_TYPE_OK;
9757
+ end ;
9758
+
9708
9759
end .
9709
9760
0 commit comments