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