@@ -107,7 +107,7 @@ interface
107107
108108const
109109{ $ifdef windows}
110- PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of TPythonVersionProp =
110+ PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of TPythonVersionProp =
111111 (
112112 (DllName: ' python33.dll' ; RegVersion: ' 3.3' ; APIVersion: 1013 ),
113113 (DllName: ' python34.dll' ; RegVersion: ' 3.4' ; APIVersion: 1013 ),
@@ -117,11 +117,12 @@ interface
117117 (DllName: ' python38.dll' ; RegVersion: ' 3.8' ; APIVersion: 1013 ),
118118 (DllName: ' python39.dll' ; RegVersion: ' 3.9' ; APIVersion: 1013 ),
119119 (DllName: ' python310.dll' ; RegVersion: ' 3.10' ; APIVersion: 1013 ),
120- (DllName: ' python311.dll' ; RegVersion: ' 3.11' ; APIVersion: 1013 )
120+ (DllName: ' python311.dll' ; RegVersion: ' 3.11' ; APIVersion: 1013 ),
121+ (DllName: ' python312.dll' ; RegVersion: ' 3.12' ; APIVersion: 1013 )
121122 );
122123{ $endif}
123124{ $ifdef _so_files}
124- PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of TPythonVersionProp =
125+ PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of TPythonVersionProp =
125126 (
126127 (DllName: ' libpython3.3m.so' ; RegVersion: ' 3.3' ; APIVersion: 1013 ),
127128 (DllName: ' libpython3.4m.so' ; RegVersion: ' 3.4' ; APIVersion: 1013 ),
@@ -131,11 +132,12 @@ interface
131132 (DllName: ' libpython3.8.so' ; RegVersion: ' 3.8' ; APIVersion: 1013 ),
132133 (DllName: ' libpython3.9.so' ; RegVersion: ' 3.9' ; APIVersion: 1013 ),
133134 (DllName: ' libpython3.10.so' ; RegVersion: ' 3.10' ; APIVersion: 1013 ),
134- (DllName: ' libpython3.11.so' ; RegVersion: ' 3.11' ; APIVersion: 1013 )
135+ (DllName: ' libpython3.11.so' ; RegVersion: ' 3.11' ; APIVersion: 1013 ),
136+ (DllName: ' libpython3.12.so' ; RegVersion: ' 3.12' ; APIVersion: 1013 )
135137 );
136138{ $endif}
137139{ $ifdef darwin}
138- PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of TPythonVersionProp =
140+ PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of TPythonVersionProp =
139141 (
140142 (DllName: ' libpython3.3.dylib' ; RegVersion: ' 3.3' ; APIVersion: 1013 ),
141143 (DllName: ' libpython3.4.dylib' ; RegVersion: ' 3.4' ; APIVersion: 1013 ),
@@ -145,7 +147,8 @@ interface
145147 (DllName: ' libpython3.8.dylib' ; RegVersion: ' 3.8' ; APIVersion: 1013 ),
146148 (DllName: ' libpython3.9.dylib' ; RegVersion: ' 3.9' ; APIVersion: 1013 ),
147149 (DllName: ' libpython3.10.dylib' ; RegVersion: ' 3.10' ; APIVersion: 1013 ),
148- (DllName: ' libpython3.11.dylib' ; RegVersion: ' 3.11' ; APIVersion: 1013 )
150+ (DllName: ' libpython3.11.dylib' ; RegVersion: ' 3.11' ; APIVersion: 1013 ),
151+ (DllName: ' libpython3.12.dylib' ; RegVersion: ' 3.12' ; APIVersion: 1013 )
149152 );
150153{ $endif}
151154
@@ -1254,7 +1257,6 @@ TPythonInterface=class(TDynamicDll)
12541257 procedure AfterLoad ; override;
12551258 function GetQuitMessage : String; override;
12561259 procedure CheckPython ;
1257- function GetUnicodeTypeSuffix : String;
12581260
12591261 public
12601262 // define Python flags. See file pyDebug.h
@@ -1585,7 +1587,7 @@ TPythonInterface=class(TDynamicDll)
15851587 PyUnicode_DecodeUTF16:function (const s:PAnsiChar; size: NativeInt; const errors: PAnsiChar; byteoder: PInteger):PPyObject; cdecl;
15861588 PyUnicode_AsEncodedString:function (unicode:PPyObject; const encoding:PAnsiChar; const errors:PAnsiChar):PPyObject; cdecl;
15871589 PyUnicode_FromOrdinal:function (ordinal:integer):PPyObject; cdecl;
1588- PyUnicode_GetSize :function (unicode:PPyObject):NativeInt; cdecl;
1590+ PyUnicode_GetLength :function (unicode:PPyObject):NativeInt; cdecl;
15891591 PyWeakref_GetObject: function ( ref : PPyObject) : PPyObject; cdecl;
15901592 PyWeakref_NewProxy: function ( ob, callback : PPyObject) : PPyObject; cdecl;
15911593 PyWeakref_NewRef: function ( ob, callback : PPyObject) : PPyObject; cdecl;
@@ -3214,30 +3216,8 @@ procedure TPythonInterface.CheckPython;
32143216 raise Exception.Create(' Python is not properly initialized' );
32153217end ;
32163218
3217- // https://github.com/Alexey-T/Python-for-Lazarus/issues/16
3218- function TPythonInterface.GetUnicodeTypeSuffix : String;
3219- begin
3220- if (fMajorVersion > 3 ) or ((fMajorVersion = 3 ) and (fMinorVersion >= 3 )) then
3221- Result := ' '
3222- else
3223- if APIVersion >= 1011 then
3224- Result :=
3225- { $if defined(windows) or defined(darwin) or defined(solaris)}
3226- ' UCS2'
3227- { $else}
3228- ' UCS4'
3229- { $endif}
3230- else
3231- Result := ' ' ;
3232- end ;
3233-
32343219procedure TPythonInterface.MapDll ;
3235- Var
3236- UnicodeSuffix : string;
3237-
32383220begin
3239- UnicodeSuffix := GetUnicodeTypeSuffix;
3240-
32413221 Py_DebugFlag := Import (' Py_DebugFlag' );
32423222 Py_VerboseFlag := Import (' Py_VerboseFlag' );
32433223 Py_InteractiveFlag := Import (' Py_InteractiveFlag' );
@@ -3546,18 +3526,18 @@ procedure TPythonInterface.MapDll;
35463526 PyType_GenericAlloc := Import (' PyType_GenericAlloc' );
35473527 PyType_GenericNew := Import (' PyType_GenericNew' );
35483528 PyType_Ready := Import (' PyType_Ready' );
3549- PyUnicode_FromWideChar := Import (AnsiString(Format( ' PyUnicode%s_FromWideChar ' ,[UnicodeSuffix])) );
3550- PyUnicode_FromString := Import (AnsiString(Format( ' PyUnicode%s_FromString ' ,[UnicodeSuffix])) );
3551- PyUnicode_FromStringAndSize := Import (AnsiString(Format( ' PyUnicode%s_FromStringAndSize ' ,[UnicodeSuffix])) );
3552- PyUnicode_FromKindAndData := Import (AnsiString(Format( ' PyUnicode%s_FromKindAndData ' ,[UnicodeSuffix])) );
3553- PyUnicode_AsWideChar := Import (AnsiString(Format( ' PyUnicode%s_AsWideChar ' ,[UnicodeSuffix])) );
3554- PyUnicode_AsUTF8 := Import (AnsiString(Format( ' PyUnicode%s_AsUTF8 ' ,[UnicodeSuffix])) );
3555- PyUnicode_AsUTF8AndSize := Import (AnsiString(Format( ' PyUnicode%s_AsUTF8AndSize ' ,[UnicodeSuffix])) );
3556- PyUnicode_Decode := Import (AnsiString(Format( ' PyUnicode%s_Decode ' ,[UnicodeSuffix])) );
3557- PyUnicode_DecodeUTF16 := Import (AnsiString(Format( ' PyUnicode%s_DecodeUTF16 ' ,[UnicodeSuffix])) );
3558- PyUnicode_AsEncodedString := Import (AnsiString(Format( ' PyUnicode%s_AsEncodedString ' ,[UnicodeSuffix])) );
3559- PyUnicode_FromOrdinal := Import (AnsiString(Format( ' PyUnicode%s_FromOrdinal ' ,[UnicodeSuffix])) );
3560- PyUnicode_GetSize := Import (AnsiString(Format( ' PyUnicode%s_GetSize ' ,[UnicodeSuffix])) );
3529+ PyUnicode_FromWideChar := Import (' PyUnicode_FromWideChar ' );
3530+ PyUnicode_FromString := Import (' PyUnicode_FromString ' );
3531+ PyUnicode_FromStringAndSize := Import (' PyUnicode_FromStringAndSize ' );
3532+ PyUnicode_FromKindAndData := Import (' PyUnicode_FromKindAndData ' );
3533+ PyUnicode_AsWideChar := Import (' PyUnicode_AsWideChar ' );
3534+ PyUnicode_AsUTF8 := Import (' PyUnicode_AsUTF8 ' );
3535+ PyUnicode_AsUTF8AndSize := Import (' PyUnicode_AsUTF8AndSize ' );
3536+ PyUnicode_Decode := Import (' PyUnicode_Decode ' );
3537+ PyUnicode_DecodeUTF16 := Import (' PyUnicode_DecodeUTF16 ' );
3538+ PyUnicode_AsEncodedString := Import (' PyUnicode_AsEncodedString ' );
3539+ PyUnicode_FromOrdinal := Import (' PyUnicode_FromOrdinal ' );
3540+ PyUnicode_GetLength := Import (' PyUnicode_GetLength ' );
35613541 PyWeakref_GetObject := Import (' PyWeakref_GetObject' );
35623542 PyWeakref_NewProxy := Import (' PyWeakref_NewProxy' );
35633543 PyWeakref_NewRef := Import (' PyWeakref_NewRef' );
@@ -5649,35 +5629,24 @@ function TPythonEngine.PyBytesAsAnsiString(obj: PPyObject): AnsiString;
56495629 raise EPythonError.CreateFmt(SPyConvertionError, [' PyBytesAsAnsiString' , ' Bytes' ]);
56505630end ;
56515631
5652- function TPythonEngine.PyUnicodeAsString ( obj : PPyObject ) : UnicodeString;
5632+ function TPythonEngine.PyUnicodeAsString (obj : PPyObject) : UnicodeString;
56535633var
5654- _size : Integer;
5655- { $IFDEF POSIX}
5656- _ucs4Str : UCS4String;
5657- { $ENDIF}
5634+ Buffer: PAnsiChar;
5635+ Size: NativeInt;
5636+ NewSize: Cardinal;
56585637begin
56595638 if PyUnicode_Check(obj) then
56605639 begin
5661- _size := PyUnicode_GetSize(obj);
5662- if _size > 0 then
5663- begin
5664- { $IFDEF POSIX}
5665- // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!!
5666- SetLength(_ucs4Str, _size+1 );
5667- if PyUnicode_AsWideChar(obj, @_ucs4Str[0 ], _size) <> _size then
5668- raise EPythonError.Create(' Could not copy the whole Unicode string into its buffer' );
5669- Result := UCS4StringToWideString(_ucs4Str);
5670- // remove trailing zeros (needed by Kylix1)
5671- while (Length(Result) > 0 ) and (Result[Length(Result)] = #0 ) do
5672- Delete(Result, Length(Result), 1 );
5673- { $ELSE}
5674- SetLength(Result, _size);
5675- if PyUnicode_AsWideChar(obj, @Result[1 ], _size) <> _size then
5676- raise EPythonError.Create(' Could not copy the whole Unicode string into its buffer' );
5677- { $ENDIF}
5678- end
5679- else
5680- Result := ' ' ;
5640+ // Size does not include the final #0
5641+ Buffer := PyUnicode_AsUTF8AndSize(obj, @Size);
5642+ SetLength(Result, Size);
5643+ if (Size = 0 ) or (Buffer = nil ) then
5644+ Exit;
5645+
5646+ // The second argument is the size of the destination (Result) including #0
5647+ NewSize := Utf8ToUnicode(PUnicodeChar(Result), Cardinal(Size + 1 ), Buffer, Cardinal(Size));
5648+ // NewSize includes #0
5649+ SetLength(Result, NewSize - 1 );
56815650 end
56825651 else
56835652 raise EPythonError.CreateFmt(SPyConvertionError, [' PyUnicodeAsString' , ' Unicode' ]);
0 commit comments