@@ -116,39 +116,42 @@   TPythonVersionProp = record
116116  end ;
117117const 
118118{ $IFDEF MSWINDOWS} 
119-   PYTHON_KNOWN_VERSIONS: array [1 ..7 ] of  TPythonVersionProp =
119+   PYTHON_KNOWN_VERSIONS: array [1 ..8 ] of  TPythonVersionProp =
120120    (
121121    (DllName: ' python33.dll'  ; RegVersion: ' 3.3'  ; APIVersion: 1013 ),
122122    (DllName: ' python34.dll'  ; RegVersion: ' 3.4'  ; APIVersion: 1013 ),
123123    (DllName: ' python35.dll'  ; RegVersion: ' 3.5'  ; APIVersion: 1013 ),
124124    (DllName: ' python36.dll'  ; RegVersion: ' 3.6'  ; APIVersion: 1013 ),
125125    (DllName: ' python37.dll'  ; RegVersion: ' 3.7'  ; APIVersion: 1013 ),
126126    (DllName: ' python38.dll'  ; RegVersion: ' 3.8'  ; APIVersion: 1013 ),
127-     (DllName: ' python39.dll'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 )
127+     (DllName: ' python39.dll'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 ),
128+     (DllName: ' python310.dll'  ; RegVersion: ' 3.10'  ; APIVersion: 1013 )
128129    );
129130{ $ENDIF} 
130131{ $IFDEF _so_files} 
131-   PYTHON_KNOWN_VERSIONS: array [1 ..7 ] of  TPythonVersionProp =
132+   PYTHON_KNOWN_VERSIONS: array [1 ..8 ] of  TPythonVersionProp =
132133    (
133134    (DllName: ' libpython3.3m.so'  ; RegVersion: ' 3.3'  ; APIVersion: 1013 ),
134135    (DllName: ' libpython3.4m.so'  ; RegVersion: ' 3.4'  ; APIVersion: 1013 ),
135136    (DllName: ' libpython3.5m.so'  ; RegVersion: ' 3.5'  ; APIVersion: 1013 ),
136137    (DllName: ' libpython3.6m.so'  ; RegVersion: ' 3.6'  ; APIVersion: 1013 ),
137138    (DllName: ' libpython3.7m.so'  ; RegVersion: ' 3.7'  ; APIVersion: 1013 ),
138139    (DllName: ' libpython3.8m.so'  ; RegVersion: ' 3.8'  ; APIVersion: 1013 ),
139-     (DllName: ' libpython3.9m.so'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 )
140+     (DllName: ' libpython3.9m.so'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 ),
141+     (DllName: ' libpython3.9m.so'  ; RegVersion: ' 3.10'  ; APIVersion: 1013 )
140142    );
141143{ $ENDIF} 
142144{ $IFDEF DARWIN} 
143-   PYTHON_KNOWN_VERSIONS: array [1 ..7 ] of  TPythonVersionProp =
145+   PYTHON_KNOWN_VERSIONS: array [1 ..8 ] of  TPythonVersionProp =
144146    (
145147    (DllName: ' libpython3.3.dylib'  ; RegVersion: ' 3.3'  ; APIVersion: 1013 ),
146148    (DllName: ' libpython3.4.dylib'  ; RegVersion: ' 3.4'  ; APIVersion: 1013 ),
147149    (DllName: ' libpython3.5.dylib'  ; RegVersion: ' 3.5'  ; APIVersion: 1013 ),
148150    (DllName: ' libpython3.6.dylib'  ; RegVersion: ' 3.6'  ; APIVersion: 1013 ),
149151    (DllName: ' libpython3.7.dylib'  ; RegVersion: ' 3.7'  ; APIVersion: 1013 ),
150152    (DllName: ' libpython3.8.dylib'  ; RegVersion: ' 3.8'  ; APIVersion: 1013 ),
151-     (DllName: ' libpython3.9.dylib'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 )
153+     (DllName: ' libpython3.9.dylib'  ; RegVersion: ' 3.9'  ; APIVersion: 1013 ),
154+     (DllName: ' libpython3.10.dylib'  ; RegVersion: ' 3.10'  ; APIVersion: 1013 )
152155    );
153156{ $endif} 
154157
@@ -1421,7 +1424,7 @@   TPythonInterface=class(TDynamicDll)
14211424    PyLong_FromString:function (pc:PAnsiChar;var  ppc:PAnsiChar;i:integer):PPyObject; cdecl;
14221425    PyLong_FromUnsignedLong:function(val:LongWord): PPyObject; cdecl;
14231426    PyLong_AsUnsignedLong:function(ob:PPyObject): LongWord; cdecl;
1424-     PyLong_FromUnicode :function(ob:PPyObject; a, b  : integer): PPyObject; cdecl;
1427+     PyLong_FromUnicodeObject :function(ob:PPyObject; base  : integer): PPyObject; cdecl;
14251428    PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl;
14261429    PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl;
14271430    PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl;
@@ -1457,7 +1460,6 @@   TPythonInterface=class(TDynamicDll)
14571460    PyNumber_Rshift:function (ob1,ob2:PPyObject):PPyObject; cdecl;
14581461    PyNumber_Subtract:function (ob1,ob2:PPyObject):PPyObject; cdecl;
14591462    PyNumber_Xor:function (ob1,ob2:PPyObject):PPyObject; cdecl;
1460-     PyOS_InitInterrupts:procedure; cdecl;
14611463    PyOS_InterruptOccurred:function :integer; cdecl;
14621464    PyObject_CallObject:function (ob,args:PPyObject):PPyObject; cdecl;
14631465    PyObject_CallMethod : function ( obj : PPyObject; method, format : PAnsiChar { ...}  ) : PPyObject; cdecl varargs;
@@ -1553,7 +1555,7 @@   TPythonInterface=class(TDynamicDll)
15531555    PyBool_FromLong: function ( ok : Integer) : PPyObject; cdecl;
15541556    PyThreadState_SetAsyncExc: function(t_id :LongInt; exc :PPyObject) : Integer; cdecl;
15551557    Py_AtExit:function (proc: AtExitProc):integer; cdecl;
1556-     Py_CompileStringExFlags:function (s1,s2 :PAnsiChar;i :integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl;
1558+     Py_CompileStringExFlags:function (str,filename :PAnsiChar;start :integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl;
15571559    Py_FatalError:procedure(s:PAnsiChar); cdecl;
15581560    _PyObject_New:function (obt:PPyTypeObject;ob:PPyObject):PPyObject; cdecl;
15591561    _PyBytes_Resize:function (var  ob:PPyObject;i:NativeInt):integer; cdecl;
@@ -1600,8 +1602,8 @@   TPythonInterface=class(TDynamicDll)
16001602  //  TODO - deal with the following:
16011603  //  the PyParser_* functions are deprecated in python 3.9 and will be removed in
16021604  //  Python 3.10
1603-   function  PyParser_SimpleParseString (  str : PAnsiChar; start : Integer) : PNode; cdecl;
1604-   function  Py_CompileString ( s1,s2 :PAnsiChar;i :integer) : PPyObject; cdecl;
1605+   function  PyParser_SimpleParseString (str : PAnsiChar; start : Integer) : PNode; cdecl;
1606+   function  Py_CompileString (str,filename :PAnsiChar;start :integer) : PPyObject; cdecl;
16051607
16061608  //  functions redefined in Delphi
16071609  class  procedure  Py_INCREF (op: PPyObject); static; inline;
@@ -2714,12 +2716,7 @@ procedure MaskFPUExceptions(ExceptionsMasked : boolean;
27142716function  CleanString (const  s : AnsiString; AppendLF : Boolean = True) : AnsiString; overload;
27152717function  CleanString (const  s : UnicodeString; AppendLF : Boolean = True) : UnicodeString; overload;
27162718
2717- // #######################################################
2718- // ##                                                   ##
2719- // ##        Global variables                           ##
2720- // ##                                                   ##
2721- // #######################################################
2722- 
2719+ procedure  DetectPythonVersionFromLibName (const  LibName: string; out MajorVersion, MinorVersion: integer);
27232720
27242721implementation 
27252722
@@ -3124,8 +3121,7 @@ constructor TPythonInterface.Create(AOwner: TComponent);
31243121procedure  TPythonInterface.AfterLoad ;
31253122begin 
31263123  inherited ;
3127-   FMajorVersion := StrToInt(DLLName[7  { $IFNDEF MSWINDOWS}  +3 { $ENDIF}  ]);
3128-   FMinorVersion := StrToInt(DLLName[8 { $IFNDEF MSWINDOWS}  +4 { $ENDIF}  ]);
3124+   DetectPythonVersionFromLibName(DLLName, FMajorVersion, FMinorVersion);
31293125
31303126  FBuiltInModuleName := ' builtins'  ;
31313127
@@ -3370,7 +3366,7 @@ procedure TPythonInterface.MapDll;
33703366  PyLong_FromString         := Import (' PyLong_FromString'  );
33713367  PyLong_FromUnsignedLong   := Import (' PyLong_FromUnsignedLong'  );
33723368  PyLong_AsUnsignedLong     := Import (' PyLong_AsUnsignedLong'  );
3373-   PyLong_FromUnicode         := Import (' PyLong_FromUnicode '  );
3369+   PyLong_FromUnicodeObject   := Import (' PyLong_FromUnicodeObject '  );
33743370  PyLong_FromLongLong       := Import (' PyLong_FromLongLong'  );
33753371  PyLong_FromUnsignedLongLong := Import (' PyLong_FromUnsignedLongLong'  );
33763372  PyLong_AsLongLong         := Import (' PyLong_AsLongLong'  );
@@ -3406,7 +3402,6 @@ procedure TPythonInterface.MapDll;
34063402  PyNumber_Rshift           := Import (' PyNumber_Rshift'  );
34073403  PyNumber_Subtract         := Import (' PyNumber_Subtract'  );
34083404  PyNumber_Xor              := Import (' PyNumber_Xor'  );
3409-   PyOS_InitInterrupts       := Import (' PyOS_InitInterrupts'  );
34103405  PyOS_InterruptOccurred    := Import (' PyOS_InterruptOccurred'  );
34113406  PyObject_CallObject       := Import (' PyObject_CallObject'  );
34123407  PyObject_CallMethod       := Import (' PyObject_CallMethod'  );
@@ -3521,8 +3516,13 @@ procedure TPythonInterface.MapDll;
35213516  Py_GetPythonHome            := Import (' Py_GetPythonHome'  );
35223517  Py_GetPrefix                := Import (' Py_GetPrefix'  );
35233518  Py_GetProgramName           := Import (' Py_GetProgramName'  );
3524-   PyParser_SimpleParseStringFlags := Import (' PyParser_SimpleParseStringFlags'  );
3525-   PyNode_Free                 := Import (' PyNode_Free'  );
3519+ 
3520+   if  (FMajorVersion = 3 ) and  (MinorVersion < 10 ) then 
3521+   begin 
3522+     PyParser_SimpleParseStringFlags := Import (' PyParser_SimpleParseStringFlags'  );
3523+     PyNode_Free                 := Import (' PyNode_Free'  );
3524+   end ;
3525+ 
35263526  PyErr_NewException          := Import (' PyErr_NewException'  );
35273527  try 
35283528    PyMem_Malloc := Import  (' PyMem_Malloc'  );
@@ -3551,9 +3551,9 @@ procedure TPythonInterface.MapDll;
35513551  PyGILState_Release       := Import (' PyGILState_Release'  );
35523552end ;
35533553
3554- function  TPythonInterface.Py_CompileString (s1,s2 :PAnsiChar;i :integer):PPyObject;
3554+ function  TPythonInterface.Py_CompileString (str,filename :PAnsiChar;start :integer):PPyObject;
35553555begin 
3556-   Result := Py_CompileStringExFlags(s1, s2, i , nil , -1 );
3556+   Result := Py_CompileStringExFlags(str, filename, start , nil , -1 );
35573557end ;
35583558
35593559function  TPythonInterface.PyParser_SimpleParseString ( str : PAnsiChar; start : integer) : PNode; cdecl;
@@ -4283,7 +4283,7 @@ procedure TPythonEngine.CheckRegistry;
42834283        VersionSuffix := ' '  ;
42844284{ $IFDEF CPUX86} 
42854285        MajorVersion := StrToInt(RegVersion[1 ]);
4286-         MinorVersion := StrToInt(RegVersion[ 3 ] );
4286+         MinorVersion := StrToInt(Copy( RegVersion,  3 ) );
42874287        if  (MajorVersion > 3 ) or  ((MajorVersion = 3 )  and  (MinorVersion >= 5 )) then 
42884288          VersionSuffix := ' -32'  ;
42894289{ $ENDIF} 
@@ -4604,11 +4604,21 @@ function TPythonEngine.CheckExecSyntax( const str : AnsiString ) : Boolean;
46044604function  TPythonEngine.CheckSyntax ( const  str : AnsiString; mode : Integer ) : Boolean;
46054605var 
46064606  n : PNode;
4607+   PyCode: PPyObject;
46074608begin 
4608-   n := PyParser_SimpleParseString( PAnsiChar(str), mode );
4609-   result := Assigned(n);
4610-   if  Assigned( n ) then 
4611-     PyNode_Free(n);
4609+   if  (FMajorVersion = 3 ) and  (MinorVersion < 10 ) then 
4610+   begin 
4611+     n := PyParser_SimpleParseString( PAnsiChar(str), mode );
4612+     result := Assigned(n);
4613+     if  Assigned( n ) then 
4614+       PyNode_Free(n);
4615+   end 
4616+   else 
4617+   begin 
4618+     PyCode := Py_CompileString(PAnsiChar(str), ' <string>'  , mode);
4619+     Result := Assigned(PyCode);
4620+     Py_XDECREF(PyCode);
4621+   end ;
46124622end ;
46134623
46144624procedure  TPythonEngine.RaiseError ;
@@ -8950,5 +8960,29 @@ function IsPythonVersionRegistered(PythonVersion : string;
89508960end ;
89518961{ $ENDIF} 
89528962
8963+ procedure  DetectPythonVersionFromLibName (const  LibName: string; out MajorVersion, MinorVersion: integer);
8964+ var 
8965+   NPos: integer;
8966+   S: String;
8967+ begin 
8968+   // Win: "python310.dll"
8969+   // Linux: "libpython3.10.so"
8970+   S := LibName;
8971+   NPos := Pos(' python'  , LowerCase(S));
8972+   if  NPos>0  then 
8973+   begin 
8974+     Inc(NPos, Length(' python'  ));
8975+     MajorVersion := StrToIntDef(S[NPos], 3 );
8976+     Inc(NPos);
8977+     if  LibName[NPos]=' .'   then 
8978+       Inc(NPos);
8979+     S := Copy(S, NPos);
8980+     NPos := Pos(' .'  , S);
8981+     if  NPos > 1  then 
8982+       MinorVersion := StrToIntDef(Copy(S, 1 , NPos-1 ), 3 );
8983+   end ;
8984+ end ;
8985+ 
8986+ 
89538987end .
89548988
0 commit comments