@@ -116,7 +116,7 @@   TPythonVersionProp = record
116116  end ;
117117const 
118118{ $IFDEF MSWINDOWS} 
119-   PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of  TPythonVersionProp =
119+   PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of  TPythonVersionProp =
120120    (
121121    (DllName: ' python33.dll' ' 3.3' 1013 ),
122122    (DllName: ' python34.dll' ' 3.4' 1013 ),
@@ -126,11 +126,12 @@   TPythonVersionProp = record
126126    (DllName: ' python38.dll' ' 3.8' 1013 ),
127127    (DllName: ' python39.dll' ' 3.9' 1013 ),
128128    (DllName: ' python310.dll' ' 3.10' 1013 ),
129-     (DllName: ' python311.dll' ' 3.11' 1013 )
129+     (DllName: ' python311.dll' ' 3.11' 1013 ),
130+     (DllName: ' python312.dll' ' 3.12' 1013 )
130131    );
131132{ $ENDIF} 
132133{ $IFDEF _so_files} 
133-   PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of  TPythonVersionProp =
134+   PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of  TPythonVersionProp =
134135    (
135136    (DllName: ' libpython3.3m.so' ' 3.3' 1013 ),
136137    (DllName: ' libpython3.4m.so' ' 3.4' 1013 ),
@@ -140,11 +141,12 @@   TPythonVersionProp = record
140141    (DllName: ' libpython3.8.so' ' 3.8' 1013 ),
141142    (DllName: ' libpython3.9.so' ' 3.9' 1013 ),
142143    (DllName: ' libpython3.10.so' ' 3.10' 1013 ),
143-     (DllName: ' libpython3.11.so' ' 3.11' 1013 )
144+     (DllName: ' libpython3.11.so' ' 3.11' 1013 ),
145+     (DllName: ' libpython3.12.so' ' 3.12' 1013 )
144146    );
145147{ $ENDIF} 
146148{ $IFDEF DARWIN} 
147-   PYTHON_KNOWN_VERSIONS: array [1 ..9 ] of  TPythonVersionProp =
149+   PYTHON_KNOWN_VERSIONS: array [1 ..10 ] of  TPythonVersionProp =
148150    (
149151    (DllName: ' libpython3.3.dylib' ' 3.3' 1013 ),
150152    (DllName: ' libpython3.4.dylib' ' 3.4' 1013 ),
@@ -154,16 +156,18 @@   TPythonVersionProp = record
154156    (DllName: ' libpython3.8.dylib' ' 3.8' 1013 ),
155157    (DllName: ' libpython3.9.dylib' ' 3.9' 1013 ),
156158    (DllName: ' libpython3.10.dylib' ' 3.10' 1013 ),
157-     (DllName: ' libpython3.11.dylib' ' 3.11' 1013 )
159+     (DllName: ' libpython3.11.dylib' ' 3.11' 1013 ),
160+     (DllName: ' libpython3.12.dylib' ' 3.12' 1013 )
158161    );
159162{ $ENDIF} 
160163{ $IFDEF ANDROID} 
161-   PYTHON_KNOWN_VERSIONS: array [6 ..9 ] of  TPythonVersionProp =
164+   PYTHON_KNOWN_VERSIONS: array [6 ..10 ] of  TPythonVersionProp =
162165    (
163166    (DllName: ' libpython3.8.so' ' 3.8' 1013 ),
164167    (DllName: ' libpython3.9.so' ' 3.9' 1013 ),
165168    (DllName: ' libpython3.10.so' ' 3.10' 1013 ),
166-     (DllName: ' libpython3.11.so' ' 3.11' 1013 )
169+     (DllName: ' libpython3.11.so' ' 3.11' 1013 ),
170+     (DllName: ' libpython3.12.so' ' 3.12' 1013 )
167171    );
168172{ $ENDIF} 
169173
@@ -1274,7 +1278,6 @@   TPythonInterface=class(TDynamicDll)
12741278    procedure  AfterLoad ; override;
12751279    function   GetQuitMessage  : string; override;
12761280    procedure  CheckPython ;
1277-     function   GetUnicodeTypeSuffix  : string;
12781281
12791282  public 
12801283    //  define Python flags. See file pyDebug.h
@@ -1607,7 +1610,7 @@   TPythonInterface=class(TDynamicDll)
16071610    PyUnicode_DecodeUTF16:function (const  s:PAnsiChar; size: NativeInt; const  errors: PAnsiChar; byteoder: PInteger):PPyObject; cdecl;
16081611    PyUnicode_AsEncodedString:function (unicode:PPyObject; const  encoding:PAnsiChar; const  errors:PAnsiChar):PPyObject; cdecl;
16091612    PyUnicode_FromOrdinal:function (ordinal:integer):PPyObject; cdecl;
1610-     PyUnicode_GetSize :function (unicode:PPyObject):NativeInt; cdecl;
1613+     PyUnicode_GetLength :function (unicode:PPyObject):NativeInt; cdecl;
16111614    PyWeakref_GetObject: function ( ref : PPyObject) : PPyObject; cdecl;
16121615    PyWeakref_NewProxy: function ( ob, callback : PPyObject) : PPyObject; cdecl;
16131616    PyWeakref_NewRef: function ( ob, callback : PPyObject) : PPyObject; cdecl;
@@ -3464,28 +3467,8 @@ procedure TPythonInterface.CheckPython;
34643467    raise Exception.Create(' Python is not properly initialized' 
34653468end ;
34663469
3467- function   TPythonInterface.GetUnicodeTypeSuffix  : string;
3468- begin 
3469-   if  (fMajorVersion > 3 ) or  ((fMajorVersion = 3 ) and  (fMinorVersion >= 3 )) then 
3470-     Result := ' ' 
3471-   else  if  APIVersion >= 1011  then 
3472-     Result :=
3473-       { $IF DEFINED(MSWINDOWS) or DEFINED(DARWIN) or DEFINED(SOLARIS)} 
3474-         ' UCS2' 
3475-       { $ELSE} 
3476-         ' UCS4' 
3477-       { $IFEND} 
3478-   else 
3479-     Result := ' ' 
3480- end ;
3481- 
34823470procedure  TPythonInterface.MapDll ;
3483- Var 
3484-   UnicodeSuffix : string;
3485- 
34863471begin 
3487-   UnicodeSuffix := GetUnicodeTypeSuffix;
3488- 
34893472  Py_DebugFlag               := Import (' Py_DebugFlag' 
34903473  Py_VerboseFlag             := Import (' Py_VerboseFlag' 
34913474  Py_InteractiveFlag         := Import (' Py_InteractiveFlag' 
@@ -3796,18 +3779,18 @@ procedure TPythonInterface.MapDll;
37963779  PyType_GenericAlloc         := Import (' PyType_GenericAlloc' 
37973780  PyType_GenericNew           := Import (' PyType_GenericNew' 
37983781  PyType_Ready                := Import (' PyType_Ready' 
3799-   PyUnicode_FromWideChar      := Import (AnsiString(Format( ' PyUnicode%s_FromWideChar ' ,[UnicodeSuffix])) );
3800-   PyUnicode_FromString        := Import (AnsiString(Format( ' PyUnicode%s_FromString ' ,[UnicodeSuffix])) );
3801-   PyUnicode_FromStringAndSize := Import (AnsiString(Format( ' PyUnicode%s_FromStringAndSize ' ,[UnicodeSuffix])) );
3802-   PyUnicode_FromKindAndData   := Import (AnsiString(Format( ' PyUnicode%s_FromKindAndData ' ,[UnicodeSuffix])) );
3803-   PyUnicode_AsWideChar        := Import (AnsiString(Format( ' PyUnicode%s_AsWideChar ' ,[UnicodeSuffix])) );
3804-   PyUnicode_AsUTF8            := Import (AnsiString(Format( ' PyUnicode%s_AsUTF8 ' ,[UnicodeSuffix])) );
3805-   PyUnicode_AsUTF8AndSize     := Import (AnsiString(Format( ' PyUnicode%s_AsUTF8AndSize ' ,[UnicodeSuffix])) );
3806-   PyUnicode_Decode            := Import (AnsiString(Format( ' PyUnicode%s_Decode ' ,[UnicodeSuffix])) );
3807-   PyUnicode_DecodeUTF16       := Import (AnsiString(Format( ' PyUnicode%s_DecodeUTF16 ' ,[UnicodeSuffix])) );
3808-   PyUnicode_AsEncodedString   := Import (AnsiString(Format( ' PyUnicode%s_AsEncodedString ' ,[UnicodeSuffix])) );
3809-   PyUnicode_FromOrdinal       := Import (AnsiString(Format( ' PyUnicode%s_FromOrdinal ' ,[UnicodeSuffix])) );
3810-   PyUnicode_GetSize             := Import (AnsiString(Format( ' PyUnicode%s_GetSize ' ,[UnicodeSuffix])) );
3782+   PyUnicode_FromWideChar      := Import (' PyUnicode_FromWideChar ' 
3783+   PyUnicode_FromString        := Import (' PyUnicode_FromString ' 
3784+   PyUnicode_FromStringAndSize := Import (' PyUnicode_FromStringAndSize ' 
3785+   PyUnicode_FromKindAndData   := Import (' PyUnicode_FromKindAndData ' 
3786+   PyUnicode_AsWideChar        := Import (' PyUnicode_AsWideChar ' 
3787+   PyUnicode_AsUTF8            := Import (' PyUnicode_AsUTF8 ' 
3788+   PyUnicode_AsUTF8AndSize     := Import (' PyUnicode_AsUTF8AndSize ' 
3789+   PyUnicode_Decode            := Import (' PyUnicode_Decode ' 
3790+   PyUnicode_DecodeUTF16       := Import (' PyUnicode_DecodeUTF16 ' 
3791+   PyUnicode_AsEncodedString   := Import (' PyUnicode_AsEncodedString ' 
3792+   PyUnicode_FromOrdinal       := Import (' PyUnicode_FromOrdinal ' 
3793+   PyUnicode_GetLength          := Import (' PyUnicode_GetLength ' 
38113794  PyWeakref_GetObject         := Import (' PyWeakref_GetObject' 
38123795  PyWeakref_NewProxy          := Import (' PyWeakref_NewProxy' 
38133796  PyWeakref_NewRef            := Import (' PyWeakref_NewRef' 
@@ -6055,35 +6038,24 @@ function TPythonEngine.PyBytesAsAnsiString(obj: PPyObject): AnsiString;
60556038    raise EPythonError.CreateFmt(SPyConvertionError, [' PyBytesAsAnsiString' ' Bytes' 
60566039end ;
60576040
6058- function  TPythonEngine.PyUnicodeAsString (  obj : PPyObject )  : UnicodeString;
6041+ function  TPythonEngine.PyUnicodeAsString (obj : PPyObject) : UnicodeString;
60596042var 
6060-   _size : Integer;
6061- { $IFDEF POSIX} 
6062-   _ucs4Str : UCS4String;
6063- { $ENDIF} 
6043+   Buffer: PAnsiChar;
6044+   Size: NativeInt;
6045+   NewSize: Cardinal;
60646046begin 
60656047  if  PyUnicode_Check(obj) then 
60666048  begin 
6067-     _size := PyUnicode_GetSize(obj);
6068-     if  _size > 0  then 
6069-     begin 
6070- { $IFDEF POSIX} 
6071-       //  Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!!
6072-       SetLength(_ucs4Str, _size+1 );
6073-       if  PyUnicode_AsWideChar(obj, @_ucs4Str[0 ], _size) <> _size then 
6074-         raise EPythonError.Create(' Could not copy the whole Unicode string into its buffer' 
6075-       Result := UCS4StringToWideString(_ucs4Str);
6076-       //  remove trailing zeros
6077-       while  (Length(Result) > 0 ) and  (Result[Length(Result)] = #0 ) do 
6078-         Delete(Result, Length(Result), 1 );
6079- { $ELSE} 
6080-       SetLength(Result, _size);
6081-       if  PyUnicode_AsWideChar(obj, @Result[1 ], _size) <> _size then 
6082-         raise EPythonError.Create(' Could not copy the whole Unicode string into its buffer' 
6083- { $ENDIF} 
6084-     end 
6085-     else 
6086-       Result := ' ' 
6049+     //  Size does not include the final #0
6050+     Buffer := PyUnicode_AsUTF8AndSize(obj, @Size);
6051+     SetLength(Result, Size);
6052+     if  (Size = 0 ) or  (Buffer = nil ) then 
6053+       Exit;
6054+ 
6055+     //  The second argument is the size of the destination (Result) including #0
6056+     NewSize := Utf8ToUnicode(PChar(Result), Cardinal(Size + 1 ), Buffer, Cardinal(Size));
6057+     //  NewSize includes #0
6058+     SetLength(Result, NewSize - 1 );
60876059  end 
60886060  else 
60896061    raise EPythonError.CreateFmt(SPyConvertionError, [' PyUnicodeAsString' ' Unicode' 
0 commit comments