@@ -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