diff --git a/Demos/Demo06/Unit1.pas b/Demos/Demo06/Unit1.pas
index e038b4fa..cf6e6faf 100644
--- a/Demos/Demo06/Unit1.pas
+++ b/Demos/Demo06/Unit1.pas
@@ -42,7 +42,7 @@ TForm1 = class(TForm)
end;
PyPointRec = record
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
po_x : Integer;
po_y : Integer;
diff --git a/Demos/Demo07/Unit1.pas b/Demos/Demo07/Unit1.pas
index f33b8817..3514b6a3 100644
--- a/Demos/Demo07/Unit1.pas
+++ b/Demos/Demo07/Unit1.pas
@@ -48,7 +48,7 @@ TForm1 = class(TForm)
end;
PyPointRec = record
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
po_x : Integer;
po_y : Integer;
diff --git a/Demos/FPC/Demo06/Unit1.pas b/Demos/FPC/Demo06/Unit1.pas
index 34c8a901..75e705bb 100644
--- a/Demos/FPC/Demo06/Unit1.pas
+++ b/Demos/FPC/Demo06/Unit1.pas
@@ -47,7 +47,7 @@ TForm1 = class(TForm)
end;
PyPointRec = record
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
po_x : Integer;
po_y : Integer;
diff --git a/Packages/Delphi/Delphi 10.4+/Python.dproj b/Packages/Delphi/Delphi 10.4+/Python.dproj
index c41368d4..568730b8 100644
--- a/Packages/Delphi/Delphi 10.4+/Python.dproj
+++ b/Packages/Delphi/Delphi 10.4+/Python.dproj
@@ -7,8 +7,9 @@
Python.dpk
Win32
{018AAA56-F5BD-4A04-BCCA-A0043EAAA5CE}
- 19.5
- 168083
+ 20.1
+ 693395
+ Python
true
@@ -54,6 +55,12 @@
true
true
+
+ true
+ Cfg_1
+ true
+ true
+
true
Cfg_1
@@ -88,7 +95,7 @@
..\..\..\lib\$(Platform)\$(Config)
Python4Delphi - Run-time Engine Package
00400000
- Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;DUnitX.Loggers.GUI;Winapi;System.Win;$(DCC_Namespace)
+ System;Xml;Data;Datasnap;Web;Soap;DUnitX.Loggers.GUI;Winapi;System.Win;$(DCC_Namespace)
$(Auto)
true
true
@@ -109,11 +116,11 @@
Debug
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
@@ -136,6 +143,9 @@
1
package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+
+ Debug
+
true
CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
@@ -204,13 +214,14 @@
True
True
+ True
+ True
True
True
True
True
True
- False
- False
+ False
12
diff --git a/Packages/Delphi/Delphi 10.4+/PythonFmx.dproj b/Packages/Delphi/Delphi 10.4+/PythonFmx.dproj
index 224e44cc..e45231c0 100644
--- a/Packages/Delphi/Delphi 10.4+/PythonFmx.dproj
+++ b/Packages/Delphi/Delphi 10.4+/PythonFmx.dproj
@@ -7,8 +7,9 @@
PythonFmx.dpk
Win32
{513BF750-373D-4C95-A672-78CA8DDF3F63}
- 19.5
- 167955
+ 20.1
+ 693395
+ PythonFmx
true
@@ -59,9 +60,14 @@
Base
true
+
+ true
+ Cfg_2
+ true
+ true
+
PythonFmx
- All
..\..\..\lib\$(Platform)\$(Config)
Python4Delphi - Run-time Engine Package for FMX
.\$(Platform)\$(Config)
@@ -87,11 +93,11 @@
Debug
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
- CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false
+ CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
Debug
@@ -127,6 +133,9 @@
false
0
+
+ Debug
+
MainSource
@@ -185,13 +194,14 @@
True
True
- False
+ True
+ True
+ True
True
True
True
True
- False
- False
+ False
12
diff --git a/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dpk b/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dpk
deleted file mode 100644
index 9525324e..00000000
--- a/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dpk
+++ /dev/null
@@ -1,63 +0,0 @@
-package PythonFmxLinux;
-
-{$R *.res}
-{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
-{$ALIGN 8}
-{$ASSERTIONS ON}
-{$BOOLEVAL OFF}
-{$DEBUGINFO OFF}
-{$EXTENDEDSYNTAX ON}
-{$IMPORTEDDATA ON}
-{$IOCHECKS ON}
-{$LOCALSYMBOLS OFF}
-{$LONGSTRINGS ON}
-{$OPENSTRINGS ON}
-{$OPTIMIZATION ON}
-{$OVERFLOWCHECKS OFF}
-{$RANGECHECKS OFF}
-{$REFERENCEINFO OFF}
-{$SAFEDIVIDE OFF}
-{$STACKFRAMES OFF}
-{$TYPEDADDRESS OFF}
-{$VARSTRINGCHECKS ON}
-{$WRITEABLECONST OFF}
-{$MINENUMSIZE 1}
-{$DEFINE RELEASE}
-{$ENDIF IMPLICITBUILDING}
-{$DESCRIPTION 'Python4Delphi - Run-time Engine Package for FMXLinux'}
-{$LIBSUFFIX AUTO}
-{$RUNONLY}
-{$IMPLICITBUILD ON}
-
-requires
- rtl,
- python,
- fmx;
-
-contains
- FMX.PythonGUIInputOutput in '..\..\..\Source\fmx\FMX.PythonGUIInputOutput.pas',
- WrapDelphiFmx in '..\..\..\Source\fmx\WrapDelphiFmx.pas',
- WrapFmxActnList in '..\..\..\Source\fmx\WrapFmxActnList.pas',
- WrapFmxColors in '..\..\..\Source\fmx\WrapFmxColors.pas',
- WrapFmxComCtrls in '..\..\..\Source\fmx\WrapFmxComCtrls.pas',
- WrapFmxControls in '..\..\..\Source\fmx\WrapFmxControls.pas',
- WrapFmxDialogs in '..\..\..\Source\fmx\WrapFmxDialogs.pas',
- WrapFmxEdit in '..\..\..\Source\fmx\WrapFmxEdit.pas',
- WrapFmxForms in '..\..\..\Source\fmx\WrapFmxForms.pas',
- WrapFmxGrids in '..\..\..\Source\fmx\WrapFmxGrids.pas',
- WrapFmxLayouts in '..\..\..\Source\fmx\WrapFmxLayouts.pas',
- WrapFmxListBox in '..\..\..\Source\fmx\WrapFmxListBox.pas',
- WrapFmxListView in '..\..\..\Source\fmx\WrapFmxListView.pas',
- WrapFmxMedia in '..\..\..\Source\fmx\WrapFmxMedia.pas',
- WrapFmxMemo in '..\..\..\Source\fmx\WrapFmxMemo.pas',
- WrapFmxMenus in '..\..\..\Source\fmx\WrapFmxMenus.pas',
- WrapFmxScrollBox in '..\..\..\Source\fmx\WrapFmxScrollBox.pas',
- WrapFmxShapes in '..\..\..\Source\fmx\WrapFmxShapes.pas',
- WrapFmxStdActns in '..\..\..\Source\fmx\WrapFmxStdActns.pas',
- WrapFmxStdCtrls in '..\..\..\Source\fmx\WrapFmxStdCtrls.pas',
- WrapFmxStyles in '..\..\..\Source\fmx\WrapFmxStyles.pas',
- WrapFmxTypes in '..\..\..\Source\fmx\WrapFmxTypes.pas',
- WrapFmxDateTime in '..\..\..\Source\fmx\WrapFmxDateTime.pas';
-
-end.
-
diff --git a/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dproj b/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dproj
deleted file mode 100644
index 445f21ac..00000000
--- a/Packages/Delphi/Delphi 10.4+/PythonFmxLinux.dproj
+++ /dev/null
@@ -1,968 +0,0 @@
-
-
- {B0F48139-24FB-42F3-93E8-05DA2E142904}
- PythonFmxLinux.dpk
- True
- Release
- 128
- Package
- FMX
- 19.5
- Linux64
-
-
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_1
- true
- true
-
-
- true
- Base
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- true
- Cfg_2
- true
- true
-
-
- false
- false
- false
- false
- false
- 00400000
- true
- true
- PythonFmxLinux
- Python4Delphi - Run-time Engine Package for FMXLinux
- $(Auto)
- true
- 1046
- CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=
- System;Xml;Data;Datasnap;Web;Soap;REST.Authenticator.OAuth.WebForm;$(DCC_Namespace)
- $(BDSCatalogRepositoryAllUsers)\FmxLinux-1.71\redist;$(DCC_UnitSearchPath)
-
-
- package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
- Debug
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
- annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar
-
-
- $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
- annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar
-
-
- $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png
-
-
- Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
- Debug
- true
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
- 1033
-
-
- RELEASE;$(DCC_Define)
- 0
- false
- 0
-
-
- /usr/bin/gnome-terminal -- "%debuggee%"
-
-
- DEBUG;$(DCC_Define)
- false
- true
- true
- true
-
-
- Debug
-
-
- Debug
-
-
- Debug
-
-
- Debug
-
-
-
- MainSource
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Base
-
-
- Cfg_1
- Base
-
-
- Cfg_2
- Base
-
-
-
- Delphi.Personality.12
- Package
-
-
-
- PythonFmxLinux.dpk
-
-
- Embarcadero C++Builder Office 2000 Servers Package
- Embarcadero C++Builder Office XP Servers Package
- Microsoft Office 2000 Sample Automation Server Wrapper Components
- Microsoft Office XP Sample Automation Server Wrapper Components
-
-
-
- False
- False
- False
- False
- True
- False
- False
- False
- False
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- bplPythonFmxLinux.so
- true
-
-
-
-
- PythonFmxLinux.bpl
- true
-
-
-
-
- 1
-
-
- 0
-
-
-
-
- classes
- 64
-
-
- classes
- 64
-
-
-
-
- res\xml
- 1
-
-
- res\xml
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- library\lib\armeabi
- 1
-
-
- library\lib\armeabi
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- library\lib\mips
- 1
-
-
- library\lib\mips
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
- library\lib\arm64-v8a
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- res\drawable
- 1
-
-
- res\drawable
- 1
-
-
-
-
- res\values
- 1
-
-
- res\values
- 1
-
-
-
-
- res\values-v21
- 1
-
-
- res\values-v21
- 1
-
-
-
-
- res\values
- 1
-
-
- res\values
- 1
-
-
-
-
- res\drawable
- 1
-
-
- res\drawable
- 1
-
-
-
-
- res\drawable-xxhdpi
- 1
-
-
- res\drawable-xxhdpi
- 1
-
-
-
-
- res\drawable-xxxhdpi
- 1
-
-
- res\drawable-xxxhdpi
- 1
-
-
-
-
- res\drawable-ldpi
- 1
-
-
- res\drawable-ldpi
- 1
-
-
-
-
- res\drawable-mdpi
- 1
-
-
- res\drawable-mdpi
- 1
-
-
-
-
- res\drawable-hdpi
- 1
-
-
- res\drawable-hdpi
- 1
-
-
-
-
- res\drawable-xhdpi
- 1
-
-
- res\drawable-xhdpi
- 1
-
-
-
-
- res\drawable-mdpi
- 1
-
-
- res\drawable-mdpi
- 1
-
-
-
-
- res\drawable-hdpi
- 1
-
-
- res\drawable-hdpi
- 1
-
-
-
-
- res\drawable-xhdpi
- 1
-
-
- res\drawable-xhdpi
- 1
-
-
-
-
- res\drawable-xxhdpi
- 1
-
-
- res\drawable-xxhdpi
- 1
-
-
-
-
- res\drawable-xxxhdpi
- 1
-
-
- res\drawable-xxxhdpi
- 1
-
-
-
-
- res\drawable-small
- 1
-
-
- res\drawable-small
- 1
-
-
-
-
- res\drawable-normal
- 1
-
-
- res\drawable-normal
- 1
-
-
-
-
- res\drawable-large
- 1
-
-
- res\drawable-large
- 1
-
-
-
-
- res\drawable-xlarge
- 1
-
-
- res\drawable-xlarge
- 1
-
-
-
-
- res\values
- 1
-
-
- res\values
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 0
-
-
-
-
- 1
- .framework
-
-
- 1
- .framework
-
-
- 1
- .framework
-
-
- 0
-
-
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 0
- .dll;.bpl
-
-
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 1
- .dylib
-
-
- 0
- .bpl
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
- ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
-
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
-
-
-
- Contents\Resources
- 1
-
-
- Contents\Resources
- 1
-
-
- Contents\Resources
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
- library\lib\arm64-v8a
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 0
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12
-
-
-
-
-
diff --git a/Packages/Delphi/Delphi 10.4+/PythonVcl.dproj b/Packages/Delphi/Delphi 10.4+/PythonVcl.dproj
index 3f40f175..9ccee1e3 100644
--- a/Packages/Delphi/Delphi 10.4+/PythonVcl.dproj
+++ b/Packages/Delphi/Delphi 10.4+/PythonVcl.dproj
@@ -7,7 +7,8 @@
PythonVcl.dpk
Win32
{D8908301-393C-4CFA-8842-4948A9935E21}
- 19.5
+ PythonVcl
+ 20.1
3
@@ -144,13 +145,14 @@
False
False
+ False
+ False
False
False
False
True
True
- False
- False
+ False
12
diff --git a/Packages/Delphi/Delphi 10.4+/dclPython.dproj b/Packages/Delphi/Delphi 10.4+/dclPython.dproj
index a2f01927..749430a6 100644
--- a/Packages/Delphi/Delphi 10.4+/dclPython.dproj
+++ b/Packages/Delphi/Delphi 10.4+/dclPython.dproj
@@ -7,7 +7,8 @@
dclPython.dpk
Win32
{D9AB994C-54A3-4E76-81C8-6D0BB035A091}
- 19.5
+ dclPython
+ 20.1
1
@@ -149,6 +150,7 @@
False
True
False
+ False
False
False
diff --git a/Packages/Delphi/Delphi 10.4+/dclPythonFmx.dproj b/Packages/Delphi/Delphi 10.4+/dclPythonFmx.dproj
index 9fed4132..1104549c 100644
--- a/Packages/Delphi/Delphi 10.4+/dclPythonFmx.dproj
+++ b/Packages/Delphi/Delphi 10.4+/dclPythonFmx.dproj
@@ -7,7 +7,8 @@
dclPythonFmx.dpk
Win32
{E057921E-25DB-426E-8090-FE3F428894FF}
- 19.5
+ dclPythonFmx
+ 20.1
1
@@ -125,6 +126,7 @@
False
True
False
+ False
False
False
diff --git a/Packages/Delphi/Delphi 10.4+/dclPythonVcl.dproj b/Packages/Delphi/Delphi 10.4+/dclPythonVcl.dproj
index 3944b8d3..7a1e1ec3 100644
--- a/Packages/Delphi/Delphi 10.4+/dclPythonVcl.dproj
+++ b/Packages/Delphi/Delphi 10.4+/dclPythonVcl.dproj
@@ -7,7 +7,8 @@
dclPythonVcl.dpk
Win32
{48DDC28A-E154-4CA0-864A-30EB8C4CCBB3}
- 19.5
+ dclPythonVcl
+ 20.1
1
@@ -125,6 +126,7 @@
False
True
False
+ False
False
False
diff --git a/Packages/Delphi/P4DLinuxComponentSuite.groupproj b/Packages/Delphi/P4DLinuxComponentSuite.groupproj
deleted file mode 100644
index 544e8812..00000000
--- a/Packages/Delphi/P4DLinuxComponentSuite.groupproj
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
- {8BE1193B-E609-445D-9BA3-F57DBEA042F5}
-
-
-
-
-
-
- Delphi 10.4+\Python.dproj
-
-
- Delphi 10.4+\Python.dproj
-
-
- Delphi 10.4+\PythonVcl.dproj
-
-
-
-
-
-
-
-
-
-
-
-
- Default.Personality.12
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas
index c08ea1dc..11ad3803 100644
--- a/Source/PythonEngine.pas
+++ b/Source/PythonEngine.pas
@@ -73,47 +73,51 @@ TPythonVersionProp = record
end;
const
{$IFDEF MSWINDOWS}
- PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
(
(DllName: 'python38.dll'; RegVersion: '3.8'; APIVersion: 1013),
(DllName: 'python39.dll'; RegVersion: '3.9'; APIVersion: 1013),
(DllName: 'python310.dll'; RegVersion: '3.10'; APIVersion: 1013),
(DllName: 'python311.dll'; RegVersion: '3.11'; APIVersion: 1013),
(DllName: 'python312.dll'; RegVersion: '3.12'; APIVersion: 1013),
- (DllName: 'python313.dll'; RegVersion: '3.13'; APIVersion: 1013)
+ (DllName: 'python313.dll'; RegVersion: '3.13'; APIVersion: 1013),
+ (DllName: 'python314.dll'; RegVersion: '3.14'; APIVersion: 1013)
);
{$ENDIF}
{$IFDEF _so_files}
- PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
(
(DllName: 'libpython3.8.so'; RegVersion: '3.8'; APIVersion: 1013),
(DllName: 'libpython3.9.so'; RegVersion: '3.9'; APIVersion: 1013),
(DllName: 'libpython3.10.so'; RegVersion: '3.10'; APIVersion: 1013),
(DllName: 'libpython3.11.so'; RegVersion: '3.11'; APIVersion: 1013),
(DllName: 'libpython3.12.so'; RegVersion: '3.12'; APIVersion: 1013),
- (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013)
+ (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013),
+ (DllName: 'libpython3.14.so'; RegVersion: '3.14'; APIVersion: 1013)
);
{$ENDIF}
{$IFDEF DARWIN}
- PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
(
(DllName: 'libpython3.8.dylib'; RegVersion: '3.8'; APIVersion: 1013),
(DllName: 'libpython3.9.dylib'; RegVersion: '3.9'; APIVersion: 1013),
(DllName: 'libpython3.10.dylib'; RegVersion: '3.10'; APIVersion: 1013),
(DllName: 'libpython3.11.dylib'; RegVersion: '3.11'; APIVersion: 1013),
(DllName: 'libpython3.12.dylib'; RegVersion: '3.12'; APIVersion: 1013),
- (DllName: 'libpython3.13.dylib'; RegVersion: '3.13'; APIVersion: 1013)
+ (DllName: 'libpython3.13.dylib'; RegVersion: '3.13'; APIVersion: 1013),
+ (DllName: 'libpython3.14.dylib'; RegVersion: '3.14'; APIVersion: 1013)
);
{$ENDIF}
{$IFDEF ANDROID}
- PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
(
(DllName: 'libpython3.8.so'; RegVersion: '3.8'; APIVersion: 1013),
(DllName: 'libpython3.9.so'; RegVersion: '3.9'; APIVersion: 1013),
(DllName: 'libpython3.10.so'; RegVersion: '3.10'; APIVersion: 1013),
(DllName: 'libpython3.11.so'; RegVersion: '3.11'; APIVersion: 1013),
- (DllName: 'libpython3.12.so'; RegVersion: '3.12'; APIVersion: 1013)
- (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013)
+ (DllName: 'libpython3.12.so'; RegVersion: '3.12'; APIVersion: 1013),
+ (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013),
+ (DllName: 'libpython3.14.so'; RegVersion: '3.14'; APIVersion: 1013)
);
{$ENDIF}
@@ -176,8 +180,8 @@ TPythonVersionProp = record
WCharTString = UnicodeString;
{$ENDIF}
- PPy_ssize_t = PNativeInt;
- Py_ssize_t = NativeInt;
+ PPy_ssize_t = PNativeUInt;
+ Py_ssize_t = NativeUInt;
const
{
@@ -340,6 +344,20 @@ TPythonVersionProp = record
PyBUF_READ = $100;
PyBUF_WRITE = $200;
+const
+ // constants used in PyModuleDef slots from moduleobject.h
+ Py_mod_create = 1;
+ Py_mod_exec = 2;
+ Py_mod_multiple_interpreters = 3; // Added in version 3.12
+ Py_mod_gil = 4; // Added in version 3.13
+
+ Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED: Pointer = Pointer(0);
+ Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED: Pointer = Pointer(1);
+ Py_MOD_PER_INTERPRETER_GIL_SUPPORTED: Pointer = Pointer(2);
+
+ Py_MOD_GIL_USED: Pointer = Pointer(0);
+ Py_MOD_GIL_NOT_USED: Pointer = Pointer(1);
+
//#######################################################
//## ##
//## Non-Python specific constants ##
@@ -470,7 +488,7 @@ TPythonVersionProp = record
end;
PyObject = {$IFDEF CPUX86}packed{$ENDIF} record
- ob_refcnt: NativeInt;
+ ob_refcnt: NativeUInt;
ob_type: PPyTypeObject;
end;
@@ -481,7 +499,7 @@ TPythonVersionProp = record
end;
PySliceObject = {$IFDEF CPUX86}packed{$ENDIF} record
- ob_refcnt: NativeInt;
+ ob_refcnt: NativeUInt;
ob_type: PPyTypeObject;
start, stop, step: PPyObject;
end;
@@ -534,28 +552,31 @@ TPythonVersionProp = record
{#define PyDescr_COMMON \
PyObject_HEAD \
PyTypeObject *d_type; \
- PyObject *d_name
+ PyObject *d_name \
+ PyObject *d_qualname
}
PPyDescrObject = ^PyDescrObject;
PyDescrObject = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
d_type : PPyTypeObject;
d_name : PPyObject;
+ d_qualname : PPyObject;
end;
PPyMethodDescrObject = ^PyMethodDescrObject;
PyMethodDescrObject = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of PyDescr_COMMON
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
d_type : PPyTypeObject;
d_name : PPyObject;
+ d_qualname : PPyObject;
// End of PyDescr_COMMON
d_method : PPyMethodDef;
end;
@@ -564,11 +585,12 @@ TPythonVersionProp = record
PyMemberDescrObject = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of PyDescr_COMMON
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
d_type : PPyTypeObject;
d_name : PPyObject;
+ d_qualname : PPyObject;
// End of PyDescr_COMMON
d_member : PPyMemberDef;
end;
@@ -577,11 +599,12 @@ TPythonVersionProp = record
PyGetSetDescrObject = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of PyDescr_COMMON
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
d_type : PPyTypeObject;
d_name : PPyObject;
+ d_qualname : PPyObject;
// End of PyDescr_COMMON
d_getset : PPyGetSetDef;
end;
@@ -590,11 +613,12 @@ TPythonVersionProp = record
PyWrapperDescrObject = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of PyDescr_COMMON
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
d_type : PPyTypeObject;
d_name : PPyObject;
+ d_qualname : PPyObject;
// End of PyDescr_COMMON
d_base : pwrapperbase;
d_wrapped : Pointer; // This can be any function pointer
@@ -603,7 +627,7 @@ TPythonVersionProp = record
PPyModuleDef_Base = ^PyModuleDef_Base;
PyModuleDef_Base = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
m_init : function( ) : PPyObject; cdecl;
@@ -633,6 +657,10 @@ TPythonVersionProp = record
m_free : inquiry;
end;
+ // signature of functions used in slots
+ Py_create_module_function = function(spec: PPyObject; def: PPyModuleDef):PPyObject; cdecl;
+ Py_exec_module_function = function(module: PPyObject): Integer; cdecl;
+
// pybuffer.h
PPy_buffer = ^Py_Buffer;
@@ -663,7 +691,7 @@ PyBufferProcs = record
// object.h
PyTypeObject = {$IFDEF CPUX86}packed{$ENDIF} record
- ob_refcnt: NativeInt;
+ ob_refcnt: NativeUInt;
ob_type: PPyTypeObject;
ob_size: NativeInt; // Number of items in variable part
tp_name: PAnsiChar; // For printing
@@ -810,7 +838,7 @@ PyBufferProcs = record
type
PyDateTime_Delta = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : NativeInt; // -1 when unknown
@@ -822,7 +850,7 @@ PyBufferProcs = record
PyDateTime_TZInfo = {$IFDEF CPUX86}packed{$ENDIF} record // a pure abstract base clase
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
end;
@@ -845,7 +873,7 @@ PyBufferProcs = record
_PyDateTime_BaseTZInfo = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -869,7 +897,7 @@ PyBufferProcs = record
// Start of _PyDateTime_TIMEHEAD
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -884,7 +912,7 @@ PyBufferProcs = record
// Start of _PyDateTime_TIMEHEAD
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -906,7 +934,7 @@ PyBufferProcs = record
PyDateTime_Date = {$IFDEF CPUX86}packed{$ENDIF} record
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -925,7 +953,7 @@ PyBufferProcs = record
_PyDateTime_BaseDateTime = {$IFDEF CPUX86}packed{$ENDIF} record // hastzinfo false
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -939,7 +967,7 @@ PyBufferProcs = record
// Start of _PyDateTime_DATETIMEHEAD
// Start of _PyTZINFO_HEAD
// Start of the Head of an object
- ob_refcnt : NativeInt;
+ ob_refcnt : NativeUInt;
ob_type : PPyTypeObject;
// End of the Head of an object
hashcode : Integer;
@@ -954,7 +982,7 @@ PyBufferProcs = record
//bytearrayobject.h
PyByteArrayObject = {$IFDEF CPUX86}packed{$ENDIF} record
- ob_refcnt: NativeInt;
+ ob_refcnt: NativeUInt;
ob_type: PPyTypeObject;
ob_alloc: Py_ssize_t;
ob_bytes: PAnsiChar;
@@ -994,6 +1022,9 @@ PyConfig = record
Filler: array [0..1000] of Byte;
end;
+ // Opaque structure PEP 741
+ PPyInitConfig = Pointer;
+
{$SCOPEDENUMS ON}
TConfigFields = (
use_environment,
@@ -1021,7 +1052,7 @@ PyConfig = record
{$IFDEF CPU64BITS}
((8, 80, 88, 144, 156, 160, 164, 172, 224, 104, 240, 248, 256, 272),
(8, 80, 88, 144, 156, 160, 164, 172, 224, 104, 240, 248, 256, 272),
- (8, 80, 104, 152, 168, 172, 176, 184, 232, 240, 256, 272, 280, 296),
+ (8, 80, 104, 152, 168, 172, 176, 184, 240, 248, 264, 280, 288, 304),
(8, 96, 120, 168, 184, 188, 192, 200, 264, 272, 288, 304, 312, 336),
(8, 96, 120, 168, 184, 188, 192, 200, 268, 272, 288, 304, 312, 336),
(8, 96, 120, 168, 184, 188, 192, 200, 272, 280, 296, 312, 320, 344));
@@ -1506,6 +1537,7 @@ TPythonInterface=class(TDynamicDll)
PySuper_Type: PPyTypeObject;
PyTraceBack_Type: PPyTypeObject;
PyUnicode_Type: PPyTypeObject;
+ PyGetSetDescr_Type: PPyTypeObject;
PyWrapperDescr_Type: PPyTypeObject;
_PyWeakref_RefType: PPyTypeObject;
_PyWeakref_ProxyType: PPyTypeObject;
@@ -1527,6 +1559,9 @@ TPythonInterface=class(TDynamicDll)
PyCallable_Check: function(ob : PPyObject): integer; cdecl;
PyModule_Create2: function(moduledef: PPyModuleDef; Api_Version: Integer):PPyObject; cdecl;
+ PyModuleDef_Init: function(moduledef: PPyModuleDef):PPyObject; cdecl;
+ PyModule_ExecDef: function(module: PPyObject; moduledef: PPyModuleDef):Integer; cdecl;
+ PyModule_FromDefAndSpec2: function(moduledef: PPyModuleDef; spec: PPyObject; Api_Version: Integer):PPyObject; cdecl;
PyErr_BadArgument: function: integer; cdecl;
PyErr_BadInternalCall: procedure; cdecl;
PyErr_CheckSignals: function: integer; cdecl;
@@ -1635,6 +1670,7 @@ TPythonInterface=class(TDynamicDll)
PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl;
PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl;
PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl;
+ PyLong_AsVoidPtr:function(ob:PPyObject): Pointer; cdecl;
PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl;
PyMapping_Check:function (ob:PPyObject):integer; cdecl;
PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl;
@@ -1796,8 +1832,9 @@ TPythonInterface=class(TDynamicDll)
Py_GetPrefix : function : PWCharT; cdecl;
Py_GetProgramName : function : PWCharT; cdecl;
- PyErr_NewException : function ( name : PAnsiChar; base, dict : PPyObject ) : PPyObject; cdecl;
- PyMem_Malloc : function ( size : NativeUInt ) : Pointer;
+ PyErr_NewException : function (name : PAnsiChar; base, dict : PPyObject): PPyObject; cdecl;
+ PyMem_Malloc : function (size: NativeUInt): Pointer; cdecl;
+ PyMem_Free : procedure (P: Pointer); cdecl;
Py_IsInitialized : function : integer; cdecl;
Py_GetProgramFullPath : function : PAnsiChar; cdecl;
@@ -1818,7 +1855,7 @@ TPythonInterface=class(TDynamicDll)
PyGILState_Ensure : function() : PyGILstate_STATE; cdecl;
PyGILState_Release : procedure(gilstate : PyGILState_STATE); cdecl;
- // Initialization functions
+ // PEP 587 Initialization functions
PyWideStringList_Append : function(list: PPyWideStringList; item: PWCharT): PyStatus; cdecl;
PyWideStringList_Insert : function(list: PPyWideStringList; index: Py_ssize_t; item: PWCharT): PyStatus; cdecl;
PyConfig_InitPythonConfig : procedure(var config: PyConfig); cdecl;
@@ -1830,6 +1867,17 @@ TPythonInterface=class(TDynamicDll)
PyConfig_SetWideStringList : function(var config: PyConfig; list: PPyWideStringList; length: Py_ssize_t; items: PPWCharT): PyStatus; cdecl;
Py_InitializeFromConfig : function({$IFDEF FPC}constref{$ELSE}[Ref] const{$ENDIF} config: PyConfig): PyStatus; cdecl;
+ // PEP 741 Initialization functions - python 3.14+
+ PyInitConfig_Create : function(): PPyInitConfig; cdecl;
+ PyInitConfig_Free : procedure(config: PPyInitConfig); cdecl;
+ Py_InitializeFromInitConfig : function(config: PPyInitConfig): Integer; cdecl;
+ PyInitConfig_SetInt : function(config: PPyInitConfig; name: PAnsiChar; value: Int64): Integer; cdecl;
+ PyInitConfig_SetStr : function(config: PPyInitConfig; name: PAnsiChar; value: PAnsiChar): Integer; cdecl;
+ PyInitConfig_SetStrList : function(config: PPyInitConfig; name: PAnsiChar; Lenght: Py_ssize_t; value: PPAnsiChar): Integer; cdecl;
+ PyInitConfig_GetError : function(config: PPyInitConfig; err_msg: PPAnsiChar): integer; cdecl;
+ PyConfig_Get : function(name: PAnsiChar): PPyObject; cdecl;
+ PyConfig_Set : function(name: PAnsiChar; value: PPyObject): Integer; cdecl;
+
function Py_CompileString(str,filename:PAnsiChar;start:integer) : PPyObject; cdecl;
// functions redefined in Delphi
@@ -1934,15 +1982,26 @@ TPythonInterface=class(TDynamicDll)
//--------------------------------------------------------
type
TDatetimeConversionMode = (dcmToTuple, dcmToDatetime);
+ TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfVerbose,
+ pfFrozen, pfIgnoreEnvironment, pfNoUserSiteDirectory,
+ pfDontWriteBytecode, pfIsolated);
+ TPythonFlags = set of TPythonFlag;
+
const
DEFAULT_DATETIME_CONVERSION_MODE = dcmToTuple;
+ DEFAULT_FLAGS =
+ {$IFDEF IOS}
+ [pfIsolated, pfNoUserSiteDirectory, pfIgnoreEnvironment,
+ pfDontWriteBytecodeFlag]
+ {$ELSE}
+ []
+ {$ENDIF IOS};
+
type
TEngineClient = class;
TSysPathInitEvent = procedure(Sender: TObject; PathList: PPyObject) of object;
- TConfigInitEvent = procedure(Sender: TObject; var Config: PyConfig) of object;
- TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfVerbose,
- pfFrozenFlag, pfIgnoreEnvironmentFlag, pfIsolated);
- TPythonFlags = set of TPythonFlag;
+ // Config will be either PPyConfig if version < 3.14 or PPyInitConfig
+ TConfigInitEvent = procedure(Sender: TObject; Config: Pointer) of object;
TTracebackItem = class
@@ -1979,7 +2038,7 @@ TPythonType = class; //forward declaration
{$IFEND}
TPythonEngine = class(TPythonInterface)
private
- FVenvPythonExe: string;
+ FPythonExecutable: string;
FInitScript: TStrings;
FIO: TPythonInputOutput;
FRedirectIO: Boolean;
@@ -2021,14 +2080,12 @@ TPythonEngine = class(TPythonInterface)
function GetClients( idx : Integer ) : TEngineClient;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
- procedure SetProgramArgs(var Config: PyConfig);
procedure InitWinConsole;
procedure SetUseWindowsConsole( const Value : Boolean );
procedure SetGlobalVars(const Value: PPyObject);
procedure SetLocalVars(const Value: PPyObject);
procedure SetPyFlags(const Value: TPythonFlags);
procedure SetIO(InputOutput: TPythonInputOutput);
- procedure AssignPyFlags(var Config: PyConfig);
public
// Constructors & Destructors
@@ -2131,13 +2188,13 @@ TPythonEngine = class(TPythonInterface)
property PythonPath: UnicodeString read FPythonPath write FPythonPath;
published
property AutoFinalize: Boolean read FAutoFinalize write FAutoFinalize default True;
- property VenvPythonExe: string read FVenvPythonExe write FVenvPythonExe;
+ property PythonExecutable: string read FPythonExecutable write FPythonExecutable;
property DatetimeConversionMode: TDatetimeConversionMode read FDatetimeConversionMode write FDatetimeConversionMode default DEFAULT_DATETIME_CONVERSION_MODE;
property InitScript: TStrings read FInitScript write SetInitScript;
property IO: TPythonInputOutput read FIO write SetIO;
- property PyFlags: TPythonFlags read FPyFlags write SetPyFlags default [];
+ property PyFlags: TPythonFlags read FPyFlags write SetPyFlags default DEFAULT_FLAGS;
property RedirectIO: Boolean read FRedirectIO write FRedirectIO default True;
- property UseWindowsConsole: Boolean read FUseWindowsConsole write FUseWindowsConsole default False;
+ property UseWindowsConsole: Boolean read FUseWindowsConsole write SetUseWindowsConsole default False;
property OnAfterInit: TNotifyEvent read FOnAfterInit write FOnAfterInit;
property OnSysPathInit: TSysPathInitEvent read FOnSysPathInit write FOnSysPathInit;
property OnConfigInit: TConfigInitEvent read FOnConfigInit write FOnConfigInit;
@@ -2498,12 +2555,6 @@ TPythonModule = class(TMethodsContainer)
end;
-//-------------------------------------------------------
-//-- --
-//--class: TPythonType derived from TGetSetContainer --
-//-- --
-//-------------------------------------------------------
-
{
A B C
+-------------------++------------------------------------------------------+
@@ -2520,15 +2571,15 @@ TPythonModule = class(TMethodsContainer)
by GetSelf
- a Python object must start at A.
- - a Delphi class class must start at B
+ - a Delphi class must start at B
- TPyObject.InstanceSize will return C-B
- Sizeof(TPyObject) will return C-B
- The total memory allocated for a TPyObject instance will be C-A,
even if its InstanceSize is C-B.
- - When turning a Python object pointer into a Delphi instance pointer, PythonToDelphi
- will offset the pointer from A to B.
- - When turning a Delphi instance into a Python object pointer, GetSelf will offset
- Self from B to A.
+ - When turning a Python object pointer into a Delphi instance pointer,
+ PythonToDelphi will offset the pointer from A to B.
+ - When turning a Delphi instance into a Python object pointer, GetSelf
+ will offset Self from B to A.
- Properties ob_refcnt and ob_type will call GetSelf to access their data.
Further Notes:
@@ -2545,12 +2596,11 @@ TPythonModule = class(TMethodsContainer)
FreeInstance.
- This class is heart of the P4D library. Pure magic!!
}
- // The base class of all new Python types
TPyObject = class
private
- function Get_ob_refcnt: NativeInt;
+ function Get_ob_refcnt: NativeUInt;
function Get_ob_type: PPyTypeObject;
- procedure Set_ob_refcnt(const Value: NativeInt);
+ procedure Set_ob_refcnt(const Value: NativeUInt);
procedure Set_ob_type(const Value: PPyTypeObject);
public
PythonType : TPythonType;
@@ -2571,7 +2621,7 @@ TPyObject = class
procedure Adjust(PyPointer: Pointer);
function GetModule : TPythonModule;
- property ob_refcnt : NativeInt read Get_ob_refcnt write Set_ob_refcnt;
+ property ob_refcnt : NativeUInt read Get_ob_refcnt write Set_ob_refcnt;
property ob_type : PPyTypeObject read Get_ob_type write Set_ob_type;
// Type services
@@ -2715,8 +2765,15 @@ TTypeServices = class(TPersistent)
property Mapping : TMappingServices read FMapping write FMapping;
end;
- // The component that initializes the Python type and
- // that creates instances of itself.
+//-------------------------------------------------------
+//-- --
+//--class: TPythonType derived from TGetSetContainer --
+//-- --
+//-------------------------------------------------------
+
+ // The component that initializes a Python type and
+ // creates instances of itself.
+ // The base class of all new Python types
{$IF not Defined(FPC) and (CompilerVersion >= 23)}
[ComponentPlatformsAttribute(pidSupportedPlatforms)]
{$IFEND}
@@ -3044,6 +3101,59 @@ implementation
SPyExcSystemError = 'Unhandled SystemExit exception. Code: %s';
SPyInitFailed = 'Python initialization failed: %s';
SPyInitFailedUnknown = 'Unknown initialization error';
+SCannotCreateMain = 'Run_CommandAsObject: can''t create __main__';
+SRaiseError = 'RaiseError: couldn''t fetch last exception';
+SMissingModuleDateTime = 'dcmToDatetime DatetimeConversionMode cannot be used with this version of python. Missing module datetime';
+SInvalidDateTimeConvMode = 'Invalid DatetimeConversionMode';
+SUnexpectedTypeInTimeObject = 'Unexpected type found in member %s of a time_struct object';
+SArguementTypeNotAllowed = 'Argument type not allowed';
+SCouldNotCreateTuple = 'Could not create a new tuple object';
+SCouldNotCreateList = 'Could not create a new list object';
+SCouldNotCreateDict = 'Could not create a new dict object';
+SArgumemntsShouldBeEven = 'You must provide an even number of arguments';
+SExpectedList = 'The python object is not a list';
+SExpectedTuple = 'The python object is not a tuple';
+SCouldNotSetVar = 'Could not set var "%s" in module "%s"';
+SCannotSetVarNoInit = 'Can''t set var "%s" in module "%s", because it is not yet initialized';
+SCannotGetDict = 'Can''t get __dict__ of module "%s"';
+SCannotDelVarNoInit = 'Can''t delete var "%s" in module "%s", because it is not yet initialized';
+SExpectedDelphiClass = 'Pytho;n object "%s" is not a Delphi class';
+SCannotCreateModule = 'CreateVar: can''t create module "%s"';
+SVarNotCreated = 'No variable was created';
+SVarExists = 'A variable "%s" already exists in the module "%s"';
+SCannotCreateThreadState = 'Could not create a new thread state';
+SCannotCreatePythonEngine = 'No Python engine was created';
+SCannotInitPythonEngine = 'The Python engine is not properly initialized';
+SThreadPythonExec = 'ThreadPythonExec should only be called from the main thread';
+SQuitMessage = 'Dll %s could not be loaded. We must quit.';
+SPythonQuitMessage = 'Python DLL %s could not be initialized. We must quit.';
+SErrCannotOpenDLL = 'Error %d: Could not open Dll "%s"';
+SPythonNoInit = 'Python is not initialized';
+SOnlyOnePythonEngine = 'You canott have more than one TPythonEngine component';
+SMoreThanOnePythonEngine = 'There is already one instance of TPythonEngine running';
+SGlobalVarsShouldBeDict = 'You must set a Python dictionary in the GlobalVars property';
+SLocalVarsShouldBeDict = 'You must set a Python dictionary in the LocalVars property';
+SCannotModifyFlags = 'You can''t modify Python flags after it has been initialized';
+SCannotFindType = 'Could not find type: %s';
+SCannotFindModule = 'Could not find module: %s';
+SCannotFindComponent = 'Could not find component: %s';
+SCannotHandleMoreThan3Dim = 'Can''t convert a variant array of more than 3 dimensions to a Python sequence';
+SNoEngineForComponent = 'No Engine defined for component "%s"';
+SIndexOutOfRange = '%s: Index %d out of range';
+SUnknownMemberType = 'Unknown member type';
+SUnknownMemberFlag = 'Unknown member flag';
+SDuplicateErrorName = 'In module "%s", there''s already an error named "%s"';
+SNoModuleWithParentClass = 'Could not find module containing the parent class of error "%s"';
+SCannotFindParentClass = 'Could not find the parent class "%s" of error "%s"';
+SObjectNotClass = 'The object "%s" in module "%s" is not a class';
+SErrorNotClass = 'Error without name in module "%s"';
+SCouldNotCreateError = 'Could not create error "%s"';
+STErrorCouldNotCreateInstance = 'TError.RaiseErrorObj: Could not create an instance of "%s"';
+STErrorCouldNotCreateTuple = 'TError.RaiseErrorObj: Could not create an empty tuple';
+STErrorNoInstance = 'TError.RaiseErrorObj: I didn''t get an instance';
+SCouldNotFindError = 'Could not find error "%s"';
+SCouldNotMapSymbol = 'Error %d: could not map symbol "%s"';
+SUndeterminedPythonVersion = 'Undetermined Python version';
(*******************************************************)
(** **)
@@ -3395,7 +3505,7 @@ procedure TDynamicDll.OpenDll(const aDllName : string);
if not IsHandleValid then begin
{$IFDEF MSWINDOWS}
- s := Format('Error %d: Could not open Dll "%s"',[GetLastError, DllName]);
+ s := Format(SErrCannotOpenDLL, [GetLastError, DllName]);
{$ELSE}
s := Format('Error: Could not open Dll "%s"',[DllName]);
{$ENDIF}
@@ -3443,7 +3553,7 @@ function TDynamicDll.Import(const funcname: AnsiString; canFail : Boolean = True
{$IFEND}
if (Result = nil) and canFail then begin
{$IFDEF MSWINDOWS}
- E := EDllImportError.CreateFmt('Error %d: could not map symbol "%s"', [GetLastError, funcname]);
+ E := EDllImportError.CreateFmt(SCouldNotMapSymbol, [GetLastError, funcname]);
E.ErrorCode := GetLastError;
{$ELSE}
E := EDllImportError.CreateFmt('Error: could not map symbol "%s"', [funcname]);
@@ -3538,7 +3648,7 @@ procedure TDynamicDll.LoadPythonInfoFromModule;
end;
if not LFound then
- raise EDLLLoadError.Create('Undetermined Python version from loaded module.');
+ raise EDLLLoadError.Create(SUndeterminedPythonVersion);
end;
procedure TDynamicDll.LoadDll;
@@ -3591,7 +3701,7 @@ procedure TDynamicDll.BeforeUnload;
function TDynamicDll.GetQuitMessage : string;
begin
- Result := Format( 'Dll %s could not be loaded. We must quit.', [DllName]);
+ Result := Format(SQuitMessage, [DllName]);
end;
function TDynamicDll.HasPythonSymbolsInLibrary: boolean;
@@ -3664,7 +3774,7 @@ procedure TPythonInterface.AfterLoad;
if not FInExtensionModule then
PythonVersionFromDLLName(DLLName, FMajorVersion, FMinorVersion)
else if not PythonVersionFromRegVersion(RegVersion, FMajorVersion, FMinorVersion) then
- raise EDLLLoadError.Create('Undetermined Python version.');
+ raise EDLLLoadError.Create(SUndeterminedPythonVersion);
FBuiltInModuleName := 'builtins';
@@ -3685,13 +3795,13 @@ procedure TPythonInterface.AfterLoad;
function TPythonInterface.GetQuitMessage : string;
begin
- Result := Format( 'Python could not be properly initialized. We must quit.', [DllName]);
+ Result := Format(SPythonQuitMessage, [DllName]);
end;
procedure TPythonInterface.CheckPython;
begin
if not Initialized then
- raise Exception.Create('Python is not properly initialized' );
+ raise Exception.Create(SPythonNoInit);
end;
procedure TPythonInterface.MapDll;
@@ -3778,6 +3888,7 @@ procedure TPythonInterface.MapDll;
PyStaticMethod_Type := Import('PyStaticMethod_Type');
PySuper_Type := Import('PySuper_Type');
PyTraceBack_Type := Import('PyTraceBack_Type');
+ PyGetSetDescr_Type := Import('PyGetSetDescr_Type');
PyWrapperDescr_Type := Import('PyWrapperDescr_Type');
_PyWeakref_RefType := Import('_PyWeakref_RefType');
_PyWeakref_ProxyType := Import('_PyWeakref_ProxyType');
@@ -3811,6 +3922,9 @@ procedure TPythonInterface.MapDll;
PyDict_SetItemString := Import('PyDict_SetItemString');
PyDictProxy_New := Import('PyDictProxy_New');
PyModule_Create2 := Import('PyModule_Create2');
+ PyModuleDef_Init := Import('PyModuleDef_Init');
+ PyModule_ExecDef := Import('PyModule_ExecDef');
+ PyModule_FromDefAndSpec2 := Import('PyModule_FromDefAndSpec2');
PyErr_Print := Import('PyErr_Print');
PyErr_SetNone := Import('PyErr_SetNone');
PyErr_SetObject := Import('PyErr_SetObject');
@@ -3895,6 +4009,7 @@ procedure TPythonInterface.MapDll;
PyLong_FromLongLong := Import('PyLong_FromLongLong');
PyLong_FromUnsignedLongLong := Import('PyLong_FromUnsignedLongLong');
PyLong_AsLongLong := Import('PyLong_AsLongLong');
+ PyLong_AsVoidPtr := Import('PyLong_AsVoidPtr');
PyLong_FromVoidPtr := Import('PyLong_FromVoidPtr');
PyMapping_Check := Import('PyMapping_Check');
PyMapping_GetItemString := Import('PyMapping_GetItemString');
@@ -4060,11 +4175,10 @@ procedure TPythonInterface.MapDll;
Py_GetPrefix := Import('Py_GetPrefix');
Py_GetProgramName := Import('Py_GetProgramName');
- PyErr_NewException := Import('PyErr_NewException');
- try
- PyMem_Malloc := Import ('PyMem_Malloc');
- except
- end;
+ PyErr_NewException := Import('PyErr_NewException');
+ PyMem_Malloc := Import ('PyMem_Malloc');
+ PyMem_Free := Import ('PyMem_Free');
+
Py_IsInitialized := Import('Py_IsInitialized');
Py_GetProgramFullPath := Import('Py_GetProgramFullPath');
Py_GetBuildInfo := Import('Py_GetBuildInfo');
@@ -4096,6 +4210,20 @@ procedure TPythonInterface.MapDll;
PyConfig_SetArgv := Import('PyConfig_SetArgv');
PyConfig_SetWideStringList := Import('PyConfig_SetWideStringList');
Py_InitializeFromConfig := Import('Py_InitializeFromConfig');
+
+ // PEP 741
+ if (MajorVersion > 3) or (MinorVersion >= 14) then
+ begin
+ PyInitConfig_Create := Import('PyInitConfig_Create');
+ PyInitConfig_Free := Import('PyInitConfig_Free');
+ Py_InitializeFromInitConfig := Import('Py_InitializeFromInitConfig');
+ PyInitConfig_SetInt := Import('PyInitConfig_SetInt');
+ PyInitConfig_SetStr := Import('PyInitConfig_SetStr');
+ PyInitConfig_SetStrList := Import('PyInitConfig_SetStrList');
+ PyInitConfig_GetError := Import('PyInitConfig_GetError');
+ PyConfig_Get := Import('PyConfig_Get');
+ PyConfig_Set := Import('PyConfig_Set');
+ end;
end;
function TPythonInterface.Py_CompileString(str,filename:PAnsiChar;start:integer):PPyObject;
@@ -4395,7 +4523,7 @@ procedure TPythonTraceback.Clear;
* This method is automatically called by the Exec/Eval methods of
* TPythonEngine. But if you use the Python core API, then don't
* forget to refresh the traceback yourself. Or much better,
- * simply use the method CheckError wich will call PyErr_Print,
+ * simply use the method CheckError which will call PyErr_Print,
* Traceback.Refresh and RaiseError for you.
}
procedure TPythonTraceback.Refresh(pytraceback: PPyObject);
@@ -4514,14 +4642,14 @@ constructor TPythonEngine.Create(AOwner: TComponent);
FAutoFinalize := True;
FTraceback := TPythonTraceback.Create;
FUseWindowsConsole := False;
- FPyFlags := [];
+ FPyFlags := DEFAULT_FLAGS;
FDatetimeConversionMode := DEFAULT_DATETIME_CONVERSION_MODE;
if csDesigning in ComponentState then
begin
for i := 0 to AOwner.ComponentCount - 1 do
if (AOwner.Components[i] is TPythonEngine) and
(AOwner.Components[i] <> Self) then
- raise Exception.Create('You can''t drop more than one TPythonEngine component');
+ raise Exception.Create(SOnlyOnePythonEngine);
end;
end;
@@ -4626,56 +4754,253 @@ procedure TPythonEngine.DoOpenDll(const aDllName : string);
end;
end;
-procedure TPythonEngine.AssignPyFlags(var Config: PyConfig);
-begin
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.parser_debug])^ :=
- IfThen(pfDebug in FPyFlags, 1, 0);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.verbose])^ :=
- IfThen(pfVerbose in FPyFlags, 1, 0);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.interactive])^ :=
- IfThen(pfInteractive in FPyFlags, 1, 0);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.optimization_level])^ :=
- IfThen(pfOptimize in FPyFlags, 1, 0);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.site_import])^ :=
- IfThen(pfNoSite in FPyFlags, 0, 1);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.pathconfig_warnings])^ :=
- IfThen(pfFrozenFlag in FPyFlags, 1, 0);
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.use_environment])^ :=
- IfThen(pfIgnoreEnvironmentFlag in FPyFlags, 0, 1);
-end;
-
procedure TPythonEngine.Initialize;
- procedure InitSysPath;
+ procedure ConfigPEP587(var ErrMsg: string);
+ // Initialize according to PEP587 available since python 3.8
+
+ procedure AssignPyFlags(var Config: PyConfig);
+ begin
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.parser_debug])^ :=
+ IfThen(pfDebug in FPyFlags, 1, 0);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.verbose])^ :=
+ IfThen(pfVerbose in FPyFlags, 1, 0);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.interactive])^ :=
+ IfThen(pfInteractive in FPyFlags, 1, 0);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.optimization_level])^ :=
+ IfThen(pfOptimize in FPyFlags, 1, 0);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.site_import])^ :=
+ IfThen(pfNoSite in FPyFlags, 0, 1);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.pathconfig_warnings])^ :=
+ IfThen(pfFrozen in FPyFlags, 1, 0);
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.use_environment])^ :=
+ IfThen(pfIgnoreEnvironment in FPyFlags, 0, 1);
+ end;
+
+ procedure SetProgramArgs(var Config: PyConfig);
+ var
+ I: Integer;
+ TempS: UnicodeString;
+ Str: WCharTString;
+
+ begin
+ // do not parse further
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.parse_argv])^ := 0;
+ for I := 0 to ParamCount do
+ begin
+ {
+ ... the first entry should refer to the script file to be executed rather
+ than the executable hosting the Python interpreter. If there isn’t a
+ script that will be run, the first entry in argv can be an empty string.
+ }
+ if I = 0 then
+ TempS := ''
+ else
+ TempS := ParamStr(I);
+ {$IFDEF POSIX}
+ Str := UnicodeStringToUCS4String(TempS);
+ {$ELSE}
+ Str := TempS;
+ {$ENDIF}
+ PyWideStringList_Append(
+ PPyWideStringList(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.argv]),
+ PWCharT(Str));
+ end;
+ end;
+
+ procedure SetPythonPath(var Config: PyConfig);
+ var
+ Paths: TStringDynArray;
+ I: Integer;
+ PWSL: PPyWideStringList;
+ begin
+ if FPythonPath = '' then Exit;
+
+ PWSL := PPyWideStringList(PByte(@Config) + ConfigOffests[MinorVersion,
+ TConfigFields.module_search_paths]);
+ Paths := SplitString(string(FPythonPath), PathSep);
+ for I := 0 to Length(Paths) - 1 do
+ begin
+ if (Paths[I] = '') and (I > 0) then
+ Continue;
+ PyWideStringList_Append(PWSL, PWCharT(StringToWCharTString(Paths[I])));
+ end;
+
+ if PWSL^.length > 0 then
+ PInteger(PByte(@Config) + ConfigOffests[MinorVersion,
+ TConfigFields.module_search_paths_set])^ := 1;
+ end;
+
var
- _path : PPyObject;
+ Config: PyConfig;
+ Status: PyStatus;
begin
- _path := PySys_GetObject('path');
- if Assigned(FOnSysPathInit) then
- FOnSysPathInit(Self, _path);
+ // Fills Config with zeros and then sets some default values
+ if pfIsolated in FPyFlags then
+ PyConfig_InitIsolatedConfig(Config)
+ else
+ PyConfig_InitPythonConfig(Config);
+ try
+ AssignPyFlags(Config);
+
+ // Set programname and pythonhome if available
+ if FProgramName <> '' then
+ PyConfig_SetString(Config,
+ PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.program_name]),
+ PWCharT(StringToWCharTString(FProgramName)));
+ if FPythonHome <> '' then
+ PyConfig_SetString(Config,
+ PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.home]),
+ PWCharT(StringToWCharTString(FPythonHome)));
+ // Set venv executable if available
+ if FPythonExecutable <> '' then
+ PyConfig_SetString(Config,
+ PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.executable]),
+ PWCharT(StringToWCharTString(FPythonExecutable)));
+
+ // Set program arguments (sys.argv)
+ SetProgramArgs(Config);
+
+ // PythonPath
+ SetPythonPath(Config);
+
+ // Fine tune Config
+ if Assigned(FOnConfigInit) then
+ FOnConfigInit(Self, @Config);
+
+ Status := Py_InitializeFromConfig(Config);
+ FInitialized := Py_IsInitialized() <> 0;
+
+ if PyStatus_Exception(Status) then
+ ErrMsg := Format(SPyInitFailed, [string(Status.err_msg)])
+ else if not FInitialized then
+ ErrMsg := Format(SPyInitFailed, [SPyInitFailedUnknown]);
+
+ finally
+ PyConfig_Clear(Config);
+ end;
end;
- procedure SetPythonPath(var Config: PyConfig);
+ procedure ConfigPEP741(var ErrMsg: string);
+ // Initialize according to PEP587 available since python 3.8
+
+ procedure AssignPyFlags(Config: PPyInitConfig);
+ begin
+ PyInitConfig_SetInt(Config, 'isolated', IfThen(pfIsolated in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'parser_debug', IfThen(pfDebug in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'verbose', IfThen(pfVerbose in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'interactive', IfThen(pfInteractive in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'optimization_level', IfThen(pfOptimize in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'site_import', IfThen(pfNoSite in FPyFlags, 0, 1));
+ PyInitConfig_SetInt(Config, 'pathconfig_warnings', IfThen(pfFrozen in FPyFlags, 1, 0));
+ PyInitConfig_SetInt(Config, 'use_environment', IfThen(pfIgnoreEnvironment in FPyFlags, 0, 1));
+ PyInitConfig_SetInt(Config, 'user_site_directory', IfThen(pfNoUserSiteDirectory in FPyFlags, 0, 1));
+ PyInitConfig_SetInt(Config, 'write_bytecode', IfThen(pfDontWriteBytecode in FPyFlags, 0, 1));
+ end;
+
+ procedure SetProgramArgs(Config: PPyInitConfig);
+ var
+ I: Integer;
+ Params: TArray;
+ PParams: TArray;
+ begin
+ // do not parse further
+ PyInitConfig_SetInt(Config, 'parse_argv', 0);
+
+ SetLength(Params, ParamCount + 1);
+ SetLength(PParams, ParamCount + 1);
+ for I := 0 to ParamCount do
+ begin
+ {
+ ... the first entry should refer to the script file to be executed rather
+ than the executable hosting the Python interpreter. If there isn’t a
+ script that will be run, the first entry in argv can be an empty string.
+ }
+ if I = 0 then
+ Params[I] := ''
+ else
+ Params[I] := EncodeString(ParamStr(I));
+ PParams[I] := PAnsiChar(Params[I])
+ end;
+ PyInitConfig_SetStrList(Config, 'argv', ParamCount + 1, @PParams[0]);
+ end;
+
+ procedure SetPythonPath(Config: PPyInitConfig);
+ var
+ Paths: TStringDynArray;
+ I: Integer;
+ Utf8Paths: TArray;
+ PUtf8Paths: TArray;
+ begin
+ if FPythonPath = '' then Exit;
+
+ Paths := SplitString(string(FPythonPath), PathSep);
+
+ if Length(Paths) = 0 then Exit;
+
+ SetLength(Utf8Paths, Length(Paths));
+ SetLength(PUtf8Paths, Length(Paths));
+
+ for I := 0 to Length(Paths) - 1 do
+ begin
+ Utf8Paths[I] := EncodeString(Paths[I]);
+ PUtf8Paths[I] := PAnsiChar(Utf8Paths[I]);
+ end;
+
+ // The following Also sets module_search_paths_set
+ PyInitConfig_SetStrList(Config, 'module_search_paths', Length(Paths), @PUtf8Paths[0]);
+ end;
+
var
- Paths: TStringDynArray;
- I: Integer;
- PWSL: PPyWideStringList;
+ Config: PPyInitConfig;
+ PErrMsg: PAnsiChar;
begin
- if FPythonPath = '' then Exit;
+ Config := PyInitConfig_Create;
+ try
+ AssignPyFlags(Config);
- PWSL := PPyWideStringList(PByte(@Config) + ConfigOffests[MinorVersion,
- TConfigFields.module_search_paths]);
- Paths := SplitString(string(FPythonPath), PathSep);
- for I := 0 to Length(Paths) - 1 do
- begin
- if (Paths[I] = '') and (I > 0) then
- Continue;
- PyWideStringList_Append(PWSL, PWCharT(StringToWCharTString(Paths[I])));
+ // Set programname and pythonhome if available
+ if FProgramName <> '' then
+ PyInitConfig_SetStr(Config, 'program_name', PAnsiChar(EncodeString(FProgramName)));
+ if FPythonHome <> '' then
+ PyInitConfig_SetStr(Config, 'home', PAnsiChar(EncodeString(FPythonHome)));
+ // Set venv executable if available
+ if FPythonExecutable <> '' then
+ PyInitConfig_SetStr(Config, 'executable', PAnsiChar(EncodeString(FPythonExecutable)));
+
+ // Set program arguments (sys.argv)
+ SetProgramArgs(Config);
+
+ // PythonPath
+ SetPythonPath(Config);
+
+ // Fine tune Config
+ if Assigned(FOnConfigInit) then
+ FOnConfigInit(Self, Config);
+
+ if Py_InitializeFromInitConfig(Config) <> 0 then
+ begin
+ FInitialized := False;
+ PyInitConfig_GetError(Config, @PErrMsg);
+ if PErrMsg <> nil then
+ ErrMsg := Format(SPyInitFailed, [UTF8ToString(AnsiString(PErrMsg))]);
+ end
+ else
+ FInitialized := Py_IsInitialized() <> 0;
+ if not FInitialized and (ErrMsg = '') then
+ ErrMsg := Format(SPyInitFailed, [SPyInitFailedUnknown]);
+ finally
+ PyInitConfig_Free(Config);
end;
+ end;
- if PWSL^.length > 0 then
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion,
- TConfigFields.module_search_paths_set])^ := 1;
+ procedure InitSysPath;
+ var
+ _path : PPyObject;
+ begin
+ _path := PySys_GetObject('path');
+ if Assigned(FOnSysPathInit) then
+ FOnSysPathInit(Self, _path);
end;
function GetVal(AModule : PPyObject; AVarName : AnsiString) : PPyObject;
@@ -4727,12 +5052,10 @@ procedure TPythonEngine.Initialize;
var
i : Integer;
- Config: PyConfig;
- Status: PyStatus;
ErrMsg: string;
begin
if Assigned(gPythonEngine) then
- raise Exception.Create('There is already one instance of TPythonEngine running' );
+ raise Exception.Create(SMoreThanOnePythonEngine);
gPythonEngine := Self;
@@ -4741,51 +5064,13 @@ procedure TPythonEngine.Initialize;
FInitialized := True
else
begin
- // Fills Config with zeros and then sets some default values
- if pfIsolated in FPyFlags then
- PyConfig_InitIsolatedConfig(Config)
+ if (MajorVersion > 3) or (MinorVersion >= 14) then
+ ConfigPEP741(ErrMsg)
else
- PyConfig_InitPythonConfig(Config);
- try
- AssignPyFlags(Config);
-
- // Set programname and pythonhome if available
- if FProgramName <> '' then
- PyConfig_SetString(Config,
- PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.program_name]),
- PWCharT(StringToWCharTString(FProgramName)));
- if FPythonHome <> '' then
- PyConfig_SetString(Config,
- PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.home]),
- PWCharT(StringToWCharTString(FPythonHome)));
- // Set venv executable if available
- if FVenvPythonExe <> '' then
- PyConfig_SetString(Config,
- PPWcharT(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.executable]),
- PWCharT(StringToWCharTString(FVenvPythonExe)));
-
- // Set program arguments (sys.argv)
- SetProgramArgs(Config);
-
- // PythonPath
- SetPythonPath(Config);
-
- // Fine tune Config
- if Assigned(FOnConfigInit) then
- FOnConfigInit(Self, Config);
-
- Status := Py_InitializeFromConfig(Config);
- FInitialized := Py_IsInitialized() <> 0
- finally
- PyConfig_Clear(Config);
- end;
+ ConfigPEP587(ErrMsg);
if not FInitialized then
begin
- if PyStatus_Exception(Status) then
- ErrMsg := Format(SPyInitFailed, [string(Status.err_msg)])
- else
- ErrMsg := Format(SPyInitFailed, [SPyInitFailedUnknown]);
if FatalMsgDlg then
{$IFDEF MSWINDOWS}
MessageBox( GetActiveWindow, PChar(ErrMsg), 'Error', MB_TASKMODAL or MB_ICONSTOP );
@@ -4811,6 +5096,19 @@ procedure TPythonEngine.Initialize;
if not Initialized then
Initialize;
+ {$IFDEF MSWINDOWS}
+ // fix #504
+ if not FRedirectIO and UseWindowsConsole then
+ PyRun_SimpleString(
+ 'import sys, io'#10 +
+ 'sys.stdout = io.TextIOWrapper(open("CONOUT$", "wb", buffering=0), ' +
+ 'encoding="utf-8", errors="replace", line_buffering=True)'#10 +
+ 'sys.stderr = io.TextIOWrapper(open("CONOUT$", "wb", buffering=0), ' +
+ 'encoding="utf-8", errors="replace", line_buffering=False)'#10 +
+ 'sys.stdin = io.TextIOWrapper(open("CONIN$", "rb", buffering=0), ' +
+ 'encoding="utf-8", errors="replace", line_buffering=True)'#10);
+ {$ENDIF}
+
if InitScript.Count > 0 then
ExecStrings(InitScript);
if Assigned(FOnAfterInit) then
@@ -4860,47 +5158,18 @@ procedure TPythonEngine.Notification( AComponent: TComponent;
IO := nil
end;
-procedure TPythonEngine.SetProgramArgs(var Config: PyConfig);
-var
- I: Integer;
- TempS: UnicodeString;
- Str: WCharTString;
-
-begin
- // do not parse further
- PInteger(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.parse_argv])^ := 0;
- for I := 0 to ParamCount do
- begin
- {
- ... the first entry should refer to the script file to be executed rather
- than the executable hosting the Python interpreter. If there isn’t a
- script that will be run, the first entry in argv can be an empty string.
- }
- if I = 0 then
- TempS := ''
- else
- TempS := ParamStr(I);
- {$IFDEF POSIX}
- Str := UnicodeStringToUCS4String(TempS);
- {$ELSE}
- Str := TempS;
- {$ENDIF}
- PyWideStringList_Append(
- PPyWideStringList(PByte(@Config) + ConfigOffests[MinorVersion, TConfigFields.argv]),
- PWCharT(Str));
- end;
-end;
-
procedure TPythonEngine.InitWinConsole;
begin
{$IFDEF MSWINDOWS}
FreeConsole;
AllocConsole;
SetConsoleTitle( 'Python console' );
+ SetConsoleOutputCP(CP_UTF8);
+ SetConsoleCP(CP_UTF8);
{$ENDIF}
end;
-procedure TPythonEngine.SetUseWindowsConsole( const Value : Boolean );
+procedure TPythonEngine.SetUseWindowsConsole(const Value: Boolean);
begin
FUseWindowsConsole := Value;
if (csDesigning in ComponentState) then
@@ -4918,7 +5187,7 @@ procedure TPythonEngine.SetGlobalVars(const Value: PPyObject);
else
begin
FGlobalVars := nil;
- raise Exception.Create('You must set a Python dictionary in the GlobalVars property');
+ raise Exception.Create(SGlobalVarsShouldBeDict);
end
else
FGlobalVars := nil;
@@ -4936,7 +5205,7 @@ procedure TPythonEngine.SetLocalVars(const Value: PPyObject);
else
begin
FLocalVars := nil;
- raise Exception.Create('You must set a Python dictionary in the LocalVars property');
+ raise Exception.Create(SLocalVarsShouldBeDict);
end
else
FLocalVars := nil;
@@ -4948,7 +5217,7 @@ procedure TPythonEngine.SetPyFlags(const Value: TPythonFlags);
if FPyFlags <> Value then
begin
if Initialized then
- raise Exception.Create('You can''t modify Python flags after it has been initialized');
+ raise Exception.Create(SCannotModifyFlags);
FPyFlags := Value;
end; // of if
end;
@@ -5089,7 +5358,7 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command: AnsiString;
m := GetMainModule;
if m = nil then
- raise EPythonError.Create('Run_CommandAsObject: can''t create __main__');
+ raise EPythonError.Create(SCannotCreateMain);
if Assigned(locals) then
_locals := locals
@@ -5340,9 +5609,7 @@ procedure TPythonEngine.RaiseError;
s_type := GetTypeAsString(err_type);
s_value := PyObjectAsString(err_value);
- if (PyErr_GivenExceptionMatches(err_type, PyExc_SystemExit^) <> 0) then
- raise Define( EPySystemExit.Create(''), s_type, s_value )
- else if (PyErr_GivenExceptionMatches(err_type, PyExc_StopIteration^) <> 0) then
+ if (PyErr_GivenExceptionMatches(err_type, PyExc_StopIteration^) <> 0) then
raise Define( EPyStopIteration.Create(''), s_type, s_value )
else if (PyErr_GivenExceptionMatches(err_type, PyExc_KeyboardInterrupt^) <> 0) then
raise Define( EPyKeyboardInterrupt.Create(''), s_type, s_value )
@@ -5433,7 +5700,7 @@ procedure TPythonEngine.RaiseError;
raise Define( EPyExecError.Create(''), s_type, s_value );
end
else
- raise EPythonError.Create('RaiseError: couldn''t fetch last exception');
+ raise EPythonError.Create(SRaiseError);
end;
function TPythonEngine.PyObjectAsString( obj : PPyObject ) : string;
@@ -5567,7 +5834,7 @@ function TPythonEngine.TypeByName( const aTypeName : AnsiString ) : PPyTypeObjec
Result := TheTypePtr;
Exit;
end;
- raise Exception.CreateFmt('Could not find type: %s', [aTypeName]);
+ raise Exception.CreateFmt(SCannotFindType, [aTypeName]);
end;
function TPythonEngine.ModuleByName( const aModuleName : AnsiString ) : PPyObject;
@@ -5582,7 +5849,7 @@ function TPythonEngine.ModuleByName( const aModuleName : AnsiString ) : PPyObj
Result := Module;
Exit;
end;
- raise Exception.CreateFmt('Could not find module: %s', [aModuleName]);
+ raise Exception.CreateFmt(SCannotFindModule, [aModuleName]);
end;
function TPythonEngine.MethodsByName( const aMethodsContainer: string ) : PPyMethodDef;
@@ -5597,7 +5864,7 @@ function TPythonEngine.MethodsByName( const aMethodsContainer: string ) : PPyMet
Result := MethodsData;
Exit;
end;
- raise Exception.CreateFmt('Could not find component: %s', [aMethodsContainer]);
+ raise Exception.CreateFmt(SCannotFindComponent, [aMethodsContainer]);
end;
function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
@@ -5717,7 +5984,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
else if (DatetimeConversionMode = dcmToDatetime) then
begin
if not Assigned(FPyDateTime_DateTimeType) then
- raise EPythonError.Create('dcmToDatetime DatetimeConversionMode cannot be used with this version of python. Missing module datetime');
+ raise EPythonError.Create(SMissingModuleDateTime);
args := ArrayToPyTuple([y, m, d, h, mi, sec, ms*1000]);
try
Result := PyObject_Call(FPyDateTime_DateTimeType, args, nil);
@@ -5727,7 +5994,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
end;
end
else
- raise EPythonError.Create('Invalid DatetimeConversionMode');
+ raise EPythonError.Create(SInvalidDateTimeConvMode);
end;
varOleStr:
begin
@@ -5755,7 +6022,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
2: Result := ArrayVarDim2;
3: Result := ArrayVarDim3;
else
- raise Exception.Create('Can''t convert a variant array of more than 3 dimensions to a Python sequence');
+ raise Exception.Create(SCannotHandleMoreThan3Dim);
end;
end
else if VarIsNull(DeRefV) or VarIsEmpty(DeRefV) then
@@ -5781,7 +6048,7 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant;
if PyLong_Check(member) then
Result := PyLong_AsLong(member)
else
- raise EPythonError.CreateFmt('Unexpected type found in member %s of a time_struct object', [AMember]);
+ raise EPythonError.CreateFmt(SUnexpectedTypeInTimeObject, [AMember]);
Py_XDecRef(member);
end;
@@ -5971,7 +6238,7 @@ function TPythonEngine.VarRecAsPyObject( const v : TVarRec ) : PPyObject;
Result := PyUnicodeFromString('');
end;
else
- Raise Exception.Create('Argument type not allowed');
+ Raise Exception.Create(SArguementTypeNotAllowed);
end;
end;
@@ -5984,7 +6251,7 @@ function TPythonEngine.MakePyTuple( const objects : array of PPyObject ) : PPyOb
begin
Result := PyTuple_New( High(objects)+1 );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new tuple object');
+ raise EPythonError.Create(SCouldNotCreateTuple);
for i := Low(objects) to High(objects) do
begin
Py_XINCREF( objects[i] );
@@ -6001,7 +6268,7 @@ function TPythonEngine.MakePyList( const objects : array of PPyObject ) : PPyObj
begin
Result := PyList_New( High(objects)+1 );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new list object');
+ raise EPythonError.Create(SCouldNotCreateList);
for i := Low(objects) to High(objects) do
begin
Py_XIncRef( objects[i] );
@@ -6015,7 +6282,7 @@ function TPythonEngine.ArrayToPyTuple( const items : array of const) : PPyObject
begin
Result := PyTuple_New( High(items)+1 );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new tuple object');
+ raise EPythonError.Create(SCouldNotCreateTuple);
for i := Low(items) to High(items) do
PyTuple_SetItem( Result, i, VarRecAsPyObject( items[i] ) );
end;
@@ -6026,7 +6293,7 @@ function TPythonEngine.ArrayToPyList( const items : array of const) : PPyObject;
begin
Result := PyList_New( High(items)+1 );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new list object');
+ raise EPythonError.Create(SCouldNotCreateList);
for i := Low(items) to High(items) do
PyList_SetItem( Result, i, VarRecAsPyObject( items[i] ) );
end;
@@ -6082,7 +6349,7 @@ function TPythonEngine.ArrayToPyDict( const items : array of const) : PPyObject;
Result := '';
end;
else
- Raise Exception.Create('Argument type not allowed');
+ Raise Exception.Create(SArguementTypeNotAllowed);
end;
end;
@@ -6092,10 +6359,10 @@ function TPythonEngine.ArrayToPyDict( const items : array of const) : PPyObject;
obj : PPyObject;
begin
if ((High(items)+1) mod 2) <> 0 then
- raise Exception.Create('You must provide an even number of arguments');
+ raise Exception.Create(SArgumemntsShouldBeEven);
Result := PyDict_New;
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new dict object');
+ raise EPythonError.Create(SCouldNotCreateDict);
i := Low(items);
try
while i <= High(items) do
@@ -6120,7 +6387,7 @@ function TPythonEngine.StringsToPyList( strings : TStrings ) : PPyObject;
begin
Result := PyList_New( strings.Count );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new list object');
+ raise EPythonError.Create(SCouldNotCreateList);
for i := 0 to strings.Count - 1 do
PyList_SetItem( Result, i,
PyUnicodeFromString(strings.Strings[i]));
@@ -6132,7 +6399,7 @@ function TPythonEngine.StringsToPyTuple( strings : TStrings ) : PPyObject;
begin
Result := PyTuple_New( strings.Count );
if not Assigned(Result) then
- raise EPythonError.Create('Could not create a new tuple object');
+ raise EPythonError.Create(SCouldNotCreateTuple);
for i := 0 to strings.Count - 1 do
PyTuple_SetItem( Result, i,
PyUnicodeFromString(strings.Strings[i]));
@@ -6144,7 +6411,7 @@ procedure TPythonEngine.PyListToStrings(list: PPyObject; Strings: TStrings;
i : Integer;
begin
if not PyList_Check(list) then
- raise EPythonError.Create('the python object is not a list');
+ raise EPythonError.Create(SExpectedList);
if ClearStrings then
Strings.Clear;
for i := 0 to PyList_Size( list ) - 1 do
@@ -6156,7 +6423,7 @@ procedure TPythonEngine.PyTupleToStrings( tuple: PPyObject; strings : TStrings )
i : Integer;
begin
if not PyTuple_Check(tuple) then
- raise EPythonError.Create('the python object is not a tuple');
+ raise EPythonError.Create(SExpectedTuple);
strings.Clear;
for i := 0 to PyTuple_Size( tuple ) - 1 do
strings.Add( PyObjectAsString( PyTuple_GetItem( tuple, i ) ) );
@@ -6376,6 +6643,7 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
var
errtype, errvalue, errtraceback: PPyObject;
SErrValue: string;
+ SystemExit: EPySystemExit;
begin
// PyErr_Fetch clears the error. The returned python objects are new references
PyErr_Fetch(errtype, errvalue, errtraceback);
@@ -6384,7 +6652,11 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
Py_XDECREF(errtype);
Py_XDECREF(errvalue);
Py_XDECREF(errtraceback);
- raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]);
+
+ SystemExit := EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]);
+ SystemExit.EValue := SErrValue;
+ SystemExit.EName := 'SystemExit';
+ raise SystemExit;
end;
var
@@ -6558,7 +6830,7 @@ procedure TEngineClient.ClearEngine;
procedure TEngineClient.CheckEngine;
begin
if not Assigned(FEngine) then
- raise Exception.CreateFmt('No Engine defined for component "%s"', [Name]);
+ raise Exception.CreateFmt(SNoEngineForComponent, [Name]);
end;
@@ -6704,7 +6976,7 @@ procedure TMethodsContainer.ReallocMethods;
function TMethodsContainer.GetMethods( idx : Integer ) : PPyMethodDef;
begin
if (idx < 0) or (idx > MethodCount) then
- raise Exception.CreateFmt('%s: Index %d out of range', [ClassName, idx]);
+ raise Exception.CreateFmt(SIndexOutOfRange, [ClassName, idx]);
Result := @( FMethods[idx] );
end;
@@ -6837,7 +7109,7 @@ procedure TMembersContainer.AddMember(MemberName: PAnsiChar; MemberType : TPyMe
mtStringInplace: _type := T_STRING_INPLACE;
mtObjectEx: _type := T_OBJECT_EX;
else
- raise Exception.Create('Unknown member type');
+ raise Exception.Create(SUnknownMemberType);
end;
offset := MemberOffset + GetMembersStartOffset;
case MemberFlags of
@@ -6847,9 +7119,9 @@ procedure TMembersContainer.AddMember(MemberName: PAnsiChar; MemberType : TPyMe
mfWriteRestricted: flags := PY_WRITE_RESTRICTED;
mfRestricted: flags := RESTRICTED;
else
- raise Exception.Create('Unknown member flag');
+ raise Exception.Create(SUnknownMemberFlag);
end;
- doc := MemberDoc;
+ doc := MemberDoc;
end;
Inc( FMemberCount );
end;
@@ -6900,7 +7172,7 @@ procedure TMembersContainer.FreeMembers;
function TMembersContainer.GetMembers(idx: Integer): PPyMemberDef;
begin
if (idx < 0) or (idx > MemberCount) then
- raise Exception.CreateFmt('%s: Index %d out of range', [ClassName, idx]);
+ raise Exception.CreateFmt(SIndexOutOfRange, [ClassName, idx]);
Result := @( FMembers[idx] );
end;
@@ -6977,7 +7249,7 @@ procedure TGetSetContainer.FreeGetSets;
function TGetSetContainer.GetGetSet(idx: Integer): PPyGetSetDef;
begin
if (idx < 0) or (idx > GetSetCount) then
- raise Exception.CreateFmt('%s: Index %d out of range', [ClassName, idx]);
+ raise Exception.CreateFmt(SIndexOutOfRange, [ClassName, idx]);
Result := @( FGetSets[idx] );
end;
@@ -7014,7 +7286,8 @@ procedure TParentClassError.AssignTo( Dest: TPersistent );
function TError.GetDisplayName: string;
begin
Result := string(Name);
- if Result = '' then Result := inherited GetDisplayName;
+ if Result = '' then
+ Result := inherited GetDisplayName;
end;
procedure TError.SetName( const Value : AnsiString );
@@ -7032,8 +7305,8 @@ procedure TError.SetName( const Value : AnsiString );
for i := 0 to Count - 1 do
with Items[i] do
if Name = Value then
- raise Exception.CreateFmt( 'In module "%s", there''s already an error named "%s"',
- [m.ModuleName, Value]);
+ raise Exception.CreateFmt(SDuplicateErrorName,
+ [m.ModuleName, Value]);
end;
end;
@@ -7143,13 +7416,13 @@ procedure TError.BuildError( const ModuleName : AnsiString );
else
m := FindModule( ModuleName );
if not Assigned(m) then
- raise Exception.CreateFmt('Could not find module containing the parent class of error "%s"', [Self.Name]);
+ raise Exception.CreateFmt(SNoModuleWithParentClass, [Self.Name]);
d := PyModule_GetDict(m);
Result := PyDict_GetItemString( d, PAnsiChar(ParentClass.Name) );
if not Assigned(Result) then
- raise Exception.CreateFmt('Could not find the parent class "%s" of error "%s"', [ParentClass.Name, Self.Name]);
+ raise Exception.CreateFmt(SCannotFindParentClass, [ParentClass.Name, Self.Name]);
if not PyClass_Check( Result ) and not PyType_CheckExact( Result ) then
- raise Exception.CreateFmt('The object "%s" in module "%s" is not a class', [ParentClass.Name, ParentClass.Module] );
+ raise Exception.CreateFmt(SObjectNotClass, [ParentClass.Name, ParentClass.Module] );
end;
end;
@@ -7160,7 +7433,7 @@ procedure TError.BuildError( const ModuleName : AnsiString );
Exit;
if Name = '' then
with GetOwner as TPythonModule do
- raise Exception.CreateFmt( 'Error without name in module "%s"', [ModuleName] );
+ raise Exception.CreateFmt(SErrorNotClass, [ModuleName] );
if Text = '' then
Text := Name;
Owner.Owner.CheckEngine;
@@ -7180,7 +7453,7 @@ procedure TError.BuildError( const ModuleName : AnsiString );
end;
end;
if not Assigned(Error) then
- raise Exception.CreateFmt( 'Could not create error "%s"', [Name] );
+ raise Exception.CreateFmt(SCouldNotCreateError, [Name]);
end;
procedure TError.RaiseError(const msg : AnsiString);
@@ -7206,18 +7479,18 @@ procedure TError.RaiseErrorObj(const msg : AnsiString; obj : PPyObject);
begin
res := PyObject_CallObject(Error, nil);
if not Assigned(res) then
- raise Exception.CreateFmt('TError.RaiseErrorObj: Could not create an instance of "%s"', [Self.Name]);
+ raise Exception.CreateFmt(STErrorCouldNotCreateInstance, [Self.Name]);
if PyObject_TypeCheck(res, PPyTypeObject(PyExc_Exception^)) then
begin
args := PyTuple_New(1);
if not Assigned(args) then
- raise Exception.Create('TError.RaiseErrorObj: Could not create an empty tuple');
+ raise Exception.Create(STErrorCouldNotCreateTuple);
str := PyUnicodeFromString(msg);
PyTuple_SetItem(args, 0, str);
res := PyObject_Call(Error, args, nil);
Py_DECREF(args);
if not Assigned(res) then
- raise Exception.CreateFmt('TError.RaiseErrorObj: Could not create an instance of "%s"', [Self.Name]);
+ raise Exception.CreateFmt(STErrorCouldNotCreateInstance, [Self.Name]);
keys := PyDict_Keys(obj);
for i := 0 to PySequence_Length(keys)-1 do
begin
@@ -7233,7 +7506,7 @@ procedure TError.RaiseErrorObj(const msg : AnsiString; obj : PPyObject);
Py_XDECREF(keys);
end
else
- raise Exception.Create('TError.RaiseErrorObj: I didn''t get an instance' );
+ raise Exception.Create(STErrorNoInstance);
PyErr_SetObject(Error, res);
Py_XDECREF(res);
end
@@ -7433,7 +7706,7 @@ function TPythonModule.ErrorByName( const AName : AnsiString ) : TError;
Result := Errors.Items[i];
Exit;
end;
- raise Exception.CreateFmt( 'Could not find error "%s"', [AName] );
+ raise Exception.CreateFmt(SCouldNotFindError, [AName] );
end;
procedure TPythonModule.RaiseError( const error, msg : AnsiString );
@@ -7485,10 +7758,10 @@ procedure TPythonModule.SetVar( const varName : AnsiString; value : PPyObject );
if Assigned(FEngine) and Assigned( FModule ) then
begin
if Engine.PyObject_SetAttrString(Module, PAnsiChar(varName), value ) <> 0 then
- raise EPythonError.CreateFmt( 'Could not set var "%s" in module "%s"', [varName, ModuleName] );
+ raise EPythonError.CreateFmt(SCouldNotSetVar, [varName, ModuleName]);
end
else
- raise EPythonError.CreateFmt( 'Can''t set var "%s" in module "%s", because it is not yet initialized', [varName, ModuleName] );
+ raise EPythonError.CreateFmt(SCannotSetVarNoInit, [varName, ModuleName]);
end;
// warning, this function will increase the refcount of value,
@@ -7502,7 +7775,7 @@ function TPythonModule.GetVar( const varName : AnsiString ) : PPyObject;
Engine.PyErr_Clear;
end
else
- raise EPythonError.CreateFmt( 'Can''t get var "%s" in module "%s", because it is not yet initialized', [varName, ModuleName] );
+ raise EPythonError.CreateFmt(SCannotSetVarNoInit, [varName, ModuleName]);
end;
procedure TPythonModule.DeleteVar( const varName : AnsiString );
@@ -7513,11 +7786,12 @@ procedure TPythonModule.DeleteVar( const varName : AnsiString );
with Engine do
begin
dict := PyModule_GetDict( Module );
- if not Assigned(dict) then raise EPythonError.CreateFmt( 'Can''t get __dict__ of module "%s"', [ModuleName] );
+ if not Assigned(dict) then
+ raise EPythonError.CreateFmt(SCannotGetDict, [ModuleName] );
PyDict_DelItemString( dict, PAnsiChar(varName) );
end
else
- raise EPythonError.CreateFmt( 'Can''t delete var "%s" in module "%s", because it is not yet initialized', [varName, ModuleName] );
+ raise EPythonError.CreateFmt(SCannotDelVarNoInit, [varName, ModuleName]);
end;
procedure TPythonModule.ClearVars;
@@ -7649,7 +7923,7 @@ function TPyObject.GetModule : TPythonModule;
Result := nil;
end;
-function TPyObject.Get_ob_refcnt: NativeInt;
+function TPyObject.Get_ob_refcnt: NativeUInt;
begin
Result := GetSelf^.ob_refcnt;
end;
@@ -7659,7 +7933,7 @@ function TPyObject.Get_ob_type: PPyTypeObject;
Result := GetSelf^.ob_type;
end;
-procedure TPyObject.Set_ob_refcnt(const Value: NativeInt);
+procedure TPyObject.Set_ob_refcnt(const Value: NativeUInt);
begin
GetSelf^.ob_refcnt := Value;
end;
@@ -8085,7 +8359,7 @@ function PythonToDelphi( obj : PPyObject ) : TPyObject;
if IsDelphiObject( obj ) then
Result := TPyObject(PAnsiChar(obj)+Sizeof(PyObject))
else
- raise EPythonError.CreateFmt( 'Python object "%s" is not a Delphi class', [GetPythonEngine.PyObjectAsString(obj)] );
+ raise EPythonError.CreateFmt(SExpectedDelphiClass, [GetPythonEngine.PyObjectAsString(obj)]);
end;
procedure PyObjectDestructor( pSelf : PPyObject); cdecl;
@@ -8936,7 +9210,7 @@ procedure TPythonDelphiVar.CreateVar;
// Add a reference to this var in the module
m := PyImport_AddModule(PAnsiChar(Module));
if m = nil then
- raise EPythonError.CreateFmt('CreateVar: can''t create module "%s"', [Module]);
+ raise EPythonError.CreateFmt(SCannotCreateModule, [Module]);
d := PyModule_GetDict(m);
if @PyDict_SetItemString = nil then
raise Exception.Create('nil');
@@ -8950,7 +9224,7 @@ function TPythonDelphiVar.GetValue : Variant;
with TPyVar(PythonToDelphi(FVarObject)) do
Result := GetValueAsVariant
else
- raise Exception.Create('No variable was created' );
+ raise Exception.Create(SVarNotCreated);
end;
procedure TPythonDelphiVar.SetValue( const val : Variant );
@@ -8959,7 +9233,7 @@ procedure TPythonDelphiVar.SetValue( const val : Variant );
with TPyVar(PythonToDelphi(FVarObject)) do
SetValueFromVariant(val)
else
- raise Exception.Create('No variable was created' );
+ raise Exception.Create(SVarNotCreated);
end;
// Warning: GetValueAsPyObject returns a preincremented object !
@@ -8969,7 +9243,7 @@ function TPythonDelphiVar.GetValueAsPyObject : PPyObject;
with TPyVar(PythonToDelphi(FVarObject)) do
Result := GetValue
else
- raise Exception.Create('No variable was created' );
+ raise Exception.Create(SVarNotCreated);
end;
procedure TPythonDelphiVar.SetValueFromPyObject( val : PPyObject );
@@ -8978,7 +9252,7 @@ procedure TPythonDelphiVar.SetValueFromPyObject( val : PPyObject );
with TPyVar(PythonToDelphi(FVarObject)) do
SetValue(val)
else
- raise Exception.Create('No variable was created' );
+ raise Exception.Create(SVarNotCreated);
end;
function TPythonDelphiVar.IsVariantOk( const v : Variant ) : Boolean;
@@ -9031,7 +9305,7 @@ procedure TPythonDelphiVar.SetVarName( const val : AnsiString );
if Owner.Components[i] is TPythonDelphiVar then
with TPythonDelphiVar(Owner.Components[i]) do
if (VarName = val) and (Module = Self.Module) then
- raise Exception.CreateFmt('A variable "%s" already exists in the module "%s"',[val, Module]);
+ raise Exception.CreateFmt(SVarExists, [val, Module]);
end;
begin
@@ -9323,7 +9597,7 @@ procedure TPythonThread.Execute;
PyThreadState_Swap(global_state);
PyGILState_Release(gilstate);
end else
- raise EPythonError.Create('Could not create a new thread state');
+ raise EPythonError.Create(SCannotCreateThreadState);
end;
end;
end;
@@ -9531,9 +9805,9 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject;
function GetPythonEngine : TPythonEngine;
begin
if not Assigned( gPythonEngine ) then
- raise Exception.Create( 'No Python engine was created' );
+ raise Exception.Create(SCannotCreatePythonEngine);
if not gPythonEngine.Finalizing and not gPythonEngine.Initialized then
- raise Exception.Create( 'The Python engine is not properly initialized' );
+ raise Exception.Create(SCannotInitPythonEngine);
Result := gPythonEngine;
end;
@@ -9886,7 +10160,7 @@ procedure ThreadPythonExec(ExecuteProc : TProc; TerminateProc : TProc;
Thread: TAnonymousPythonThread;
begin
if GetCurrentThreadId <> MainThreadID then
- raise Exception.Create('ThreadPythonExec should only be called from the main thread');
+ raise Exception.Create(SThreadPythonExec);
Thread := TAnonymousPythonThread.Create(ExecuteProc, TerminateProc, WaitToFinish, ThreadExecMode);
if WaitToFinish then
begin
diff --git a/Source/PythonVersions.pas b/Source/PythonVersions.pas
index 569ba52f..ea79ed84 100644
--- a/Source/PythonVersions.pas
+++ b/Source/PythonVersions.pas
@@ -33,7 +33,7 @@ TPythonVersion = record
function GetDisplayName: string;
function GetApiVersion: integer;
function GetSysArchitecture: string;
- function GetPythonExecutable: string;
+ function GetPythonExecutable(Index: Integer): string;
public
IsRegistered: Boolean;
IsAllUsers: Boolean;
@@ -46,7 +46,8 @@ TPythonVersion = record
function Is_virtualenv: Boolean;
function Is_conda: Boolean;
procedure AssignTo(PythonEngine: TPersistent);
- property PythonExecutable: string read GetPythonExecutable;
+ property PythonExecutable: string index 0 read GetPythonExecutable;
+ property PythonFreeThreadedExecutable: string index 1 read GetPythonExecutable;
property DLLName: string read GetDLLName;
property SysArchitecture: string read GetSysArchitecture;
property IsPython3K: Boolean read GetIsPython3K;
@@ -127,7 +128,7 @@ procedure TPythonVersion.AssignTo(PythonEngine: TPersistent);
TPythonEngine(PythonEngine).DllPath := DLLPath;
TPythonEngine(PythonEngine).APIVersion := ApiVersion;
if Is_venv then begin
- TPythonEngine(PythonEngine).VenvPythonExe := PythonExecutable;
+ TPythonEngine(PythonEngine).PythonExecutable := PythonExecutable;
TPythonEngine(PythonEngine).SetPythonHome(DLLPath);
end else
{
@@ -204,11 +205,18 @@ function TPythonVersion.GetIsPython3K: Boolean;
end;
end;
-function TPythonVersion.GetPythonExecutable: string;
+function TPythonVersion.GetPythonExecutable(Index: Integer): string;
+var
+ ExeName: string;
begin
- Result := IncludeTrailingPathDelimiter(InstallPath) + 'python.exe';
+ if Index = 0 then
+ ExeName := 'python.exe'
+ else
+ ExeName := Format('python%st.exe', [SysVersion]);
+
+ Result := IncludeTrailingPathDelimiter(InstallPath) + ExeName;
if not FileExists(Result) then begin
- Result := IncludeTrailingPathDelimiter(InstallPath) + 'Scripts' + PathDelim + 'python.exe';
+ Result := IncludeTrailingPathDelimiter(InstallPath) + 'Scripts' + PathDelim + ExeName;
if not FileExists(Result) then Result := '';
end;
end;
diff --git a/Source/VarPyth.pas b/Source/VarPyth.pas
index b16f91b8..52607cf0 100644
--- a/Source/VarPyth.pas
+++ b/Source/VarPyth.pas
@@ -2154,7 +2154,7 @@ procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings);
V: Variant;
begin
for V in VarPyIterate(AValue) do
- AStrings.Add(V)
+ AStrings.Add(VarPythonAsString(V))
end;
initialization
diff --git a/Source/WrapDelphi.pas b/Source/WrapDelphi.pas
index bed385ea..a19bc718 100644
--- a/Source/WrapDelphi.pas
+++ b/Source/WrapDelphi.pas
@@ -1042,7 +1042,7 @@ implementation
rs_ExpectedNil = 'In static methods Self should be nil';
rs_ExpectedInterface = 'Expected a Pascal interface';
rs_ExpectedSequence = 'Expected a python sequence';
- rsExpectedPPyObject = 'Expected a PPyObject';
+ rsExpectedPointer = 'Expected a Pointer';
rs_InvalidClass = 'Invalid class';
rs_ErrEventNotReg = 'No Registered EventHandler for events of type "%s';
rs_ErrEventNoSuport = 'Class %s does not support events because it must '+
@@ -2188,12 +2188,16 @@ function ValidateDynArray(PyValue: PPyObject; const RttiType: TRttiType;
end;
end;
-function ValidatePPyObject(PyValue: PPyObject; const RttiType: TRttiType;
+function ValidatePointer(PyValue: PPyObject; const RttiType: TRttiType;
out ParamValue: TValue; out ErrMsg: string): Boolean;
var
RefType: TRttiType;
+ PyEngine: TPythonEngine;
+ P: Pointer;
begin
Result := False;
+ PyEngine := GetPythonEngine;
+
if (RTTIType is TRttiPointerType) then
begin
RefType := TRttiPointerType(RTTIType).ReferredType;
@@ -2201,10 +2205,21 @@ function ValidatePPyObject(PyValue: PPyObject; const RttiType: TRttiType;
begin
Result := True;
ParamValue := TValue.From(PyValue);
+ end
+ else if PyEngine.PyLong_Check(PyValue) then
+ begin
+ P := PyEngine.PyLong_AsVoidPtr(PyValue);
+ if PyEngine.PyErr_Occurred = nil then
+ begin
+ Result := True;
+ ParamValue := TValue.From(P);
+ end
+ else
+ PyEngine.PyErr_Clear;
end;
end;
if not Result then
- ErrMsg := rsExpectedPPyObject;
+ ErrMsg := rsExpectedPointer;
end;
function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType;
@@ -2238,7 +2253,7 @@ function PyObjectToTValue(PyArg: PPyObject; ArgType: TRttiType;
tkDynArray:
Result := ValidateDynArray(PyArg, ArgType, Arg, ErrMsg);
tkPointer:
- Result := ValidatePPyObject(PyArg, ArgType, Arg, ErrMsg);
+ Result := ValidatePointer(PyArg, ArgType, Arg, ErrMsg);
else
Result := SimplePythonToValue(PyArg, ArgType.Handle, Arg, ErrMsg);
end;
@@ -2277,7 +2292,7 @@ function TValueToPyObject(const Value: TValue;
DelphiWrapper: TPyDelphiWrapper; out ErrMsg: string): PPyObject;
begin
if Value.IsEmpty then
- Result := GetPythonEngine.ReturnNone
+ Result := DelphiWrapper.Engine.ReturnNone
else
case Value.Kind of
tkClass: Result := DelphiWrapper.Wrap(Value.AsObject);
@@ -2288,13 +2303,10 @@ function TValueToPyObject(const Value: TValue;
tkArray, tkDynArray:
Result := DynArrayToPython(Value, DelphiWrapper, ErrMsg);
tkPointer:
- if Value.IsType then
+ if Value.TypeInfo = TypeInfo(PPyObject) then
Result := Value.AsType
else
- begin
- Result := nil;
- ErrMsg := rs_ErrValueToPython;
- end;
+ Result := DelphiWrapper.Engine.PyLong_FromVoidPtr(Value.AsType);
else
Result := SimpleValueToPython(Value, ErrMsg);
end;
diff --git a/Source/fmx/WrapDelphiFmx.pas b/Source/fmx/WrapDelphiFmx.pas
index 0bcc5f45..92f11120 100644
--- a/Source/fmx/WrapDelphiFmx.pas
+++ b/Source/fmx/WrapDelphiFmx.pas
@@ -24,9 +24,7 @@ implementation
WrapDelphiWindows,
{$ENDIF MSWINDOWS}
WrapDelphiDataBind,
- {$IFNDEF LINUX}
WrapFmxDataBind,
- {$ENDIF LINUX}
WrapFmxTypes,
WrapFmxImgList,
WrapFmxControls,
diff --git a/Tests/WrapDelphiTest.pas b/Tests/WrapDelphiTest.pas
index 350b0bb2..d320f53a 100644
--- a/Tests/WrapDelphiTest.pas
+++ b/Tests/WrapDelphiTest.pas
@@ -55,6 +55,7 @@ TTestRttiAccess = class
ObjectField: TObject;
RecordField: TTestRecord;
InterfaceField: ITestInterface;
+ PointerField: Pointer;
ClassRef: TClass;
function GetData: TObject;
procedure BuyFruits(AFruits: TFruits);
@@ -160,6 +161,8 @@ TTestWrapDelphi = class(TObject)
procedure TestVarArgs;
[Test]
procedure TestPPyObjects;
+ [Test]
+ procedure TestPointers;
end;
implementation
@@ -439,6 +442,12 @@ procedure TTestWrapDelphi.TestPPyObjects;
Assert.AreEqual(List.GetItem(0), 'abc');
end;
+procedure TTestWrapDelphi.TestPointers;
+begin
+ rtti_var.PointerField := $FFFF;
+ Assert.AreEqual(rtti_var.PointerField, $FFFF);
+end;
+
procedure TTestWrapDelphi.TestRecord;
begin
Rtti_rec.StringField := 'abcd';
diff --git a/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm b/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm
index cda1daa9..0d78949a 100644
--- a/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm
+++ b/Tutorials/Webinar II/VizDemo/MainFormSVG.dfm
@@ -10,17 +10,12 @@ object Form1: TForm1
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
- OldCreateOrder = False
OnCreate = FormCreate
- PixelsPerInch = 96
TextHeight = 13
object Splitter1: TSplitter
Left = 489
Top = 0
Height = 613
- ExplicitLeft = 528
- ExplicitTop = 280
- ExplicitHeight = 100
end
object SVGIconImage1: TSVGIconImage
Left = 960
@@ -35,8 +30,6 @@ object Form1: TForm1
Width = 543
Height = 613
AutoSize = False
- ParentDoubleBuffered = False
- DoubleBuffered = True
Align = alClient
end
object PageControl1: TPageControl
@@ -46,7 +39,7 @@ object Form1: TForm1
Height = 613
ActivePage = TabSheet1
Align = alLeft
- TabOrder = 2
+ TabOrder = 0
object TabSheet1: TTabSheet
Caption = 'matplotlib'
object Panel1: TPanel
@@ -63,8 +56,6 @@ object Form1: TForm1
Height = 3
Cursor = crVSplit
Align = alBottom
- ExplicitTop = 10
- ExplicitWidth = 492
end
object SynEdit1: TSynEdit
Left = 1
@@ -72,6 +63,7 @@ object Form1: TForm1
Width = 479
Height = 444
Align = alClient
+ CaseSensitive = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
@@ -85,6 +77,8 @@ object Form1: TForm1
Gutter.Font.Height = -11
Gutter.Font.Name = 'Consolas'
Gutter.Font.Style = []
+ Gutter.Font.Quality = fqClearTypeNatural
+ Gutter.Bands = <>
Highlighter = SynPythonSyn1
Lines.Strings = (
'from delphi_module import svg_image'
@@ -102,10 +96,16 @@ object Form1: TForm1
'# stores the date as an np.datetime64 with a day unit ('#39'D'#39') in t' +
'he date column.'
-
- 'price_data = (cbook.get_sample_data('#39'goog.npz'#39', np_load=True)['#39'p' +
- 'rice_data'#39']'
- ' .view(np.recarray))'
+ '# Load Google stock price data from Matplotlib'#39's sample data'
+ 'data = cbook.get_sample_data('#39'goog.npz'#39')'
+ ''
+ '# Handle different return types from get_sample_data'
+ 'if isinstance(data, np.lib.npyio.NpzFile):'
+ ' # Already an NpzFile, access price_data directly'
+ ' price_data = data['#39'price_data'#39'].view(np.recarray)'
+ 'else:'
+ ' # Assume data is a path or file-like object, use np.load'
+ ' price_data = np.load(data)['#39'price_data'#39'].view(np.recarray)'
'price_data = price_data[-250:] # get the most recent 250 tradin' +
'g days'
@@ -138,6 +138,7 @@ object Form1: TForm1
'svg_image.SvgText = figdata_svg'
''
'#plt.show()')
+ ScrollbarAnnotations = <>
end
object Panel2: TPanel
Left = 1
@@ -183,8 +184,6 @@ object Form1: TForm1
Height = 3
Cursor = crVSplit
Align = alBottom
- ExplicitTop = 151
- ExplicitWidth = 433
end
object SynEdit2: TSynEdit
Left = 1
@@ -192,6 +191,7 @@ object Form1: TForm1
Width = 479
Height = 376
Align = alClient
+ CaseSensitive = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
@@ -205,6 +205,8 @@ object Form1: TForm1
Gutter.Font.Height = -11
Gutter.Font.Name = 'Consolas'
Gutter.Font.Style = []
+ Gutter.Font.Quality = fqClearTypeNatural
+ Gutter.Bands = <>
Highlighter = SynPythonSyn1
Lines.Strings = (
'from delphi_module import svg_image'
@@ -222,6 +224,7 @@ object Form1: TForm1
''
'#plt.show()'
'')
+ ScrollbarAnnotations = <>
end
object Panel6: TPanel
Left = 1
@@ -252,9 +255,6 @@ object Form1: TForm1
end
end
object SynPythonSyn1: TSynPythonSyn
- Options.AutoDetectEnabled = False
- Options.AutoDetectLineLimit = 0
- Options.Visible = False
Left = 632
Top = 40
end
@@ -264,6 +264,10 @@ object Form1: TForm1
Top = 89
end
object PythonEngine1: TPythonEngine
+ DllName = 'python313.dll'
+ APIVersion = 1013
+ RegVersion = '3.13'
+ UseLastKnownVersion = False
IO = PythonGUIInputOutput1
Left = 632
Top = 136