@@ -956,28 +956,35 @@ PyBufferProcs = record
956956
957957 // bytearrayobject.h
958958
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-
967959 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;
973963 ob_bytes: PAnsiChar;
974964 ob_start: PAnsiChar;
975965 ob_exports: Py_ssize_t;
976966 end ;
977967
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+
978985// #######################################################
979986// ## ##
980- // ## GIL state ##
987+ // ## GIL related ##
981988// ## ##
982989// #######################################################
983990const
@@ -986,12 +993,40 @@ PyBufferProcs = record
986993type
987994 PyGILState_STATE = type Integer; // (PyGILState_LOCKED, PyGILState_UNLOCKED);
988995
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+
9891024// #######################################################
9901025// ## ##
9911026// ## New exception classes ##
9921027// ## ##
9931028// #######################################################
994-
1029+ type
9951030 // Components' exceptions
9961031 EDLLLoadError = class (Exception);
9971032 EDLLImportError = class (Exception)
@@ -1709,6 +1744,7 @@ TPythonInterface=class(TDynamicDll)
17091744 Py_IsInitialized : function : integer; cdecl;
17101745 Py_GetProgramFullPath : function : PAnsiChar; cdecl;
17111746 Py_NewInterpreter : function : PPyThreadState; cdecl;
1747+ Py_NewInterpreterFromConfig : function( tstate: PPyThreadState; config: PPyInterpreterConfig): PyStatus; cdecl;
17121748 Py_EndInterpreter : procedure( tstate: PPyThreadState); cdecl;
17131749 PyEval_AcquireLock : procedure; cdecl;
17141750 PyEval_ReleaseLock : procedure; cdecl;
@@ -2798,7 +2834,7 @@ TPyVar = class(TPyObject)
27982834// ## Thread Object with Python interpreter lock ##
27992835// ## ##
28002836// #######################################################
2801- TThreadExecMode = (emNewState, emNewInterpreter);
2837+ TThreadExecMode = (emNewState, emNewInterpreter, emNewInterpreterOwnGIL );
28022838
28032839{ $HINTS OFF}
28042840 TPythonThread = class (TThread)
@@ -2813,6 +2849,7 @@ TPythonThread = class(TThread)
28132849 protected
28142850 procedure ExecuteWithPython ; virtual ; abstract ;
28152851 public
2852+ InterpreterConfig: PyInterpreterConfig;
28162853 class procedure Py_Begin_Allow_Threads ;
28172854 class procedure Py_End_Allow_Threads ;
28182855 // The following procedures are redundant and only for
@@ -2863,6 +2900,7 @@ function SysVersionFromDLLName(const DLLFileName : string): string;
28632900procedure PythonVersionFromDLLName (LibName: string; out MajorVersion, MinorVersion: integer);
28642901function PythonVersionFromRegVersion (const ARegVersion: string;
28652902 out AMajorVersion, AMinorVersion: integer): boolean;
2903+ function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
28662904
28672905{ Helper functions}
28682906(*
@@ -3950,6 +3988,8 @@ procedure TPythonInterface.MapDll;
39503988 Py_GetProgramFullPath := Import (' Py_GetProgramFullPath' );
39513989 Py_GetBuildInfo := Import (' Py_GetBuildInfo' );
39523990 Py_NewInterpreter := Import (' Py_NewInterpreter' );
3991+ if (FMajorVersion > 3 ) or (FMinorVersion >= 12 ) then
3992+ Py_NewInterpreterFromConfig := Import (' Py_NewInterpreterFromConfig' );
39533993 Py_EndInterpreter := Import (' Py_EndInterpreter' );
39543994 PyEval_AcquireLock := Import (' PyEval_AcquireLock' );
39553995 PyEval_ReleaseLock := Import (' PyEval_ReleaseLock' );
@@ -9237,8 +9277,9 @@ procedure TPyVar.SetValueFromVariant( const value : Variant );
92379277
92389278procedure TPythonThread.Execute ;
92399279var
9240- global_state : PPyThreadState;
9241- gilstate : PyGILState_STATE;
9280+ global_state: PPyThreadState;
9281+ gilstate: PyGILState_STATE;
9282+ Status: PyStatus;
92429283begin
92439284 with GetPythonEngine do
92449285 begin
@@ -9256,7 +9297,12 @@ procedure TPythonThread.Execute;
92569297 gilstate := PyGILState_Ensure();
92579298 global_state := PyThreadState_Get;
92589299 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;
92609306
92619307 if Assigned( fThreadState) then
92629308 begin
@@ -9705,5 +9751,10 @@ function PythonVersionFromRegVersion(const ARegVersion: string;
97059751 Result := (AMajorVersion > 0 ) and (AMinorVersion > 0 );
97069752end ;
97079753
9754+ function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
9755+ begin
9756+ Result := APyStatus._type <> _PyStatus_TYPE_OK;
9757+ end ;
9758+
97089759end .
97099760
0 commit comments