Skip to content

Commit 74a70a7

Browse files
committed
Support for Python 3.10 added
1 parent 04d4e13 commit 74a70a7

File tree

1 file changed

+64
-30
lines changed

1 file changed

+64
-30
lines changed

Source/PythonEngine.pas

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -116,39 +116,42 @@ TPythonVersionProp = record
116116
end;
117117
const
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;
27142716
function CleanString(const s : AnsiString; AppendLF : Boolean = True) : AnsiString; overload;
27152717
function 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

27242721
implementation
27252722

@@ -3124,8 +3121,7 @@ constructor TPythonInterface.Create(AOwner: TComponent);
31243121
procedure TPythonInterface.AfterLoad;
31253122
begin
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');
35523552
end;
35533553

3554-
function TPythonInterface.Py_CompileString(s1,s2:PAnsiChar;i:integer):PPyObject;
3554+
function TPythonInterface.Py_CompileString(str,filename:PAnsiChar;start:integer):PPyObject;
35553555
begin
3556-
Result := Py_CompileStringExFlags(s1, s2, i, nil, -1);
3556+
Result := Py_CompileStringExFlags(str, filename, start, nil, -1);
35573557
end;
35583558

35593559
function 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;
46044604
function TPythonEngine.CheckSyntax( const str : AnsiString; mode : Integer ) : Boolean;
46054605
var
46064606
n : PNode;
4607+
PyCode: PPyObject;
46074608
begin
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;
46124622
end;
46134623

46144624
procedure TPythonEngine.RaiseError;
@@ -8950,5 +8960,29 @@ function IsPythonVersionRegistered(PythonVersion : string;
89508960
end;
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+
89538987
end.
89548988

0 commit comments

Comments
 (0)