Delphi.Personality.12
@@ -117,16 +132,714 @@
+
+
+
+ dclPythonVcl.bpl
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ 1
+
+
+ 0
+
+
+
+
+ classes
+ 1
+
+
+ classes
+ 1
+
+
+
+
+ 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-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
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 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\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
+
+
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
- False
- False
- False
- False
- False
True
- False
- False
- False
+ True
12
diff --git a/Packages/Delphi/Delphi 10.4+/dclPythonVcl.res b/Packages/Delphi/Delphi 10.4+/dclPythonVcl.res
new file mode 100644
index 00000000..06004792
Binary files /dev/null and b/Packages/Delphi/Delphi 10.4+/dclPythonVcl.res differ
diff --git a/Packages/Delphi/Delphi 10.4+/dclPythonVclResource.rc b/Packages/Delphi/Delphi 10.4+/dclPythonVclResource.rc
new file mode 100644
index 00000000..f3a83271
--- /dev/null
+++ b/Packages/Delphi/Delphi 10.4+/dclPythonVclResource.rc
@@ -0,0 +1 @@
+TPythonGUIInputOutput BITMAP "..\\..\\Resources\\TPYTHONGUIINPUTOUTPUT.bmp"
diff --git a/Packages/FPC/p4dlaz_register.pas b/Packages/FPC/p4dlaz_register.pas
index ab6b0986..f693a653 100644
--- a/Packages/FPC/p4dlaz_register.pas
+++ b/Packages/FPC/p4dlaz_register.pas
@@ -1,25 +1,25 @@
-unit P4DLaz_register;
-
-interface
-
-uses SysUtils, Classes;
-
-procedure Register;
-
-implementation
-{$R '..\..\Source\PythonEngine.dcr'}
-
-uses
- PythonEngine,
- Lcl.PythonGUIInputOutput,
- WrapDelphi;
-
-procedure Register;
-begin
- RegisterComponents('Python', [TPythonEngine, TPythonInputOutput,
- TPythonType, TPythonModule, TPythonDelphiVar]);
- RegisterComponents('Python', [TPythonGUIInputOutput]);
- RegisterComponents('Python', [TPyDelphiWrapper]);
-end;
-
-end.
+unit P4DLaz_register;
+
+interface
+
+uses SysUtils, Classes;
+
+procedure Register;
+
+implementation
+{$R '..\..\Source\PythonEngine.dcr'}
+
+uses
+ PythonEngine,
+ Lcl.PythonGUIInputOutput,
+ WrapDelphi;
+
+procedure Register;
+begin
+ RegisterComponents('Python', [TPythonEngine, TPythonInputOutput,
+ TPythonType, TPythonModule, TPythonDelphiVar]);
+ RegisterComponents('Python', [TPythonGUIInputOutput]);
+ RegisterComponents('Python', [TPyDelphiWrapper]);
+end;
+
+end.
diff --git a/Source/Definition.Inc b/Source/Definition.Inc
index 826b61a9..5d1efe02 100644
--- a/Source/Definition.Inc
+++ b/Source/Definition.Inc
@@ -173,7 +173,7 @@
{$DEFINE DELPHI10_4_OR_HIGHER}
{$IF RTLVERSION1042}
{$DEFINE DELPHI10_4_2} //Delphi 10.4.2
- {$ENDIF RTLVERSION1042}
+ {$IFEND RTLVERSION1042}
{$ENDIF}
{$IFDEF VER350} // Delphi 11
{$DEFINE DELPHI11}
@@ -244,7 +244,7 @@
{$ENDIF FPC}
{$IFDEF DELPHIXE_OR_HIGHER}
- {$DEFINE EXTENDED_RTTI}
+ //{$DEFINE EXTENDED_RTTI}
{$ENDIF DELPHIXE_OR_HIGHER}
{$IFDEF DELPHIXE4_OR_HIGHER}
diff --git a/Source/PythonEngine.pas b/Source/PythonEngine.pas
index e29bed72..06ead906 100644
--- a/Source/PythonEngine.pas
+++ b/Source/PythonEngine.pas
@@ -19,11 +19,11 @@
{ TODO -oMMM : implement tp_as_buffer slot }
{ TODO -oMMM : implement Attribute descriptor and subclassing stuff }
-{$IFNDEF FPC}
- {$IFNDEF DELPHIXE2_OR_HIGHER}
- Error! Delphi XE2 or higher is required!
- {$ENDIF}
-{$ENDIF}
+//{$IFNDEF FPC}
+// {$IFNDEF DELPHIXE2_OR_HIGHER}
+// Error! Delphi XE2 or higher is required!
+// {$ENDIF}
+//{$ENDIF}
{$IF defined(LINUX) or (defined(BSD) and not defined(DARWIN)) or defined(SOLARIS) or defined(HAIKU)}
{$define _so_files}
@@ -173,7 +173,7 @@ TPythonVersionProp = record
C_Long = Integer;
C_ULong = Cardinal;
{$ELSE}
- C_Long = NativeInt;
+ C_Long= NativeInt;
C_ULong = NativeUInt;
{$ENDIF}
@@ -1396,6 +1396,7 @@ TPythonInterface=class(TDynamicDll)
Py_BuildValue: TPy_BuildValue;
Py_Initialize: procedure; cdecl;
+ Py_InitializeEx: procedure(initsigs: Integer); cdecl;
Py_Exit: procedure( RetVal: Integer); cdecl;
PyEval_GetBuiltins: function: PPyObject; cdecl;
PyDict_Copy: function(mp: PPyObject):PPyObject; cdecl;
@@ -2023,8 +2024,8 @@ TEngineClient = class(TComponent)
//-- --
//-------------------------------------------------------
- TDelphiMethod = function ( self, args : PPyObject ) : PPyObject of object; cdecl;
- TDelphiMethodWithKW = function ( self, args, keywords : PPyObject ) : PPyObject of object; cdecl;
+ TDelphiMethod = function ( PSelf, Args : PPyObject ) : PPyObject of object; cdecl;
+ TDelphiMethodWithKW = function ( PSelf, Args, keywords : PPyObject ) : PPyObject of object; cdecl;
TPythonEvent = procedure(Sender: TObject; PSelf, Args: PPyObject; var Result: PPyObject) of object;
TMethodsContainer = class; // forward declaration
TEventDefs = class; // forward declaration
@@ -3033,7 +3034,7 @@ function TDynamicDll.GetDllPath : string;
Result := DllPath;
if (DLLPath = '') and not FInExtensionModule then begin
- {$IFDEF MSWINDOWS}
+ {$IFDEF MSWINDOWS}
if IsPythonVersionRegistered(RegVersion, Result, AllUserInstall) and (Self is TPythonEngine) then
// https://github.com/python/cpython/issues/100171
TPythonEngine(Self).SetPythonHome(Result);
@@ -3617,6 +3618,7 @@ procedure TPythonInterface.MapDll;
PyArg_ParseTupleAndKeywords := Import('PyArg_ParseTupleAndKeywords');
Py_BuildValue := Import('Py_BuildValue');
Py_Initialize := Import('Py_Initialize');
+ Py_InitializeEx := Import('Py_InitializeEx');
PyModule_GetDict := Import('PyModule_GetDict');
PyObject_Str := Import('PyObject_Str');
PyRun_String := Import('PyRun_String');
@@ -4177,7 +4179,7 @@ procedure TPythonTraceback.Refresh(pytraceback: PPyObject);
alimit := PyLong_AsLong(limitv);
tb := pytraceback;
if tb = nil then
- tb := PySys_GetObject('last_traceback');
+ tb := PySys_GetObject('last_traceback');
tb1 := tb;
Py_XIncRef(tb1);
depth := 0;
@@ -4311,10 +4313,14 @@ procedure TPythonEngine.Finalize;
begin
RedirectIO := False;
// restore the initial streams also.
- ExecString('import sys'+LF+
- 'if hasattr(sys, "old_stdin"): sys.stdin=sys.old_stdin'+LF+
- 'if hasattr(sys, "old_stdout"): sys.stdout=sys.old_stdout'+LF+
- 'if hasattr(sys, "old_stderr"): sys.stderr=sys.old_stderr' );
+ try
+ ExecString('import sys'+LF+
+ 'if hasattr(sys, "old_stdin"): sys.stdin=sys.old_stdin'+LF+
+ 'if hasattr(sys, "old_stdout"): sys.stdout=sys.old_stdout'+LF+
+ 'if hasattr(sys, "old_stderr"): sys.stderr=sys.old_stderr' );
+ except
+ // Exception if a script error occurred previously. e.g. in CheckExecSyntax with incorrect syntax.
+ end;
end;
// First finalize our clients
if Initialized then
@@ -4654,9 +4660,9 @@ procedure TPythonEngine.SetProgramArgs;
TempS := ''
else
TempS := ParamStr(I);
- {$IFDEF POSIX}
+ {$IFDEF POSIX}
WL[I] := UnicodeStringToUCS4String(TempS);
- {$ELSE}
+ {$ELSE}
WL[I] := UnicodeString(TempS);
{$ENDIF}
wargv[I] := PWCharT(WL[I]);
@@ -4781,7 +4787,7 @@ procedure TPythonEngine.SetPythonHome(const PythonHome: UnicodeString);
{$IFDEF POSIX}
FPythonHome := UnicodeStringToUCS4String(PythonHome);
{$ELSE}
- FPythonHome := PythonHome;
+ FPythonHome := PythonHome;
{$ENDIF}
end;
@@ -5431,7 +5437,7 @@ function TPythonEngine.ModuleByName( const aModuleName : AnsiString ) : PPyObj
raise Exception.CreateFmt('Could not find module: %s', [aModuleName]);
end;
-function TPythonEngine.MethodsByName( const aMethodsContainer: string ) : PPyMethodDef;
+function TPythonEngine.MethodsByName( const aMethodsContainer: string ) : PPyMethodDef;
var
i : Integer;
begin
@@ -6092,7 +6098,7 @@ function TPythonEngine.PyUnicodeFromString(const AString : UnicodeString) : PPyO
_ucs4Str := WideStringToUCS4String(AString);
Result := PyUnicode_FromWideChar(@_ucs4Str[0], Length(_ucs4Str)-1 {trim trailing zero});
{$ELSE}
- Result := PyUnicode_FromWideChar(PWideChar(AString), Length(AString));
+ Result := PyUnicode_FromWideChar( PWideChar(AString), Length(AString) );
{$ENDIF}
end;
@@ -6221,7 +6227,7 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
var
errtype, errvalue, errtraceback: PPyObject;
SErrValue: string;
- begin
+begin
PyErr_Fetch(errtype, errvalue, errtraceback);
Traceback.Refresh(errtraceback);
SErrValue := PyObjectAsString(errvalue);
@@ -6231,10 +6237,10 @@ procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
var
PyException: PPyObject;
-begin
+ begin
PyException := PyErr_Occurred;
if PyException <> nil then
- begin
+ begin
if ACatchStopEx and (PyErr_GivenExceptionMatches(PyException, PyExc_StopIteration^) <> 0) then
begin
PyErr_Clear;
diff --git a/Tests/FMX/Android/MethodCallBackTest.pas b/Tests/FMX/Android/MethodCallBackTest.pas
index f4d2044f..9ea45f45 100644
--- a/Tests/FMX/Android/MethodCallBackTest.pas
+++ b/Tests/FMX/Android/MethodCallBackTest.pas
@@ -1,262 +1,262 @@
-(**************************************************************************)
-(* *)
-(* Module: Unit 'MethodCallbackTest' Copyright (c) 2021 *)
-(* *)
-(* Lucas Moura Belo - lmbelo *)
-(* lucas.belo@live.com *)
-(* BH, Brazil *)
-(* *)
-(* PyScripter *)
-(* e-mail: pyscripter@gmail.com *)
-(* *)
-(* Project pages: https://github.com/Embarcadero/python4delphi *)
-(* https://github.com/pyscripter/python4delphi *)
-(**************************************************************************)
-(* Functionality: Test unit for MethodCallback *)
-(* *)
-(* *)
-(**************************************************************************)
-(* This source code is distributed with no WARRANTY, for no reason or use.*)
-(* Everyone is allowed to use and change this code free for his own tasks *)
-(* and projects, as long as this header and its copyright text is intact. *)
-(* For changed versions of this code, which are public distributed the *)
-(* following additional conditions have to be fullfilled: *)
-(* 1) The header has to contain a comment on the change and the author of *)
-(* it. *)
-(* 2) A copy of the changed source has to be sent to the above E-Mail *)
-(* address or my then valid address, if this is possible to the *)
-(* author. *)
-(* The second condition has the target to maintain an up to date central *)
-(* version of the component. If this condition is not acceptable for *)
-(* confidential or legal reasons, everyone is free to derive a component *)
-(* or to generate a diff file to my or other original sources. *)
-(**************************************************************************)
-
-unit MethodCallBackTest;
-
-interface
-
-uses
- DUnitX.TestFramework,
- MethodCallback,
- PythonLoad;
-
-implementation
-
-type
- TTwoArgArmStdFunction = function (arg1, arg2: string): integer;
- TThreeArgArmStdProcedure = procedure (arg1, arg2, arg3: string);
-
- TFourArgArmStdFunction = function(arg1, arg2, arg3, arg4: integer): integer;
- TFiveArgArmStdFunction = function(arg1, arg2, arg3, arg4, arg5: integer): integer;
-
- TMyFuncCallback = function(arg1, arg2: string): integer of object;
- TMyProcCallback = procedure (arg1, arg2, arg3: string) of object;
-
- TTestObj = class
- public
- Argument1: string;
- Argument2: string;
- Argument3: string;
- function TwoArgArmStdFunction(arg1, arg2: string): integer;
- procedure ThreeArgArmStdProcedure(arg1, arg2, arg3: string);
- function FourArgArmStdFunction(arg1, arg2, arg3, arg4: integer): integer;
- function FiveArgArmStdFunction(arg1, arg2, arg3, arg4, arg5: integer): integer;
- end;
-
- [TestFixture]
- TMethodCallbackTest = class
- private
- fTestObj: TTestObj;
- public
- [SetupFixture]
- procedure SetupFixture;
- [TearDownFixture]
- procedure Teardown;
- [Test]
- procedure TestDeleteOnEmptyAllocator;
- [Test]
- procedure TestCallBackArmStd;
- [Test]
- procedure TestOfObjectCallBackArmStd;
- [Test]
- procedure TestDeleteCallBack;
- [Test]
- procedure TestFourArgArmStdFunction;
- [Test]
- procedure TestFiveArgArmStdFunction;
- [Test]
- procedure TestMemoryMgmt;
- end;
-
-{ TTestObj }
-
-function TTestObj.FiveArgArmStdFunction(arg1, arg2, arg3, arg4,
- arg5: integer): integer;
-begin
- Result := arg1 * arg4 + arg2 * arg5 + arg3;
-end;
-
-function TTestObj.FourArgArmStdFunction(arg1, arg2, arg3, arg4: integer): integer;
-begin
- Result := arg1 * arg3 + arg2 * arg4;
-end;
-
-procedure TTestObj.ThreeArgArmStdProcedure(arg1, arg2, arg3: string);
-begin
- Argument1:=arg1;
- Argument2:=arg2;
- Argument3:=arg3;
-end;
-
-function TTestObj.TwoArgArmStdFunction(arg1, arg2: string): integer;
-begin
- Argument1:=arg1;
- Argument2:=arg2;
- result:=1;
-end;
-
-{ TMethodCallbackTest }
-
-procedure TMethodCallbackTest.SetupFixture;
-begin
- fTestObj:=TTestObj.Create;
-end;
-
-procedure TMethodCallbackTest.Teardown;
-begin
- fTestObj.Free;
- FreeCallBacks;
-end;
-
-procedure TMethodCallbackTest.TestMemoryMgmt;
-const
- AllocCount = {$IFDEF CPUARM}
- {$IFDEF CPUARM32}
- 31
- {$ELSE}
- 46
- {$ENDIF CPUARM32}
- {$ELSE}
- {$IFDEF CPUX64}
- {$IFDEF MSWINDOWS}
- 51
- {$ELSE}
- 88
- {$ENDIF}
- {$ELSE}
- 90
- {$ENDIF}
- {$ENDIF};
-var
- i: integer;
- ptr: Pointer;
-begin
- //---Test the code-memory manager
-
- FreeCallBacks;
- Assert.AreEqual(0, CodeMemPageCount);
-
- for i:=1 to AllocCount do
- ptr:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 5, ctArmStd);
-
- // there should still be 1 page allocated
- Assert.AreEqual(1, CodeMemPageCount);
-
- // get one callback more and we should have 2 pages
- ptr:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 5, ctArmStd);
- // getting CodeMemPageCount would crash as the next page pointer was overwritten by the
- // last allocation
- Assert.AreEqual(2, CodeMemPageCount);
-end;
-
-procedure TMethodCallbackTest.TestCallBackArmStd;
-var
- ptr: pointer;
- func: TTwoArgArmStdFunction;
-begin
- ptr:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
-
- //---call method through pointer
- func:=TTwoArgArmStdFunction(ptr);
-
- Assert.AreEqual(1, func('first arg', 'second arg'));
- Assert.AreEqual(string('first arg'), fTestObj.Argument1);
- Assert.AreEqual(string('second arg'), fTestObj.Argument2);
-end;
-
-procedure TMethodCallbackTest.TestDeleteCallBack;
-var
- ptr1, ptr2, ptr3: Pointer;
- proc: TThreeArgArmStdProcedure;
- func: TTwoArgArmStdFunction;
-begin
- //---we create 3 callbacks and delete them.
- // if there aren't any AV, we assume it works...
- ptr1:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 3, ctArmStd);
- ptr2:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
- DeleteCallBack(ptr1);
- ptr1:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
- ptr3:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 3, ctArmStd);
-
- func:=TTwoArgArmStdFunction(ptr1);
- func('arg1', 'arg2');
- func:=TTwoArgArmStdFunction(ptr2);
- func('arg1', 'arg2');
- proc:=TThreeArgArmStdProcedure(ptr3);
- proc('arg1', 'arg2', 'arg3');
-
- DeleteCallBack(ptr1);
- DeleteCallBack(ptr2);
- DeleteCallback(ptr3);
- Assert.Pass;
-end;
-
-procedure TMethodCallbackTest.TestDeleteOnEmptyAllocator;
-var
- ptr1 : Pointer;
-begin
- ptr1 := nil;
- DeleteCallBack(ptr1);
- Assert.Pass();
-end;
-
-procedure TMethodCallbackTest.TestFiveArgArmStdFunction;
-Var
- CallBack : TFiveArgArmStdFunction;
-begin
- CallBack := GetCallBack(fTestObj, @TTestObj.FiveArgArmStdFunction, 5, ctArmStd);
- Assert.AreEqual(CallBack(1,2,3,4,5), 1*4+2*5+3);
- DeleteCallBack(@CallBack);
-end;
-
-procedure TMethodCallbackTest.TestFourArgArmStdFunction;
-Var
- CallBack : TFourArgArmStdFunction;
-begin
- CallBack := GetCallBack(fTestObj, @TTestObj.FourArgArmStdFunction, 4, ctArmStd);
- Assert.AreEqual(CallBack(1,2,3,4), 1*3+2*4);
- DeleteCallBack(@CallBack);
-end;
-
-procedure TMethodCallbackTest.TestOfObjectCallBackArmStd;
-var
- ptr: pointer;
- func: TTwoArgArmStdFunction;
- cb: TMyFuncCallBack;
-begin
- cb:=fTestObj.TwoArgArmStdFunction;
- ptr:=GetOfObjectCallBack(TCallBack(cb), 2, ctARMSTD);
-
- //---call method through pointer
- func:=TTwoArgArmStdFunction(ptr);
-
- Assert.AreEqual(1, func('first arg', 'second arg'));
- Assert.AreEqual('first arg', fTestObj.Argument1);
- Assert.AreEqual('second arg', fTestObj.Argument2);
-end;
-
-initialization
- TDUnitX.RegisterTestFixture(TMethodCallBackTest);
-
-end.
+(**************************************************************************)
+(* *)
+(* Module: Unit 'MethodCallbackTest' Copyright (c) 2021 *)
+(* *)
+(* Lucas Moura Belo - lmbelo *)
+(* lucas.belo@live.com *)
+(* BH, Brazil *)
+(* *)
+(* PyScripter *)
+(* e-mail: pyscripter@gmail.com *)
+(* *)
+(* Project pages: https://github.com/Embarcadero/python4delphi *)
+(* https://github.com/pyscripter/python4delphi *)
+(**************************************************************************)
+(* Functionality: Test unit for MethodCallback *)
+(* *)
+(* *)
+(**************************************************************************)
+(* This source code is distributed with no WARRANTY, for no reason or use.*)
+(* Everyone is allowed to use and change this code free for his own tasks *)
+(* and projects, as long as this header and its copyright text is intact. *)
+(* For changed versions of this code, which are public distributed the *)
+(* following additional conditions have to be fullfilled: *)
+(* 1) The header has to contain a comment on the change and the author of *)
+(* it. *)
+(* 2) A copy of the changed source has to be sent to the above E-Mail *)
+(* address or my then valid address, if this is possible to the *)
+(* author. *)
+(* The second condition has the target to maintain an up to date central *)
+(* version of the component. If this condition is not acceptable for *)
+(* confidential or legal reasons, everyone is free to derive a component *)
+(* or to generate a diff file to my or other original sources. *)
+(**************************************************************************)
+
+unit MethodCallBackTest;
+
+interface
+
+uses
+ DUnitX.TestFramework,
+ MethodCallback,
+ PythonLoad;
+
+implementation
+
+type
+ TTwoArgArmStdFunction = function (arg1, arg2: string): integer;
+ TThreeArgArmStdProcedure = procedure (arg1, arg2, arg3: string);
+
+ TFourArgArmStdFunction = function(arg1, arg2, arg3, arg4: integer): integer;
+ TFiveArgArmStdFunction = function(arg1, arg2, arg3, arg4, arg5: integer): integer;
+
+ TMyFuncCallback = function(arg1, arg2: string): integer of object;
+ TMyProcCallback = procedure (arg1, arg2, arg3: string) of object;
+
+ TTestObj = class
+ public
+ Argument1: string;
+ Argument2: string;
+ Argument3: string;
+ function TwoArgArmStdFunction(arg1, arg2: string): integer;
+ procedure ThreeArgArmStdProcedure(arg1, arg2, arg3: string);
+ function FourArgArmStdFunction(arg1, arg2, arg3, arg4: integer): integer;
+ function FiveArgArmStdFunction(arg1, arg2, arg3, arg4, arg5: integer): integer;
+ end;
+
+ [TestFixture]
+ TMethodCallbackTest = class
+ private
+ fTestObj: TTestObj;
+ public
+ [SetupFixture]
+ procedure SetupFixture;
+ [TearDownFixture]
+ procedure Teardown;
+ [Test]
+ procedure TestDeleteOnEmptyAllocator;
+ [Test]
+ procedure TestCallBackArmStd;
+ [Test]
+ procedure TestOfObjectCallBackArmStd;
+ [Test]
+ procedure TestDeleteCallBack;
+ [Test]
+ procedure TestFourArgArmStdFunction;
+ [Test]
+ procedure TestFiveArgArmStdFunction;
+ [Test]
+ procedure TestMemoryMgmt;
+ end;
+
+{ TTestObj }
+
+function TTestObj.FiveArgArmStdFunction(arg1, arg2, arg3, arg4,
+ arg5: integer): integer;
+begin
+ Result := arg1 * arg4 + arg2 * arg5 + arg3;
+end;
+
+function TTestObj.FourArgArmStdFunction(arg1, arg2, arg3, arg4: integer): integer;
+begin
+ Result := arg1 * arg3 + arg2 * arg4;
+end;
+
+procedure TTestObj.ThreeArgArmStdProcedure(arg1, arg2, arg3: string);
+begin
+ Argument1:=arg1;
+ Argument2:=arg2;
+ Argument3:=arg3;
+end;
+
+function TTestObj.TwoArgArmStdFunction(arg1, arg2: string): integer;
+begin
+ Argument1:=arg1;
+ Argument2:=arg2;
+ result:=1;
+end;
+
+{ TMethodCallbackTest }
+
+procedure TMethodCallbackTest.SetupFixture;
+begin
+ fTestObj:=TTestObj.Create;
+end;
+
+procedure TMethodCallbackTest.Teardown;
+begin
+ fTestObj.Free;
+ FreeCallBacks;
+end;
+
+procedure TMethodCallbackTest.TestMemoryMgmt;
+const
+ AllocCount = {$IFDEF CPUARM}
+ {$IFDEF CPUARM32}
+ 31
+ {$ELSE}
+ 46
+ {$ENDIF CPUARM32}
+ {$ELSE}
+ {$IFDEF CPUX64}
+ {$IFDEF MSWINDOWS}
+ 51
+ {$ELSE}
+ 88
+ {$ENDIF}
+ {$ELSE}
+ 90
+ {$ENDIF}
+ {$ENDIF};
+var
+ i: integer;
+ ptr: Pointer;
+begin
+ //---Test the code-memory manager
+
+ FreeCallBacks;
+ Assert.AreEqual(0, CodeMemPageCount);
+
+ for i:=1 to AllocCount do
+ ptr:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 5, ctArmStd);
+
+ // there should still be 1 page allocated
+ Assert.AreEqual(1, CodeMemPageCount);
+
+ // get one callback more and we should have 2 pages
+ ptr:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 5, ctArmStd);
+ // getting CodeMemPageCount would crash as the next page pointer was overwritten by the
+ // last allocation
+ Assert.AreEqual(2, CodeMemPageCount);
+end;
+
+procedure TMethodCallbackTest.TestCallBackArmStd;
+var
+ ptr: pointer;
+ func: TTwoArgArmStdFunction;
+begin
+ ptr:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
+
+ //---call method through pointer
+ func:=TTwoArgArmStdFunction(ptr);
+
+ Assert.AreEqual(1, func('first arg', 'second arg'));
+ Assert.AreEqual(string('first arg'), fTestObj.Argument1);
+ Assert.AreEqual(string('second arg'), fTestObj.Argument2);
+end;
+
+procedure TMethodCallbackTest.TestDeleteCallBack;
+var
+ ptr1, ptr2, ptr3: Pointer;
+ proc: TThreeArgArmStdProcedure;
+ func: TTwoArgArmStdFunction;
+begin
+ //---we create 3 callbacks and delete them.
+ // if there aren't any AV, we assume it works...
+ ptr1:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 3, ctArmStd);
+ ptr2:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
+ DeleteCallBack(ptr1);
+ ptr1:=GetCallBack(fTestObj, @TTestObj.TwoArgArmStdFunction, 2, ctArmStd);
+ ptr3:=GetCallBack(fTestObj, @TTestObj.ThreeArgArmStdProcedure, 3, ctArmStd);
+
+ func:=TTwoArgArmStdFunction(ptr1);
+ func('arg1', 'arg2');
+ func:=TTwoArgArmStdFunction(ptr2);
+ func('arg1', 'arg2');
+ proc:=TThreeArgArmStdProcedure(ptr3);
+ proc('arg1', 'arg2', 'arg3');
+
+ DeleteCallBack(ptr1);
+ DeleteCallBack(ptr2);
+ DeleteCallback(ptr3);
+ Assert.Pass;
+end;
+
+procedure TMethodCallbackTest.TestDeleteOnEmptyAllocator;
+var
+ ptr1 : Pointer;
+begin
+ ptr1 := nil;
+ DeleteCallBack(ptr1);
+ Assert.Pass();
+end;
+
+procedure TMethodCallbackTest.TestFiveArgArmStdFunction;
+Var
+ CallBack : TFiveArgArmStdFunction;
+begin
+ CallBack := GetCallBack(fTestObj, @TTestObj.FiveArgArmStdFunction, 5, ctArmStd);
+ Assert.AreEqual(CallBack(1,2,3,4,5), 1*4+2*5+3);
+ DeleteCallBack(@CallBack);
+end;
+
+procedure TMethodCallbackTest.TestFourArgArmStdFunction;
+Var
+ CallBack : TFourArgArmStdFunction;
+begin
+ CallBack := GetCallBack(fTestObj, @TTestObj.FourArgArmStdFunction, 4, ctArmStd);
+ Assert.AreEqual(CallBack(1,2,3,4), 1*3+2*4);
+ DeleteCallBack(@CallBack);
+end;
+
+procedure TMethodCallbackTest.TestOfObjectCallBackArmStd;
+var
+ ptr: pointer;
+ func: TTwoArgArmStdFunction;
+ cb: TMyFuncCallBack;
+begin
+ cb:=fTestObj.TwoArgArmStdFunction;
+ ptr:=GetOfObjectCallBack(TCallBack(cb), 2, ctARMSTD);
+
+ //---call method through pointer
+ func:=TTwoArgArmStdFunction(ptr);
+
+ Assert.AreEqual(1, func('first arg', 'second arg'));
+ Assert.AreEqual('first arg', fTestObj.Argument1);
+ Assert.AreEqual('second arg', fTestObj.Argument2);
+end;
+
+initialization
+ TDUnitX.RegisterTestFixture(TMethodCallBackTest);
+
+end.
diff --git a/Tests/FMX/Android/P4DAndroidTest.dpr b/Tests/FMX/Android/P4DAndroidTest.dpr
index c711bef2..a4b96caa 100644
--- a/Tests/FMX/Android/P4DAndroidTest.dpr
+++ b/Tests/FMX/Android/P4DAndroidTest.dpr
@@ -1,18 +1,18 @@
-program P4DAndroidTest;
-uses
- System.StartUpCopy,
- FMX.Forms,
- DUNitX.Loggers.MobileGUI,
- MethodCallBackTest in 'MethodCallBackTest.pas',
- NumberServicesTest in 'NumberServicesTest.pas',
- PyEnvTest in 'PyEnvTest.pas',
- PythonLoad in 'PythonLoad.pas',
- VarPythTest in 'VarPythTest.pas',
- WrapDelphiTest in 'WrapDelphiTest.pas';
-
-{$R *.res}
-begin
- Application.Initialize;
- Application.CreateForm(TMobileGUITestRunner, MobileGUITestRunner);
- Application.Run;
-end.
+program P4DAndroidTest;
+uses
+ System.StartUpCopy,
+ FMX.Forms,
+ DUNitX.Loggers.MobileGUI,
+ MethodCallBackTest in 'MethodCallBackTest.pas',
+ NumberServicesTest in 'NumberServicesTest.pas',
+ PyEnvTest in 'PyEnvTest.pas',
+ PythonLoad in 'PythonLoad.pas',
+ VarPythTest in 'VarPythTest.pas',
+ WrapDelphiTest in 'WrapDelphiTest.pas';
+
+{$R *.res}
+begin
+ Application.Initialize;
+ Application.CreateForm(TMobileGUITestRunner, MobileGUITestRunner);
+ Application.Run;
+end.
diff --git a/Tests/FMX/Android/PyEnvTest.pas b/Tests/FMX/Android/PyEnvTest.pas
index d76098b2..1832098c 100644
--- a/Tests/FMX/Android/PyEnvTest.pas
+++ b/Tests/FMX/Android/PyEnvTest.pas
@@ -1,106 +1,106 @@
-(**************************************************************************)
-(* *)
-(* Module: Unit 'PyEnvTest' Copyright (c) 2021 *)
-(* *)
-(* Lucas Moura Belo - lmbelo *)
-(* lucas.belo@live.com *)
-(* BH, Brazil *)
-(* *)
-(* PyScripter *)
-(* e-mail: pyscripter@gmail.com *)
-(* *)
-(* Project pages: https://github.com/Embarcadero/python4delphi *)
-(* https://github.com/pyscripter/python4delphi *)
-(**************************************************************************)
-(* Functionality: Test unit for Python's environment *)
-(* *)
-(* *)
-(**************************************************************************)
-(* This source code is distributed with no WARRANTY, for no reason or use.*)
-(* Everyone is allowed to use and change this code free for his own tasks *)
-(* and projects, as long as this header and its copyright text is intact. *)
-(* For changed versions of this code, which are public distributed the *)
-(* following additional conditions have to be fullfilled: *)
-(* 1) The header has to contain a comment on the change and the author of *)
-(* it. *)
-(* 2) A copy of the changed source has to be sent to the above E-Mail *)
-(* address or my then valid address, if this is possible to the *)
-(* author. *)
-(* The second condition has the target to maintain an up to date central *)
-(* version of the component. If this condition is not acceptable for *)
-(* confidential or legal reasons, everyone is free to derive a component *)
-(* or to generate a diff file to my or other original sources. *)
-(**************************************************************************)
-
-unit PyEnvTest;
-
-interface
-
-uses
- DUnitX.TestFramework, PythonEngine;
-
-type
- [TestFixture]
- TPyEnvTest = class
- private
- FPythonEngine: TPythonEngine;
- public
- [SetupFixture]
- procedure SetupFixture;
- [TearDownFixture]
- procedure TearDownFixture;
- [Test]
- procedure TestLibFile();
- [Test]
- procedure TestZipFile();
- [Test]
- procedure TestExtraction();
- [Test]
- procedure TestConfigure();
- end;
-
-implementation
-
-uses
- PythonLoad;
-
-{ TPyEnvTest }
-
-procedure TPyEnvTest.SetupFixture;
-begin
- FPythonEngine := TPythonEngine.Create(nil);
- FPythonEngine.Name := 'PythonEngine';
-end;
-
-procedure TPyEnvTest.TearDownFixture;
-begin
- FPythonEngine.Free();
-end;
-
-procedure TPyEnvTest.TestConfigure;
-begin
- TPythonLoad.Configure(FPythonEngine);
- FPythonEngine.LoadDll;
- Assert.IsTrue(FPythonEngine.IsHandleValid());
-end;
-
-procedure TPyEnvTest.TestExtraction;
-begin
- TPythonLoad.Extract();
- Assert.IsTrue(TPythonLoad.HasPythonDist());
-end;
-
-procedure TPyEnvTest.TestLibFile;
-begin
- Assert.IsTrue(TPythonLoad.HasPythonLib());
-end;
-
-procedure TPyEnvTest.TestZipFile;
-begin
- Assert.IsTrue(TPythonLoad.HasPythonZip());
-end;
-
-initialization
- TDUnitX.RegisterTestFixture(TPyEnvTest);
-
-end.
+(**************************************************************************)
+(* *)
+(* Module: Unit 'PyEnvTest' Copyright (c) 2021 *)
+(* *)
+(* Lucas Moura Belo - lmbelo *)
+(* lucas.belo@live.com *)
+(* BH, Brazil *)
+(* *)
+(* PyScripter *)
+(* e-mail: pyscripter@gmail.com *)
+(* *)
+(* Project pages: https://github.com/Embarcadero/python4delphi *)
+(* https://github.com/pyscripter/python4delphi *)
+(**************************************************************************)
+(* Functionality: Test unit for Python's environment *)
+(* *)
+(* *)
+(**************************************************************************)
+(* This source code is distributed with no WARRANTY, for no reason or use.*)
+(* Everyone is allowed to use and change this code free for his own tasks *)
+(* and projects, as long as this header and its copyright text is intact. *)
+(* For changed versions of this code, which are public distributed the *)
+(* following additional conditions have to be fullfilled: *)
+(* 1) The header has to contain a comment on the change and the author of *)
+(* it. *)
+(* 2) A copy of the changed source has to be sent to the above E-Mail *)
+(* address or my then valid address, if this is possible to the *)
+(* author. *)
+(* The second condition has the target to maintain an up to date central *)
+(* version of the component. If this condition is not acceptable for *)
+(* confidential or legal reasons, everyone is free to derive a component *)
+(* or to generate a diff file to my or other original sources. *)
+(**************************************************************************)
+
+unit PyEnvTest;
+
+interface
+
+uses
+ DUnitX.TestFramework, PythonEngine;
+
+type
+ [TestFixture]
+ TPyEnvTest = class
+ private
+ FPythonEngine: TPythonEngine;
+ public
+ [SetupFixture]
+ procedure SetupFixture;
+ [TearDownFixture]
+ procedure TearDownFixture;
+ [Test]
+ procedure TestLibFile();
+ [Test]
+ procedure TestZipFile();
+ [Test]
+ procedure TestExtraction();
+ [Test]
+ procedure TestConfigure();
+ end;
+
+implementation
+
+uses
+ PythonLoad;
+
+{ TPyEnvTest }
+
+procedure TPyEnvTest.SetupFixture;
+begin
+ FPythonEngine := TPythonEngine.Create(nil);
+ FPythonEngine.Name := 'PythonEngine';
+end;
+
+procedure TPyEnvTest.TearDownFixture;
+begin
+ FPythonEngine.Free();
+end;
+
+procedure TPyEnvTest.TestConfigure;
+begin
+ TPythonLoad.Configure(FPythonEngine);
+ FPythonEngine.LoadDll;
+ Assert.IsTrue(FPythonEngine.IsHandleValid());
+end;
+
+procedure TPyEnvTest.TestExtraction;
+begin
+ TPythonLoad.Extract();
+ Assert.IsTrue(TPythonLoad.HasPythonDist());
+end;
+
+procedure TPyEnvTest.TestLibFile;
+begin
+ Assert.IsTrue(TPythonLoad.HasPythonLib());
+end;
+
+procedure TPyEnvTest.TestZipFile;
+begin
+ Assert.IsTrue(TPythonLoad.HasPythonZip());
+end;
+
+initialization
+ TDUnitX.RegisterTestFixture(TPyEnvTest);
+
+end.
diff --git a/Tests/FMX/Android/VarPythTest.pas b/Tests/FMX/Android/VarPythTest.pas
index ca1e0043..f26fce2b 100644
--- a/Tests/FMX/Android/VarPythTest.pas
+++ b/Tests/FMX/Android/VarPythTest.pas
@@ -1,1084 +1,1084 @@
-(**************************************************************************)
-(* *)
-(* Module: Unit 'VarPythTest' Copyright (c) 2021 *)
-(* *)
-(* Lucas Moura Belo - lmbelo *)
-(* lucas.belo@live.com *)
-(* BH, Brazil *)
-(* *)
-(* PyScripter *)
-(* e-mail: pyscripter@gmail.com *)
-(* *)
-(* Project pages: https://github.com/Embarcadero/python4delphi *)
-(* https://github.com/pyscripter/python4delphi *)
-(**************************************************************************)
-(* Functionality: Test unit for variants *)
-(* *)
-(* *)
-(**************************************************************************)
-(* This source code is distributed with no WARRANTY, for no reason or use.*)
-(* Everyone is allowed to use and change this code free for his own tasks *)
-(* and projects, as long as this header and its copyright text is intact. *)
-(* For changed versions of this code, which are public distributed the *)
-(* following additional conditions have to be fullfilled: *)
-(* 1) The header has to contain a comment on the change and the author of *)
-(* it. *)
-(* 2) A copy of the changed source has to be sent to the above E-Mail *)
-(* address or my then valid address, if this is possible to the *)
-(* author. *)
-(* The second condition has the target to maintain an up to date central *)
-(* version of the component. If this condition is not acceptable for *)
-(* confidential or legal reasons, everyone is free to derive a component *)
-(* or to generate a diff file to my or other original sources. *)
-(**************************************************************************)
-
-unit VarPythTest;
-
-interface
-
-uses
- DUnitX.TestFramework,
- PythonEngine,
- PythonLoad;
-
-type
- {$M+}
- [TestFixture]
- TVarPythTest = class
- private
- FPythonEngine: TPythonEngine;
- public
- [SetupFixture]
- procedure SetupFixture;
- [TearDownFixture]
- procedure TearDownFixture;
- [Test]
- procedure TestIterator;
- [Test]
- procedure TestIntegers;
- [Test]
- procedure TestFloats;
- [Test]
- procedure TestStrings;
- [Test]
- procedure TestSequences;
- [Test]
- procedure TestMappings;
- [Test]
- procedure TestDates;
- [Test]
- procedure TestObjects;
- end;
-
-implementation
-
-uses
- SysUtils, StrUtils,
- Variants,
- VarPyth;
-
-{ TVarPythTest }
-
-procedure TVarPythTest.SetupFixture;
-begin
- FPythonEngine := TPythonEngine.Create(nil);
- FPythonEngine.Name := 'PythonEngine';
- TPythonLoad.Configure(FPythonEngine);
- FPythonEngine.LoadDll;
-end;
-procedure TVarPythTest.TearDownFixture;
-begin
- FPythonEngine.Free();
-end;
-procedure TVarPythTest.TestDates;
-var
- a, b, _timeMod : Variant;
- c : Variant;
- _date, _date2 : TDateTime;
- _year, _month, _day : Word;
- _year2, _month2, _day2 : Word;
- _hour, _min, _sec, _msec : Word;
- _hour2, _min2, _sec2, _msec2 : Word;
-begin
- _timeMod := Import('time'); // get the time module of Python
- _date := Now;
- DecodeDate( _date, _year, _month, _day );
- DecodeTime( _date, _hour, _min, _sec, _msec );
- b := _timeMod.localtime(_timeMod.time()); // same as Now in Delphi
- a := VarPythonCreate(_date);
- Assert.IsTrue( a.Length = 9 );
- Assert.IsTrue( a.GetItem(0) = _year );
- Assert.IsTrue( a.GetItem(1) = _month );
- Assert.IsTrue( a.GetItem(2) = _day );
- Assert.IsTrue( a.GetItem(3) = _hour );
- Assert.IsTrue( a.GetItem(4) = _min );
- Assert.IsTrue( a.GetItem(5) = _sec );
- Assert.IsTrue( b.Length = 9 );
- Assert.IsTrue( b.GetItem(0) = a.GetItem(0) );
- Assert.IsTrue( b.GetItem(1) = a.GetItem(1) );
- Assert.IsTrue( b.GetItem(2) = a.GetItem(2) );
- Assert.IsTrue( b.GetItem(3) = a.GetItem(3) );
- Assert.IsTrue( b.GetItem(4) = a.GetItem(4) );
- Assert.IsTrue( b.GetItem(5) = a.GetItem(5) );
- Assert.IsTrue( b.GetItem(6) = a.GetItem(6) );
- Assert.IsTrue( b.GetItem(7) = a.GetItem(7) );
- // don't test the 9th item of the tuple, because it's the daylight saving,
- // and it's not computed by the Python for Delphi.
- //Assert.IsTrue( b.GetItem(8) = a.GetItem(8) );
- _date2 := b;
- DecodeDate( _date2, _year2, _month2, _day2 );
- DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 );
- Assert.IsTrue( _year2 = _year );
- Assert.IsTrue( _month2 = _month );
- Assert.IsTrue( _day2 = _day );
- Assert.IsTrue( _hour2 = _hour );
- Assert.IsTrue( _min2 = _min );
- Assert.IsTrue( _sec2 = _sec );
- // test new datetime module
- _timeMod := Import('datetime'); // get the datetime module of Python
- //or _timeMod := DatetimeModule; // get the datetime module of Python
- a := _timeMod.datetime(2002, 12, 30, 22, 15, 38, 827738);
- Assert.IsTrue(VarIsPythonDateTime(a));
- Assert.IsTrue(VarIsPythonDate(a));
- Assert.IsTrue(not VarIsPythonTime(a));
- Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
- Assert.IsTrue(a.year = 2002);
- Assert.IsTrue(a.month = 12);
- Assert.IsTrue(a.day = 30);
- Assert.IsTrue(a.hour = 22);
- Assert.IsTrue(a.minute = 15);
- Assert.IsTrue(a.second = 38);
- Assert.IsTrue(a.microsecond = 827738);
- _date := a;
- DecodeDate( _date, _year, _month, _day );
- DecodeTime( _date, _hour, _min, _sec, _msec );
- Assert.IsTrue(_year = 2002);
- Assert.IsTrue(_month = 12);
- Assert.IsTrue(_day = 30);
- Assert.IsTrue(_hour = 22);
- Assert.IsTrue(_min = 15);
- Assert.IsTrue(_sec = 38);
- Assert.IsTrue(_msec = 827738 div 1000);
- a := _timeMod.date(2002, 12, 30);
- Assert.IsTrue(not VarIsPythonDateTime(a));
- Assert.IsTrue(VarIsPythonDate(a));
- Assert.IsTrue(not VarIsPythonTime(a));
- Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
- _date := a;
- DecodeDate( _date, _year, _month, _day );
- DecodeTime( _date, _hour, _min, _sec, _msec );
- Assert.IsTrue(_year = 2002);
- Assert.IsTrue(_month = 12);
- Assert.IsTrue(_day = 30);
- Assert.IsTrue(_hour = 0);
- Assert.IsTrue(_min = 0);
- Assert.IsTrue(_sec = 0);
- Assert.IsTrue(_msec = 0);
- Assert.IsTrue(a.year = 2002);
- Assert.IsTrue(a.month = 12);
- Assert.IsTrue(a.day = 30);
- a := _timeMod.time(22, 15, 38, 827738);
- Assert.IsTrue(not VarIsPythonDateTime(a));
- Assert.IsTrue(not VarIsPythonDate(a));
- Assert.IsTrue(VarIsPythonTime(a));
- Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
- Assert.IsTrue(a.hour = 22);
- Assert.IsTrue(a.minute = 15);
- Assert.IsTrue(a.second = 38);
- Assert.IsTrue(a.microsecond = 827738);
- _date := a;
- DecodeTime( _date, _hour, _min, _sec, _msec );
- Assert.IsTrue(_hour = 22);
- Assert.IsTrue(_min = 15);
- Assert.IsTrue(_sec = 38);
- Assert.IsTrue(_msec = 827738 div 1000);
- a := DatetimeModule.datetime(2002, 12, 30, 22, 15, 38, 827738);
- b := _timeMod.datetime(2002, 12, 30, 22, 16, 38, 827738);
- c := b - a;
- Assert.IsTrue(VarIsPythonDateTimeDelta(c));
- Assert.IsTrue(c.days = 0);
- Assert.IsTrue(c.seconds = 60);
- Assert.IsTrue(c.microseconds = 0);
- _date := c;
- Assert.IsTrue(Trunc(_date)=0);
- DecodeTime( _date, _hour, _min, _sec, _msec );
- Assert.IsTrue(_hour = 0);
- Assert.IsTrue(_min = 1);
- Assert.IsTrue(_sec = 0);
- Assert.IsTrue(_msec = 0);
- c := a - b;
- Assert.IsTrue(VarIsPythonDateTimeDelta(c));
- Assert.IsTrue(c.days = -1);
- Assert.IsTrue(c.seconds = 86340);
- Assert.IsTrue(c.microseconds = 0);
- _date := c;
- Assert.IsTrue(Trunc(_date)=0);
- Assert.IsTrue(_date<0);
- DecodeTime( _date, _hour, _min, _sec, _msec );
- Assert.IsTrue(_hour = 0);
- Assert.IsTrue(_min = 1);
- Assert.IsTrue(_sec = 0);
- Assert.IsTrue(_msec = 0);
- c := a + (b-a);
- Assert.IsTrue(VarIsPythonDateTime(c));
- Assert.IsTrue(c = b);
- Assert.IsTrue(c <> a);
- Assert.IsTrue(a < b);
- Assert.IsTrue(b > a);
- GetPythonEngine.DatetimeConversionMode := dcmToDatetime;
- try
- _date := EncodeDate(2003, 01, 28) + EncodeTime(12, 22, 33, 450);
- a := VarPythonCreate(_date);
- Assert.IsTrue(VarIsPythonDateTime(c));
- _date2 := a;
- DecodeDate( _date, _year, _month, _day );
- DecodeTime( _date, _hour, _min, _sec, _msec );
- DecodeDate( _date2, _year2, _month2, _day2 );
- DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 );
- Assert.IsTrue( _year2 = _year );
- Assert.IsTrue( _month2 = _month );
- Assert.IsTrue( _day2 = _day );
- Assert.IsTrue( _hour2 = _hour );
- Assert.IsTrue( _min2 = _min );
- Assert.IsTrue( _sec2 = _sec );
- Assert.IsTrue( _msec2 = _msec );
- Assert.IsTrue(a.year = 2003);
- Assert.IsTrue(a.month = 01);
- Assert.IsTrue(a.day = 28);
- Assert.IsTrue(a.hour = 12);
- Assert.IsTrue(a.minute = 22);
- Assert.IsTrue(a.second = 33);
- Assert.IsTrue(a.microsecond = 450000);
- finally
- GetPythonEngine.DatetimeConversionMode := dcmToTuple;
- end;
-end;
-procedure TVarPythTest.TestFloats;
-var
- a, b, c : Variant;
- dbl_a, dbl_b, dbl_c : Double;
- int : Integer;
-begin
- // initialize the operands
- dbl_a := 2.5;
- a := VarPythonCreate(dbl_a);
- Assert.IsTrue(VarIsPython(a));
- Assert.IsTrue(VarIsPythonNumber(a));
- Assert.IsTrue(VarIsPythonFloat(a));
- Assert.IsTrue(Double(a) = 2.5);
- dbl_b := 3.2;
- b := VarPythonCreate(dbl_b);
- Assert.IsTrue(VarIsPython(b));
- Assert.IsTrue(VarIsPythonNumber(b));
- Assert.IsTrue(VarIsPythonFloat(b));
- Assert.IsTrue(Double(b) = dbl_b); // note that Assert.IsTrue(Double(b) = 3.2) fails.
- // arithmetic operations
- //----------------------
- // addition
- c := a + b;
- // check result of operation
- Assert.IsTrue( Double(c) = (dbl_a + dbl_b) );
- // check that operation did not change the content of operands.
- Assert.IsTrue(Double(a) = dbl_a);
- Assert.IsTrue(Double(b) = dbl_b);
- // now with a litteral
- c := a + b + 1;
- Assert.IsTrue( Double(c) = (dbl_a+dbl_b+1) );
- c := a + 1 + b;
- Assert.IsTrue( Double(c) = (dbl_a+1+dbl_b) );
- c := 1 + a + b;
- Assert.IsTrue( Double(c) = (1+dbl_a+dbl_b) );
- // substraction
- c := b - a;
- Assert.IsTrue( Double(c) = (dbl_b - dbl_a) );
- // now with a litteral
- c := b - a - 1;
- Assert.IsTrue( Double(c) = (dbl_b-dbl_a-1) );
- c := b - 1 - a;
- Assert.IsTrue( Double(c) = (dbl_b-1-dbl_a) );
- c := 1 - b - a;
- Assert.IsTrue( Double(c) = (1-dbl_b-dbl_a) );
- // multiplication
- c := a * b;
- dbl_c := dbl_a * dbl_b;
- Assert.IsTrue( Double(c) = dbl_c );
- // now with a litteral
- c := a * b * 2;
- dbl_c := dbl_a * dbl_b * 2;
- Assert.IsTrue( Double(c) = dbl_c );
- c := a * 2 * b;
- dbl_c := dbl_a * 2 * dbl_b;
- Assert.IsTrue( Double(c) = dbl_c );
- c := 2 * a * b;
- dbl_c := 2 * dbl_a * dbl_b;
- Assert.IsTrue( Double(c) = dbl_c );
- // division: in Python a division between 2 integers is the same as the integer division
- c := b / a;
- dbl_c := dbl_b / dbl_a;
- Assert.IsTrue( Double(c) = dbl_c );
- // negation
- c := -a;
- Assert.IsTrue( Double(c) = -dbl_a );
- // comparisons
- //------------
- // equal
- c := a = b;
- Assert.IsTrue(c = False);
- c := a = a;
- Assert.IsTrue(c = True);
- Assert.IsTrue( a = dbl_a);
- // not equal
- c := a <> b;
- Assert.IsTrue(c = True);
- Assert.IsTrue( not (c = b) );
- c := a <> a;
- Assert.IsTrue(c = False);
- Assert.IsTrue( a = dbl_a);
- // greater than
- c := a > b; Assert.IsTrue(c = False);
- c := b > a; Assert.IsTrue(c = True);
- Assert.IsTrue( a > (dbl_a-1));
- // greater or equal than
- c := a >= b; Assert.IsTrue(c = False);
- c := b >= a; Assert.IsTrue(c = True);
- c := a >= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a >= dbl_a );
- // less than
- c := a < b; Assert.IsTrue(c = True);
- c := b < a; Assert.IsTrue(c = False);
- Assert.IsTrue( a < dbl_b);
- // less or equal than
- c := a <= b; Assert.IsTrue(c = True);
- c := b <= a; Assert.IsTrue(c = False);
- c := a <= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a <= dbl_a);
- // parenthesis
- c := a * ((a * b) / b);
- dbl_c := dbl_a * ((dbl_a * dbl_b) / dbl_b);
- Assert.IsTrue( c = dbl_c );
- // copy
- c := a;
- Assert.IsTrue( c = a);
- Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
- // casts
- int := a;
- Assert.IsTrue(int = 2);
-end;
-procedure TVarPythTest.TestIntegers;
-var
- a, b, c : Variant;
- big : Int64;
-begin
- // initialize the operands
- a := VarPythonCreate(2);
- Assert.IsTrue(VarIsPython(a));
- Assert.IsTrue(VarIsPythonNumber(a));
- Assert.IsTrue(VarIsPythonInteger(a));
- Assert.IsTrue(Integer(a) = 2);
- b := VarPythonCreate(3);
- Assert.IsTrue(VarIsPython(b));
- Assert.IsTrue(VarIsPythonNumber(b));
- Assert.IsTrue(VarIsPythonInteger(b));
- Assert.IsTrue(Integer(b) = 3);
- // arithmetic operations
- //----------------------
- // addition
- c := a + b;
- // check result of operation
- Assert.IsTrue( Integer(c) = 5 );
- // check that operation did not change the content of operands.
- Assert.IsTrue(Integer(a) = 2);
- Assert.IsTrue(Integer(b) = 3);
- // now with a litteral
- c := a + b + 1;
- Assert.IsTrue( Integer(c) = 6 );
- c := a + 1 + b;
- Assert.IsTrue( Integer(c) = 6 );
- c := 1 + a + b;
- Assert.IsTrue( Integer(c) = 6 );
- // substraction
- c := b - a;
- Assert.IsTrue( Integer(c) = 1 );
- // now with a litteral
- c := b - a - 1;
- Assert.IsTrue( Integer(c) = 0 );
- c := b - 1 - a;
- Assert.IsTrue( Integer(c) = 0 );
- c := 1 - b - a;
- Assert.IsTrue( Integer(c) = -4 );
- // multiplication
- c := a * b;
- Assert.IsTrue( Integer(c) = 6 );
- // now with a litteral
- c := a * b * 2;
- Assert.IsTrue( Integer(c) = 12 );
- c := a * 2 * b;
- Assert.IsTrue( Integer(c) = 12 );
- c := 2 * a * b;
- Assert.IsTrue( Integer(c) = 12 );
- // integer division
- c := b div a;
- Assert.IsTrue( Integer(c) = 1 );
- // division: in Python a division between 2 integers is the same as the integer division
- c := b / a;
- Assert.IsTrue( c = 1.5 );
- Assert.IsTrue( Integer(c) = 2 );
- // modulus
- c := b mod a;
- Assert.IsTrue( Integer(c) = 1 );
- c := BuiltinModule.divmod(b, a); // this returns a tuple whose first item is the result of the division,
- // and second item the modulo.
- if VarIsPythonSequence(c) and (c.Length = 2) then
- begin
- Assert.IsTrue(Integer(c.GetItem(0)) = 1); // division
- Assert.IsTrue(Integer(c.GetItem(1)) = 1); // modulo
- end;
- // power
- c := BuiltinModule.pow(a, b);
- Assert.IsTrue(c = 8);
- // negation
- c := -a;
- Assert.IsTrue( Integer(c) = -2 );
- // logical operations
- //------------------
- // inverse
- c := not a; // in python it would be: c = ~2
- Assert.IsTrue( Integer(c) = -3 );
- // shift left (<<)
- c := a shl b;
- Assert.IsTrue( Integer(c) = 16 );
- c := a shl 1;
- Assert.IsTrue( Integer(c) = 4 );
- // shift right (>>)
- c := a shl b;
- c := c shr b;
- Assert.IsTrue( Integer(c) = Integer(a) );
- c := b shr 1;
- Assert.IsTrue( Integer(c) = 1 );
- // and
- c := a and (a*5);
- Assert.IsTrue( Integer(c) = Integer(a) );
- c := a and 6;
- Assert.IsTrue( Integer(c) = Integer(a) );
- // or
- c := a or b;
- Assert.IsTrue( Integer(c) = 3 );
- c := a or 3;
- Assert.IsTrue( Integer(c) = 3 );
- // xor
- c := a xor b;
- Assert.IsTrue( Integer(c) = 1 );
- c := a xor 3;
- Assert.IsTrue( Integer(c) = 1 );
- // comparisons
- //------------
- // equal
- c := a = b;
- Assert.IsTrue(c = False);
- c := a = a;
- Assert.IsTrue(c = True);
- Assert.IsTrue( a = 2);
- // not equal
- c := a <> b;
- Assert.IsTrue(c = True);
- Assert.IsTrue( not (c = b) );
- c := a <> a;
- Assert.IsTrue(c = False);
- Assert.IsTrue( a = 2);
- // greater than
- c := a > b; Assert.IsTrue(c = False);
- c := b > a; Assert.IsTrue(c = True);
- Assert.IsTrue( a > 1);
- // greater or equal than
- c := a >= b; Assert.IsTrue(c = False);
- c := b >= a; Assert.IsTrue(c = True);
- c := a >= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a >= 2 );
- // less than
- c := a < b; Assert.IsTrue(c = True);
- c := b < a; Assert.IsTrue(c = False);
- Assert.IsTrue( a < 6);
- // less or equal than
- c := a <= b; Assert.IsTrue(c = True);
- c := b <= a; Assert.IsTrue(c = False);
- c := a <= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a <= 2);
- // parenthesis
- c := a * ((a * b) div b);
- Assert.IsTrue( c = a*2 );
- // copy
- c := a;
- Assert.IsTrue( c = a);
- Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
- // test long long (Int64)
- big := Int64(MaxInt)*4;
- b := VarPythonCreate(big);
- Assert.IsTrue( b = big );
- Assert.IsTrue( b <> big+1 );
- Assert.IsTrue( b > MaxInt );
- Assert.IsTrue( MaxInt < b );
- Assert.IsTrue( b+1 = big+1 );
- Assert.IsTrue( b*2 = big*2 );
- Assert.IsTrue( b div 2 = big div 2 );
- c := VarPythonCreate(True);
- Assert.IsTrue(VarIsBool(c));
- Assert.IsTrue(VarIsTrue(c));
- c := VarPythonCreate(False);
- Assert.IsTrue(VarIsBool(c));
- Assert.IsTrue(not VarIsTrue(c));
-end;
-procedure TVarPythTest.TestIterator;
-var
- Module: Variant;
- Count: integer;
-begin
- Count := 0;
- for Module in VarPyIterate(SysModule.modules) do begin
- Count := Count + 1;
- Log(Module);
- end;
- Assert.IsTrue(Count = len(SysModule.modules));
-end;
-procedure TVarPythTest.TestMappings;
-var
- a, b, c, keys, values : Variant;
-begin
- // initialize the operands
- a := NewPythonDict;
- Assert.IsTrue(VarIsPython(a));
- Assert.IsTrue(VarIsPythonMapping(a));
- Assert.IsTrue(VarIsPythonDict(a));
- // There is a bug in D2010 in which Char('a') gets translated to integer parameter
- a.SetItem( string('a'), 1 );
- a.SetItem( string('b'), 2 );
- a.SetItem( string('c'), 3 );
- Assert.IsTrue(a.Length = 3); // this is a special property that does the same as: len(a) in Python
- Assert.IsTrue(a.Length() = 3); // this is a special method that does the same as the special property
- Assert.IsTrue(len(a) = 3);
- Assert.IsTrue(a.GetItem(string('a')) = 1); // this is a special method that lets you do the same as: a[0] in Python
- Assert.IsTrue(a.GetItem(string('b')) = 2);
- Assert.IsTrue(a.GetItem(string('c')) = 3);
-
-
- b := NewPythonDict;
- Assert.IsTrue(VarIsPython(b));
- Assert.IsTrue(VarIsPythonMapping(b));
- Assert.IsTrue(VarIsPythonDict(b));
- b.SetItem( string('d'), 4 );
- b.SetItem( string('e'), 5 );
- b.SetItem( string('f'), 6 );
- Assert.IsTrue(b.Length = 3);
- Assert.IsTrue(b.Length() = 3);
- Assert.IsTrue(len(b) = 3);
- Assert.IsTrue(b.GetItem(string('d')) = 4);
- Assert.IsTrue(b.GetItem(string('e')) = 5);
- Assert.IsTrue(b.GetItem(string('f')) = 6);
-
- // copy
- c := a;
- Assert.IsTrue( c = a);
- Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
-
- // dict methods
- Assert.IsTrue( Boolean(a.__contains__(string('a'))) );
- Assert.IsTrue( not Boolean(a.__contains__('abc')) );
- keys := BuiltinModule.list(a.keys());
- keys.sort();
- Assert.IsTrue( keys = VarPythonCreate(VarArrayOf(['a', 'b', 'c'])));
- values := BuiltinModule.list(a.values());
- values.sort();
- Assert.IsTrue( values = VarPythonCreate(VarArrayOf([1, 2, 3])));
- c := a;
- c.DeleteItem(string('a'));
- Assert.IsTrue( not Boolean(c.__contains__(string('a'))) );
-
- // test string values
- a := NewPythonDict;
- a.SetItem( string('a'), 'Hello');
- a.SetItem( string('b'), 'World!');
- a.SetItem( string('c'), '');
- Assert.IsTrue(a.GetItem(string('a')) = 'Hello');
- Assert.IsTrue(a.GetItem(string('b')) = 'World!');
- Assert.IsTrue(a.GetItem(string('c')) = '');
-end;
-
-procedure TVarPythTest.TestObjects;
-var
- _main, f, a, b, c : Variant;
- val : Integer;
- _str : String;
-const
- Script =
- 'class XYZ(object):' + sLineBreak +
- ' pass' + sLineBreak +
- '' + sLineBreak +
- 'class Foo:' + sLineBreak +
- ' def __init__(Self, Value=0):' + sLineBreak +
- ' Self.Value = Value' + sLineBreak +
- ' def __del__(Self):' + sLineBreak +
- ' print("delete", Self)' + sLineBreak +
- ' def __add__(self, other):' + sLineBreak +
- ' return Foo(self.Value + other.Value)' + sLineBreak +
- ' def Inc(Self, AValue = 1):' + sLineBreak +
- ' Self.Value = Self.Value + AValue' + sLineBreak +
- ' def GetSelf(Self):' + sLineBreak +
- ' return Self' + sLineBreak +
- ' def GetValue(Self):' + sLineBreak +
- ' return Self.Value' + sLineBreak +
- ' def SetABC(Self, A, B, C):' + sLineBreak +
- ' Self.A = A' + sLineBreak +
- ' Self.B = B' + sLineBreak +
- ' Self.C = C' + sLineBreak +
- ' def Add(Self, AFooInst):' + sLineBreak +
- ' Self.Value = Self.Value + AFooInst.Value' + sLineBreak +
- 'class Bar(Foo):' + sLineBreak +
- ' def Inc(Self, AValue = 1):' + sLineBreak +
- ' Self.Value = Self.Value - AValue' + sLineBreak +
- 'def Add(a, b):' + sLineBreak +
- ' return a + b' + sLineBreak +
- 'def MakeList(a, b, c, d):' + sLineBreak +
- ' return [a, b, c, d]' + sLineBreak +
- '' + sLineBreak +
- 'f = Foo()' + sLineBreak +
- 'print("Created", f)' + sLineBreak +
- 'f.Inc()' + sLineBreak +
- 'f.Inc(2)' + sLineBreak +
- 'b = Bar()' + sLineBreak +
- 'b.Inc()' + sLineBreak +
- 'b.Inc(2)';
-
-begin
- FPythonEngine.ExecString(Script);
- _main := MainModule;
- Assert.IsTrue( VarIsPythonModule(_main) );
- Assert.IsTrue( VarIsPythonModule(SysModule) );
- Assert.IsTrue( Import('sys').version = SysModule.version );
- Log(SysModule.version);
- Assert.IsTrue( Boolean(SysModule.modules.Contains(GetPythonEngine.ExecModule)) ); // if __main__ in sys.modules
- Assert.IsTrue( VarIsSameType(_main, SysModule) );
- Assert.IsTrue( _type(_main).__name__ = 'module');
- Assert.IsTrue( BuiltinModule.type(_main).__name__ = 'module');
-
- Assert.IsTrue( VarIsPythonClass(_main.Foo) );
- Assert.IsTrue( VarIsPythonClass(_main.Bar) );
- Assert.IsTrue( VarIsPythonClass(_main.XYZ) );
- Assert.IsTrue( not VarIsPythonClass(_main.Foo.__add__) );
- Assert.IsTrue( not VarIsPythonClass(_main.f) );
- Assert.IsTrue( VarIsPythonCallable(_main.Foo) );
- Assert.IsTrue( VarIsPythonCallable(_main.Foo) );
- Assert.IsTrue( VarIsTrue(BuiltinModule.callable(_main.Foo)) );
- Assert.IsTrue( VarIsSame(_main.f.__class__, _main.Foo) );
- Assert.IsTrue( VarIsPythonMethod(_main.f.Inc) );
- Assert.IsTrue( VarIsPythonCallable(_main.f.Inc) );
- Assert.IsTrue( VarIsTrue(BuiltinModule.callable(_main.f.Inc)) );
- Assert.IsTrue( VarIsPythonFunction(_main.Add) );
- Assert.IsTrue( VarIsPythonCallable(_main.Add) );
- Assert.IsTrue( VarIsInstanceOf(_main.f, _main.Foo) );
- Assert.IsTrue( VarIsTrue(BuiltinModule.isinstance(_main.f, _main.Foo)) );
- Assert.IsTrue( VarIsSubclassOf(_main.Bar, _main.Foo) );
- Assert.IsTrue( VarIsTrue(BuiltinModule.issubclass(_main.Bar, _main.Foo)) );
- Assert.IsTrue( not VarIsSubclassOf(_main.Foo, _main.Bar) );
- Assert.IsTrue( VarIsInstanceOf(_main.b, _main.Foo) );
- Assert.IsTrue( not VarIsInstanceOf(_main.f, _main.Bar) );
- Assert.IsTrue( VarIsTrue( BuiltinModule.vars(_main).__contains__(string('f')) ) );
- Assert.IsTrue( VarIsTrue( BuiltinModule.dir(_main).Contains(string('f')) ) );
-
- f := _main.Foo(); // new instance of class Foo
- Log('Instanciate class Foo: ' + f);
- f.Inc(); // call a method without any arg, because there's a default arg.
- f.Inc(2); // call a method with one arg, overriding the default arg.
- Assert.IsTrue( VarIsPythonNumber(f.Value) );
- Assert.IsTrue( VarIsPythonInteger(f.Value) );
- Assert.IsTrue( f.Value = _main.f.Value ); // compare the result with what we did in the script
- Assert.IsTrue( f.GetValue() = _main.f.GetValue() ); // compare the result with what we did in the script
- Assert.IsTrue( VarIsPython( f.GetSelf() ) );
- Assert.IsTrue( VarIsSame( f.GetSelf(), f ) );
- Assert.IsTrue( BuiltinModule.getattr(f, 'Value') = f.Value );
- // python (+) operator overloading
- a := _main.Foo(10);
- b := _main.Foo(5);
- c := a + b;
- Assert.IsTrue(a.Value = 10);
- Assert.IsTrue(b.Value = 5);
- Assert.IsTrue(c.Value = 15);
- Log('Test -> a, b, c : ' + a.Value + ', ' + b.Value + ', ' + c.Value);
- // cascading calls
- Assert.IsTrue( f.GetSelf().GetSelf().GetSelf().GetSelf().GetValue() = _main.f.GetValue() );
- Assert.IsTrue( Boolean(f.__dict__.__contains__('Value')) );
- Assert.IsTrue( VarIsTrue( BuiltinModule.hasattr(f, 'Value') ) );
- _str := 'Value';
- Assert.IsTrue( Boolean(f.__dict__.__contains__(_str)) ); // check with a string var
- Assert.IsTrue( Boolean( BuiltinModule.hasattr(f, _str) ) );
- val := f.Value;
- f.Add(f); // passing itself as an argument
- Assert.IsTrue( f.Value = val*2 );
- // check param order
- f.SetABC(1, 2, 3);
- Assert.IsTrue(f.A = 1);
- Assert.IsTrue(f.B = 2);
- Assert.IsTrue(f.C = 3);
- // add a property to an instance
- f.Z := 99;
- Assert.IsTrue(f.Z = 99);
- // add a var to a module
- _main.Z := 99;
- Assert.IsTrue(_main.Z = 99);
- // check none
- Assert.IsTrue( VarIsNone(None) );
- Assert.IsTrue( VarIsNone(VarPythonCreate([1, Null, 3]).GetItem(1)) ); // Null is casted to None
- Assert.IsTrue( VarIsNone(VarPythonCreate([1, None, 3]).GetItem(1)) );
- Assert.IsTrue( VarIsNone(f.Inc()) );
- Assert.IsTrue( f.Inc() = None );
- Assert.IsTrue( not Boolean(None) ); // if not None:
- Assert.IsTrue( not VarIsTrue(None) ); // if not None:
- Assert.IsTrue( Boolean(f) ); // if f:
- Assert.IsTrue( VarIsTrue(f) ); // if f:
-
- // call a function
- Assert.IsTrue( _main.Add(2, 2) = 4 );
- // call a function with a mix of regular parameters and named parameters
- f := _main.MakeList(1, 2, 3, 4);
- Assert.IsTrue(VarIsPythonList(f));
- Assert.IsTrue(f.Length = 4);
- Assert.IsTrue(f.GetItem(0) = 1);
- Assert.IsTrue(f.GetItem(1) = 2);
- Assert.IsTrue(f.GetItem(2) = 3);
- Assert.IsTrue(f.GetItem(3) = 4);
- f := _main.MakeList(1, d:=3, c:=4, b:=2);
- Assert.IsTrue(VarIsPythonList(f));
- Assert.IsTrue(f.Length = 4);
- Assert.IsTrue(f.GetItem(0) = 1);
- Assert.IsTrue(f.GetItem(1) = 2);
- Assert.IsTrue(f.GetItem(2) = 4);
- Assert.IsTrue(f.GetItem(3) = 3);
- f := _main.MakeList(1, 2, d:= 3, c:=4);
- Assert.IsTrue(VarIsPythonList(f));
- Assert.IsTrue(f.Length = 4);
- Assert.IsTrue(f.GetItem(0) = 1);
- Assert.IsTrue(f.GetItem(1) = 2);
- Assert.IsTrue(f.GetItem(2) = 4);
- Assert.IsTrue(f.GetItem(3) = 3);
- f := _main.MakeList(1, 2, 3, d:=4);
- Assert.IsTrue(VarIsPythonList(f));
- Assert.IsTrue(f.Length = 4);
- Assert.IsTrue(f.GetItem(0) = 1);
- Assert.IsTrue(f.GetItem(1) = 2);
- Assert.IsTrue(f.GetItem(2) = 3);
- Assert.IsTrue(f.GetItem(3) = 4);
- f := _main.MakeList(b:=1, a:=2, d:= 3, c:=4);
- Assert.IsTrue(VarIsPythonList(f));
- Assert.IsTrue(f.Length = 4);
- Assert.IsTrue(f.GetItem(0) = 2);
- Assert.IsTrue(f.GetItem(1) = 1);
- Assert.IsTrue(f.GetItem(2) = 4);
- Assert.IsTrue(f.GetItem(3) = 3);
-end;
-procedure TVarPythTest.TestSequences;
-var
- a, b, c : Variant;
- iter : Variant;
- cpt : Integer;
-begin
- // initialize the operands
- // you can either use the overloaded function with an array of const
- // or use the VarArrayOf function that returns an array of variants that will
- // be casted to a Python list.
- a := VarPythonCreate([1, 2, 3]);
- Assert.IsTrue(VarIsPython(a));
- Assert.IsTrue(VarIsPythonSequence(a));
- Assert.IsTrue(VarIsPythonList(a));
- Assert.IsTrue(a.Length = 3); // this is a special property that does the same as: len(a) in Python
- Assert.IsTrue(a.Length() = 3); // this is a special method that does the same as the special property
- Assert.IsTrue(len(a) = 3);
- Assert.IsTrue(a.GetItem(0) = 1); // this is a special method that lets you do the same as: a[0] in Python
- Assert.IsTrue(a.GetItem(1) = 2);
- Assert.IsTrue(a.GetItem(2) = 3);
- Assert.IsTrue(string(a) = '[1, 2, 3]');
- // indexed access using brackets when the sequence is a property of an object (module, instance...)
- MainModule.a := VarPythonCreate([1, 2, 3]);
- Assert.IsTrue(MainModule.a[1] = 2);
-
- b := VarPythonCreate(VarArrayOf([4, 5, 6]));
- Assert.IsTrue(VarIsPython(b));
- Assert.IsTrue(VarIsPythonSequence(b));
- Assert.IsTrue(VarIsPythonList(b));
- Assert.IsTrue(b.Length = 3);
- Assert.IsTrue(b.Length() = 3);
- Assert.IsTrue(len(b) = 3);
- Assert.IsTrue(b.GetItem(0) = 4);
- Assert.IsTrue(b.GetItem(1) = 5);
- Assert.IsTrue(b.GetItem(2) = 6);
- Assert.IsTrue(string(b) = '[4, 5, 6]');
- // concatenation
- c := a + b;
- // check result of operation
- Assert.IsTrue(string(c) = '[1, 2, 3, 4, 5, 6]');
- // check that operation did not change the content of operands.
- Assert.IsTrue(string(a) = '[1, 2, 3]');
- Assert.IsTrue(string(b) = '[4, 5, 6]');
- // now with a litteral: note that with D6 SP1, we can't concatenate a custom variant with an var array of variants
- c := a + b + VarPythonCreate(['Hello', 'World!', 3.14]);
- Assert.IsTrue( string(c) = '[1, 2, 3, 4, 5, 6, ''Hello'', ''World!'', 3.14]' );
- c := a + VarPythonCreate(['Hello', 'World!', 3.14]) + b;
- Assert.IsTrue( string(c) = '[1, 2, 3, ''Hello'', ''World!'', 3.14, 4, 5, 6]' );
- c := VarPythonCreate(['Hello', 'World!', 3.14]) + a + b;
- Assert.IsTrue( string(c) = '[''Hello'', ''World!'', 3.14, 1, 2, 3, 4, 5, 6]' );
-
- // multiplication
- c := a * 3; // in Python the multiplication of sequence concatenates n times the sequence
- Assert.IsTrue( string(c) = '[1, 2, 3, 1, 2, 3, 1, 2, 3]' );
-
- // comparisons
- //------------
-
- // equal
- c := a = b;
- Assert.IsTrue(c = False);
- c := a = a;
- Assert.IsTrue(c = True);
- Assert.IsTrue( string(a) = '[1, 2, 3]');
-
- // not equal
- c := a <> b;
- Assert.IsTrue(c = True);
- Assert.IsTrue( not (c = b) );
- c := a <> a;
- Assert.IsTrue(c = False);
- Assert.IsTrue( string(a) = '[1, 2, 3]');
-
- // greater than
- c := a > b; Assert.IsTrue(c = False);
- c := b > a; Assert.IsTrue(c = True);
- Assert.IsTrue( string(a) > '[1, 1, 1]');
-
- // greater or equal than
- c := a >= b; Assert.IsTrue(c = False);
- c := b >= a; Assert.IsTrue(c = True);
- c := a >= a; Assert.IsTrue(c = True);
- Assert.IsTrue( string(a) >= '[1, 2, 3]' );
-
- // less than
- c := a < b; Assert.IsTrue(c = True);
- c := b < a; Assert.IsTrue(c = False);
- Assert.IsTrue( string(a) < '[4, 4, 4]');
-
- // less or equal than
- c := a <= b; Assert.IsTrue(c = True);
- c := b <= a; Assert.IsTrue(c = False);
- c := a <= a; Assert.IsTrue(c = True);
- Assert.IsTrue( string(a) <= '[1, 2, 3]');
-
- // copy
- c := a;
- Assert.IsTrue( c = a);
- Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
-
- // sequence methods:
- c := b + a;
- c.sort(); // note that you must you the parenthesis to distinguish the call between a method or a property.
- Assert.IsTrue( c = (a+b) );
-
- c := NewPythonList; // facility for building sequences
- Assert.IsTrue( not VarIsTrue(c) ); // c is false because it's an empty collection
- c.append(1);
- c.append(2);
- c.append(3);
- Assert.IsTrue( VarIsTrue(c) ); // c is true because it's not an empty collection
- Assert.IsTrue(c = a);
- Assert.IsTrue( c.pop() = 3 );
- Assert.IsTrue( string(c) = '[1, 2]');
-
- c := NewPythonList(3); // facility for building sequences
- c.SetItem(0, 1);
- c.SetItem(1, 2);
- c.SetItem(2, 3);
- Assert.IsTrue(c = a);
- c.DeleteItem(1);
- Assert.IsTrue(c = VarPythonCreate([1,3]));
-
- Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, 3) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:3]
- Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, Ellipsis) = VarPythonCreate([2,3,4])); // same as x = [1,2,3,4]; x[1:]
- Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, -1) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:-1]
- c := VarPythonCreate([1,2,3,4]);
- c.SetSlice(1, 3, VarPythonCreate([7, 8, 9]));
- Assert.IsTrue( c = VarPythonCreate([1, 7, 8, 9, 4]) );
- Assert.IsTrue( Boolean(c.Contains( 7 )) ); // same as 7 in c
- Assert.IsTrue( not Boolean(c.Contains( 77 )) );
- c.DelSlice(1,3);
- Assert.IsTrue( c = VarPythonCreate([1,9,4]) );
-
- c := VarPythonCreate([1, 2, 3, 4], stTuple); // test a tuple
- Assert.IsTrue( VarIsPythonTuple(c) );
- Assert.IsTrue( VarIsPythonSequence(c) );
- Assert.IsTrue( c.GetItem(1) = 2 );
- Assert.IsTrue( c.Length = 4 );
- c := NewPythonTuple(3);
- c.SetItem(0, 1);
- c.SetItem(1, 2);
- c.SetItem(2, 3);
- Assert.IsTrue( VarIsPythonTuple(c) );
- Assert.IsTrue( VarIsPythonSequence(c) );
- Assert.IsTrue( c.GetItem(1) = 2 );
- Assert.IsTrue( c.Length = 3 );
-
- // test iterator
- iter := BuiltinModule.iter(VarPythonCreate([1, 2, 3, 4], stTuple));
- Assert.IsTrue(VarIsPythonIterator(iter));
- Assert.IsTrue(iter.__next__() = 1);
- Assert.IsTrue(iter.__next__() = 2);
- Assert.IsTrue(iter.__next__() = 3);
- Assert.IsTrue(iter.__next__() = 4);
- try
- iter.__next__();
- except
- on E: EPyStopIteration do
- begin
- Assert.IsTrue(True); //Ok.
- end
- else
- Assert.IsTrue(False, 'expected stop exception');
- end;
- cpt := 0;
- iter := VarPyth.iter(VarPythonCreate([1, 2, 3, 4], stTuple));
- Assert.IsTrue(VarIsPythonIterator(iter));
- try
- while True do
- begin
- a := iter.__next__();
- Inc(cpt);
- Assert.IsTrue(a = cpt);
- end;
- except
- on E: EPyStopIteration do
- begin
- Assert.IsTrue(True); //Ok.
- end
- else
- Assert.IsTrue(False, 'expected stop exception');
- end;
- Assert.IsTrue(cpt = 4);
-end;
-procedure TVarPythTest.TestStrings;
-var
- a, b, c : Variant;
- w : WideString;
- _obj : PPyObject;
-begin
- // initialize the operands
- a := VarPythonCreate('abc');
- Assert.IsTrue(VarIsPython(a));
- Assert.IsTrue(VarIsPythonString(a));
- Assert.IsTrue(string(a) = 'abc');
- b := VarPythonCreate('def');
- Assert.IsTrue(VarIsPython(b));
- Assert.IsTrue(VarIsPythonString(b));
- Assert.IsTrue(string(b) = 'def');
- // concatenation
- c := a + b;
- // check result of operation
- Assert.IsTrue( string(c) = 'abcdef' );
- // check that operation did not change the content of operands.
- Assert.IsTrue(string(a) = 'abc');
- Assert.IsTrue(string(b) = 'def');
- // now with a litteral
- c := a + b + '!';
- Assert.IsTrue( string(c) = 'abcdef!' );
- c := a + '!' + b;
- Assert.IsTrue( string(c) = 'abc!def' );
- c := '!' + a + b;
- Assert.IsTrue( string(c) = '!abcdef' );
- // multiplication
- c := a * 3; // in Python the multiplication of string concatenates n times the string
- Assert.IsTrue( string(c) = 'abcabcabc' );
- // comparisons
- //------------
- // equal
- c := a = b;
- Assert.IsTrue(c = False);
- c := a = a;
- Assert.IsTrue(c = True);
- Assert.IsTrue( a = 'abc');
- // not equal
- c := a <> b;
- Assert.IsTrue(c = True);
- Assert.IsTrue( not (c = b) );
- c := a <> a;
- Assert.IsTrue(c = False);
- Assert.IsTrue( a = 'abc');
- // greater than
- c := a > b; Assert.IsTrue(c = False);
- c := b > a; Assert.IsTrue(c = True);
- Assert.IsTrue( a > 'aaa');
- // greater or equal than
- c := a >= b; Assert.IsTrue(c = False);
- c := b >= a; Assert.IsTrue(c = True);
- c := a >= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a >= 'abc' );
- // less than
- c := a < b; Assert.IsTrue(c = True);
- c := b < a; Assert.IsTrue(c = False);
- Assert.IsTrue( a < 'bbb');
- // less or equal than
- c := a <= b; Assert.IsTrue(c = True);
- c := b <= a; Assert.IsTrue(c = False);
- c := a <= a; Assert.IsTrue(c = True);
- Assert.IsTrue( a <= 'abc');
- // copy
- c := a;
- Assert.IsTrue( c = a);
- Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
- // empty strings
- a := VarPythonCreate('');
- Assert.IsTrue(a.length = 0);
- Assert.IsTrue(a = '');
- Assert.IsTrue(string(a) = '');
- // Unicode strings
- b := VarPythonEval( 'u"Hello world!"' );
- Assert.IsTrue( VarIsPythonUnicode(b) );
- w := FPythonEngine.PyUnicodeAsString(ExtractPythonObjectFrom(b));
- Assert.IsTrue( w = 'Hello world!');
- Assert.IsTrue( b = 'Hello world!');
- Assert.IsTrue( b <> a );
- _obj := FPythonEngine.PyUnicodeFromString(w);
- try
- c := VarPythonCreate( _obj );
- finally
- FPythonEngine.Py_XDecRef(_obj);
- end;
- Assert.IsTrue(b = c);
- Assert.IsTrue(c = w);
- Assert.IsTrue( c = 'Hello world!');
- w := b;
- Assert.IsTrue( b = w);
- Assert.IsTrue( w = 'Hello world!');
- Assert.IsTrue( Length(w) = 12 );
- Assert.IsTrue( Length(w) = b.Length() );
- c := FPythonEngine.PyObjectAsVariant(ExtractPythonObjectFrom(b));
- Assert.IsTrue( c = b );
- Assert.IsTrue( c = w );
- Assert.IsTrue( c = 'Hello world!');
- Assert.IsTrue( VarType(c) and VarTypeMask = varUString );
- c := VarPythonCreate(w);
- Assert.IsTrue( c = 'Hello world!');
- Assert.IsTrue( c = w );
- c := VarPythonCreate([w]);
- Assert.IsTrue( VarIsPythonUnicode(c.GetItem(0)) );
- Assert.IsTrue( c.GetItem(0) = 'Hello world!');
- Assert.IsTrue( c.GetItem(0) = w );
- c := w;
- b := VarPythonCreate(c);
- Assert.IsTrue( VarIsPythonUnicode(b) );
- Assert.IsTrue( b = c );
- Assert.IsTrue( b = w );
- // empty strings
- a := VarPythonEval( 'u""' );
- Assert.IsTrue(a.length = 0);
- Assert.IsTrue(a = '');
- Assert.IsTrue(string(a) = '');
- Assert.IsTrue(WideString(a) = '');
-end;
-
-initialization
- TDUnitX.RegisterTestFixture(TVarPythTest);
-
-end.
+(**************************************************************************)
+(* *)
+(* Module: Unit 'VarPythTest' Copyright (c) 2021 *)
+(* *)
+(* Lucas Moura Belo - lmbelo *)
+(* lucas.belo@live.com *)
+(* BH, Brazil *)
+(* *)
+(* PyScripter *)
+(* e-mail: pyscripter@gmail.com *)
+(* *)
+(* Project pages: https://github.com/Embarcadero/python4delphi *)
+(* https://github.com/pyscripter/python4delphi *)
+(**************************************************************************)
+(* Functionality: Test unit for variants *)
+(* *)
+(* *)
+(**************************************************************************)
+(* This source code is distributed with no WARRANTY, for no reason or use.*)
+(* Everyone is allowed to use and change this code free for his own tasks *)
+(* and projects, as long as this header and its copyright text is intact. *)
+(* For changed versions of this code, which are public distributed the *)
+(* following additional conditions have to be fullfilled: *)
+(* 1) The header has to contain a comment on the change and the author of *)
+(* it. *)
+(* 2) A copy of the changed source has to be sent to the above E-Mail *)
+(* address or my then valid address, if this is possible to the *)
+(* author. *)
+(* The second condition has the target to maintain an up to date central *)
+(* version of the component. If this condition is not acceptable for *)
+(* confidential or legal reasons, everyone is free to derive a component *)
+(* or to generate a diff file to my or other original sources. *)
+(**************************************************************************)
+
+unit VarPythTest;
+
+interface
+
+uses
+ DUnitX.TestFramework,
+ PythonEngine,
+ PythonLoad;
+
+type
+ {$M+}
+ [TestFixture]
+ TVarPythTest = class
+ private
+ FPythonEngine: TPythonEngine;
+ public
+ [SetupFixture]
+ procedure SetupFixture;
+ [TearDownFixture]
+ procedure TearDownFixture;
+ [Test]
+ procedure TestIterator;
+ [Test]
+ procedure TestIntegers;
+ [Test]
+ procedure TestFloats;
+ [Test]
+ procedure TestStrings;
+ [Test]
+ procedure TestSequences;
+ [Test]
+ procedure TestMappings;
+ [Test]
+ procedure TestDates;
+ [Test]
+ procedure TestObjects;
+ end;
+
+implementation
+
+uses
+ SysUtils, StrUtils,
+ Variants,
+ VarPyth;
+
+{ TVarPythTest }
+
+procedure TVarPythTest.SetupFixture;
+begin
+ FPythonEngine := TPythonEngine.Create(nil);
+ FPythonEngine.Name := 'PythonEngine';
+ TPythonLoad.Configure(FPythonEngine);
+ FPythonEngine.LoadDll;
+end;
+procedure TVarPythTest.TearDownFixture;
+begin
+ FPythonEngine.Free();
+end;
+procedure TVarPythTest.TestDates;
+var
+ a, b, _timeMod : Variant;
+ c : Variant;
+ _date, _date2 : TDateTime;
+ _year, _month, _day : Word;
+ _year2, _month2, _day2 : Word;
+ _hour, _min, _sec, _msec : Word;
+ _hour2, _min2, _sec2, _msec2 : Word;
+begin
+ _timeMod := Import('time'); // get the time module of Python
+ _date := Now;
+ DecodeDate( _date, _year, _month, _day );
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ b := _timeMod.localtime(_timeMod.time()); // same as Now in Delphi
+ a := VarPythonCreate(_date);
+ Assert.IsTrue( a.Length = 9 );
+ Assert.IsTrue( a.GetItem(0) = _year );
+ Assert.IsTrue( a.GetItem(1) = _month );
+ Assert.IsTrue( a.GetItem(2) = _day );
+ Assert.IsTrue( a.GetItem(3) = _hour );
+ Assert.IsTrue( a.GetItem(4) = _min );
+ Assert.IsTrue( a.GetItem(5) = _sec );
+ Assert.IsTrue( b.Length = 9 );
+ Assert.IsTrue( b.GetItem(0) = a.GetItem(0) );
+ Assert.IsTrue( b.GetItem(1) = a.GetItem(1) );
+ Assert.IsTrue( b.GetItem(2) = a.GetItem(2) );
+ Assert.IsTrue( b.GetItem(3) = a.GetItem(3) );
+ Assert.IsTrue( b.GetItem(4) = a.GetItem(4) );
+ Assert.IsTrue( b.GetItem(5) = a.GetItem(5) );
+ Assert.IsTrue( b.GetItem(6) = a.GetItem(6) );
+ Assert.IsTrue( b.GetItem(7) = a.GetItem(7) );
+ // don't test the 9th item of the tuple, because it's the daylight saving,
+ // and it's not computed by the Python for Delphi.
+ //Assert.IsTrue( b.GetItem(8) = a.GetItem(8) );
+ _date2 := b;
+ DecodeDate( _date2, _year2, _month2, _day2 );
+ DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 );
+ Assert.IsTrue( _year2 = _year );
+ Assert.IsTrue( _month2 = _month );
+ Assert.IsTrue( _day2 = _day );
+ Assert.IsTrue( _hour2 = _hour );
+ Assert.IsTrue( _min2 = _min );
+ Assert.IsTrue( _sec2 = _sec );
+ // test new datetime module
+ _timeMod := Import('datetime'); // get the datetime module of Python
+ //or _timeMod := DatetimeModule; // get the datetime module of Python
+ a := _timeMod.datetime(2002, 12, 30, 22, 15, 38, 827738);
+ Assert.IsTrue(VarIsPythonDateTime(a));
+ Assert.IsTrue(VarIsPythonDate(a));
+ Assert.IsTrue(not VarIsPythonTime(a));
+ Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
+ Assert.IsTrue(a.year = 2002);
+ Assert.IsTrue(a.month = 12);
+ Assert.IsTrue(a.day = 30);
+ Assert.IsTrue(a.hour = 22);
+ Assert.IsTrue(a.minute = 15);
+ Assert.IsTrue(a.second = 38);
+ Assert.IsTrue(a.microsecond = 827738);
+ _date := a;
+ DecodeDate( _date, _year, _month, _day );
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ Assert.IsTrue(_year = 2002);
+ Assert.IsTrue(_month = 12);
+ Assert.IsTrue(_day = 30);
+ Assert.IsTrue(_hour = 22);
+ Assert.IsTrue(_min = 15);
+ Assert.IsTrue(_sec = 38);
+ Assert.IsTrue(_msec = 827738 div 1000);
+ a := _timeMod.date(2002, 12, 30);
+ Assert.IsTrue(not VarIsPythonDateTime(a));
+ Assert.IsTrue(VarIsPythonDate(a));
+ Assert.IsTrue(not VarIsPythonTime(a));
+ Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
+ _date := a;
+ DecodeDate( _date, _year, _month, _day );
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ Assert.IsTrue(_year = 2002);
+ Assert.IsTrue(_month = 12);
+ Assert.IsTrue(_day = 30);
+ Assert.IsTrue(_hour = 0);
+ Assert.IsTrue(_min = 0);
+ Assert.IsTrue(_sec = 0);
+ Assert.IsTrue(_msec = 0);
+ Assert.IsTrue(a.year = 2002);
+ Assert.IsTrue(a.month = 12);
+ Assert.IsTrue(a.day = 30);
+ a := _timeMod.time(22, 15, 38, 827738);
+ Assert.IsTrue(not VarIsPythonDateTime(a));
+ Assert.IsTrue(not VarIsPythonDate(a));
+ Assert.IsTrue(VarIsPythonTime(a));
+ Assert.IsTrue(not VarIsPythonDateTimeDelta(a));
+ Assert.IsTrue(a.hour = 22);
+ Assert.IsTrue(a.minute = 15);
+ Assert.IsTrue(a.second = 38);
+ Assert.IsTrue(a.microsecond = 827738);
+ _date := a;
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ Assert.IsTrue(_hour = 22);
+ Assert.IsTrue(_min = 15);
+ Assert.IsTrue(_sec = 38);
+ Assert.IsTrue(_msec = 827738 div 1000);
+ a := DatetimeModule.datetime(2002, 12, 30, 22, 15, 38, 827738);
+ b := _timeMod.datetime(2002, 12, 30, 22, 16, 38, 827738);
+ c := b - a;
+ Assert.IsTrue(VarIsPythonDateTimeDelta(c));
+ Assert.IsTrue(c.days = 0);
+ Assert.IsTrue(c.seconds = 60);
+ Assert.IsTrue(c.microseconds = 0);
+ _date := c;
+ Assert.IsTrue(Trunc(_date)=0);
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ Assert.IsTrue(_hour = 0);
+ Assert.IsTrue(_min = 1);
+ Assert.IsTrue(_sec = 0);
+ Assert.IsTrue(_msec = 0);
+ c := a - b;
+ Assert.IsTrue(VarIsPythonDateTimeDelta(c));
+ Assert.IsTrue(c.days = -1);
+ Assert.IsTrue(c.seconds = 86340);
+ Assert.IsTrue(c.microseconds = 0);
+ _date := c;
+ Assert.IsTrue(Trunc(_date)=0);
+ Assert.IsTrue(_date<0);
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ Assert.IsTrue(_hour = 0);
+ Assert.IsTrue(_min = 1);
+ Assert.IsTrue(_sec = 0);
+ Assert.IsTrue(_msec = 0);
+ c := a + (b-a);
+ Assert.IsTrue(VarIsPythonDateTime(c));
+ Assert.IsTrue(c = b);
+ Assert.IsTrue(c <> a);
+ Assert.IsTrue(a < b);
+ Assert.IsTrue(b > a);
+ GetPythonEngine.DatetimeConversionMode := dcmToDatetime;
+ try
+ _date := EncodeDate(2003, 01, 28) + EncodeTime(12, 22, 33, 450);
+ a := VarPythonCreate(_date);
+ Assert.IsTrue(VarIsPythonDateTime(c));
+ _date2 := a;
+ DecodeDate( _date, _year, _month, _day );
+ DecodeTime( _date, _hour, _min, _sec, _msec );
+ DecodeDate( _date2, _year2, _month2, _day2 );
+ DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 );
+ Assert.IsTrue( _year2 = _year );
+ Assert.IsTrue( _month2 = _month );
+ Assert.IsTrue( _day2 = _day );
+ Assert.IsTrue( _hour2 = _hour );
+ Assert.IsTrue( _min2 = _min );
+ Assert.IsTrue( _sec2 = _sec );
+ Assert.IsTrue( _msec2 = _msec );
+ Assert.IsTrue(a.year = 2003);
+ Assert.IsTrue(a.month = 01);
+ Assert.IsTrue(a.day = 28);
+ Assert.IsTrue(a.hour = 12);
+ Assert.IsTrue(a.minute = 22);
+ Assert.IsTrue(a.second = 33);
+ Assert.IsTrue(a.microsecond = 450000);
+ finally
+ GetPythonEngine.DatetimeConversionMode := dcmToTuple;
+ end;
+end;
+procedure TVarPythTest.TestFloats;
+var
+ a, b, c : Variant;
+ dbl_a, dbl_b, dbl_c : Double;
+ int : Integer;
+begin
+ // initialize the operands
+ dbl_a := 2.5;
+ a := VarPythonCreate(dbl_a);
+ Assert.IsTrue(VarIsPython(a));
+ Assert.IsTrue(VarIsPythonNumber(a));
+ Assert.IsTrue(VarIsPythonFloat(a));
+ Assert.IsTrue(Double(a) = 2.5);
+ dbl_b := 3.2;
+ b := VarPythonCreate(dbl_b);
+ Assert.IsTrue(VarIsPython(b));
+ Assert.IsTrue(VarIsPythonNumber(b));
+ Assert.IsTrue(VarIsPythonFloat(b));
+ Assert.IsTrue(Double(b) = dbl_b); // note that Assert.IsTrue(Double(b) = 3.2) fails.
+ // arithmetic operations
+ //----------------------
+ // addition
+ c := a + b;
+ // check result of operation
+ Assert.IsTrue( Double(c) = (dbl_a + dbl_b) );
+ // check that operation did not change the content of operands.
+ Assert.IsTrue(Double(a) = dbl_a);
+ Assert.IsTrue(Double(b) = dbl_b);
+ // now with a litteral
+ c := a + b + 1;
+ Assert.IsTrue( Double(c) = (dbl_a+dbl_b+1) );
+ c := a + 1 + b;
+ Assert.IsTrue( Double(c) = (dbl_a+1+dbl_b) );
+ c := 1 + a + b;
+ Assert.IsTrue( Double(c) = (1+dbl_a+dbl_b) );
+ // substraction
+ c := b - a;
+ Assert.IsTrue( Double(c) = (dbl_b - dbl_a) );
+ // now with a litteral
+ c := b - a - 1;
+ Assert.IsTrue( Double(c) = (dbl_b-dbl_a-1) );
+ c := b - 1 - a;
+ Assert.IsTrue( Double(c) = (dbl_b-1-dbl_a) );
+ c := 1 - b - a;
+ Assert.IsTrue( Double(c) = (1-dbl_b-dbl_a) );
+ // multiplication
+ c := a * b;
+ dbl_c := dbl_a * dbl_b;
+ Assert.IsTrue( Double(c) = dbl_c );
+ // now with a litteral
+ c := a * b * 2;
+ dbl_c := dbl_a * dbl_b * 2;
+ Assert.IsTrue( Double(c) = dbl_c );
+ c := a * 2 * b;
+ dbl_c := dbl_a * 2 * dbl_b;
+ Assert.IsTrue( Double(c) = dbl_c );
+ c := 2 * a * b;
+ dbl_c := 2 * dbl_a * dbl_b;
+ Assert.IsTrue( Double(c) = dbl_c );
+ // division: in Python a division between 2 integers is the same as the integer division
+ c := b / a;
+ dbl_c := dbl_b / dbl_a;
+ Assert.IsTrue( Double(c) = dbl_c );
+ // negation
+ c := -a;
+ Assert.IsTrue( Double(c) = -dbl_a );
+ // comparisons
+ //------------
+ // equal
+ c := a = b;
+ Assert.IsTrue(c = False);
+ c := a = a;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( a = dbl_a);
+ // not equal
+ c := a <> b;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( not (c = b) );
+ c := a <> a;
+ Assert.IsTrue(c = False);
+ Assert.IsTrue( a = dbl_a);
+ // greater than
+ c := a > b; Assert.IsTrue(c = False);
+ c := b > a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a > (dbl_a-1));
+ // greater or equal than
+ c := a >= b; Assert.IsTrue(c = False);
+ c := b >= a; Assert.IsTrue(c = True);
+ c := a >= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a >= dbl_a );
+ // less than
+ c := a < b; Assert.IsTrue(c = True);
+ c := b < a; Assert.IsTrue(c = False);
+ Assert.IsTrue( a < dbl_b);
+ // less or equal than
+ c := a <= b; Assert.IsTrue(c = True);
+ c := b <= a; Assert.IsTrue(c = False);
+ c := a <= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a <= dbl_a);
+ // parenthesis
+ c := a * ((a * b) / b);
+ dbl_c := dbl_a * ((dbl_a * dbl_b) / dbl_b);
+ Assert.IsTrue( c = dbl_c );
+ // copy
+ c := a;
+ Assert.IsTrue( c = a);
+ Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
+ // casts
+ int := a;
+ Assert.IsTrue(int = 2);
+end;
+procedure TVarPythTest.TestIntegers;
+var
+ a, b, c : Variant;
+ big : Int64;
+begin
+ // initialize the operands
+ a := VarPythonCreate(2);
+ Assert.IsTrue(VarIsPython(a));
+ Assert.IsTrue(VarIsPythonNumber(a));
+ Assert.IsTrue(VarIsPythonInteger(a));
+ Assert.IsTrue(Integer(a) = 2);
+ b := VarPythonCreate(3);
+ Assert.IsTrue(VarIsPython(b));
+ Assert.IsTrue(VarIsPythonNumber(b));
+ Assert.IsTrue(VarIsPythonInteger(b));
+ Assert.IsTrue(Integer(b) = 3);
+ // arithmetic operations
+ //----------------------
+ // addition
+ c := a + b;
+ // check result of operation
+ Assert.IsTrue( Integer(c) = 5 );
+ // check that operation did not change the content of operands.
+ Assert.IsTrue(Integer(a) = 2);
+ Assert.IsTrue(Integer(b) = 3);
+ // now with a litteral
+ c := a + b + 1;
+ Assert.IsTrue( Integer(c) = 6 );
+ c := a + 1 + b;
+ Assert.IsTrue( Integer(c) = 6 );
+ c := 1 + a + b;
+ Assert.IsTrue( Integer(c) = 6 );
+ // substraction
+ c := b - a;
+ Assert.IsTrue( Integer(c) = 1 );
+ // now with a litteral
+ c := b - a - 1;
+ Assert.IsTrue( Integer(c) = 0 );
+ c := b - 1 - a;
+ Assert.IsTrue( Integer(c) = 0 );
+ c := 1 - b - a;
+ Assert.IsTrue( Integer(c) = -4 );
+ // multiplication
+ c := a * b;
+ Assert.IsTrue( Integer(c) = 6 );
+ // now with a litteral
+ c := a * b * 2;
+ Assert.IsTrue( Integer(c) = 12 );
+ c := a * 2 * b;
+ Assert.IsTrue( Integer(c) = 12 );
+ c := 2 * a * b;
+ Assert.IsTrue( Integer(c) = 12 );
+ // integer division
+ c := b div a;
+ Assert.IsTrue( Integer(c) = 1 );
+ // division: in Python a division between 2 integers is the same as the integer division
+ c := b / a;
+ Assert.IsTrue( c = 1.5 );
+ Assert.IsTrue( Integer(c) = 2 );
+ // modulus
+ c := b mod a;
+ Assert.IsTrue( Integer(c) = 1 );
+ c := BuiltinModule.divmod(b, a); // this returns a tuple whose first item is the result of the division,
+ // and second item the modulo.
+ if VarIsPythonSequence(c) and (c.Length = 2) then
+ begin
+ Assert.IsTrue(Integer(c.GetItem(0)) = 1); // division
+ Assert.IsTrue(Integer(c.GetItem(1)) = 1); // modulo
+ end;
+ // power
+ c := BuiltinModule.pow(a, b);
+ Assert.IsTrue(c = 8);
+ // negation
+ c := -a;
+ Assert.IsTrue( Integer(c) = -2 );
+ // logical operations
+ //------------------
+ // inverse
+ c := not a; // in python it would be: c = ~2
+ Assert.IsTrue( Integer(c) = -3 );
+ // shift left (<<)
+ c := a shl b;
+ Assert.IsTrue( Integer(c) = 16 );
+ c := a shl 1;
+ Assert.IsTrue( Integer(c) = 4 );
+ // shift right (>>)
+ c := a shl b;
+ c := c shr b;
+ Assert.IsTrue( Integer(c) = Integer(a) );
+ c := b shr 1;
+ Assert.IsTrue( Integer(c) = 1 );
+ // and
+ c := a and (a*5);
+ Assert.IsTrue( Integer(c) = Integer(a) );
+ c := a and 6;
+ Assert.IsTrue( Integer(c) = Integer(a) );
+ // or
+ c := a or b;
+ Assert.IsTrue( Integer(c) = 3 );
+ c := a or 3;
+ Assert.IsTrue( Integer(c) = 3 );
+ // xor
+ c := a xor b;
+ Assert.IsTrue( Integer(c) = 1 );
+ c := a xor 3;
+ Assert.IsTrue( Integer(c) = 1 );
+ // comparisons
+ //------------
+ // equal
+ c := a = b;
+ Assert.IsTrue(c = False);
+ c := a = a;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( a = 2);
+ // not equal
+ c := a <> b;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( not (c = b) );
+ c := a <> a;
+ Assert.IsTrue(c = False);
+ Assert.IsTrue( a = 2);
+ // greater than
+ c := a > b; Assert.IsTrue(c = False);
+ c := b > a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a > 1);
+ // greater or equal than
+ c := a >= b; Assert.IsTrue(c = False);
+ c := b >= a; Assert.IsTrue(c = True);
+ c := a >= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a >= 2 );
+ // less than
+ c := a < b; Assert.IsTrue(c = True);
+ c := b < a; Assert.IsTrue(c = False);
+ Assert.IsTrue( a < 6);
+ // less or equal than
+ c := a <= b; Assert.IsTrue(c = True);
+ c := b <= a; Assert.IsTrue(c = False);
+ c := a <= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a <= 2);
+ // parenthesis
+ c := a * ((a * b) div b);
+ Assert.IsTrue( c = a*2 );
+ // copy
+ c := a;
+ Assert.IsTrue( c = a);
+ Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
+ // test long long (Int64)
+ big := Int64(MaxInt)*4;
+ b := VarPythonCreate(big);
+ Assert.IsTrue( b = big );
+ Assert.IsTrue( b <> big+1 );
+ Assert.IsTrue( b > MaxInt );
+ Assert.IsTrue( MaxInt < b );
+ Assert.IsTrue( b+1 = big+1 );
+ Assert.IsTrue( b*2 = big*2 );
+ Assert.IsTrue( b div 2 = big div 2 );
+ c := VarPythonCreate(True);
+ Assert.IsTrue(VarIsBool(c));
+ Assert.IsTrue(VarIsTrue(c));
+ c := VarPythonCreate(False);
+ Assert.IsTrue(VarIsBool(c));
+ Assert.IsTrue(not VarIsTrue(c));
+end;
+procedure TVarPythTest.TestIterator;
+var
+ Module: Variant;
+ Count: integer;
+begin
+ Count := 0;
+ for Module in VarPyIterate(SysModule.modules) do begin
+ Count := Count + 1;
+ Log(Module);
+ end;
+ Assert.IsTrue(Count = len(SysModule.modules));
+end;
+procedure TVarPythTest.TestMappings;
+var
+ a, b, c, keys, values : Variant;
+begin
+ // initialize the operands
+ a := NewPythonDict;
+ Assert.IsTrue(VarIsPython(a));
+ Assert.IsTrue(VarIsPythonMapping(a));
+ Assert.IsTrue(VarIsPythonDict(a));
+ // There is a bug in D2010 in which Char('a') gets translated to integer parameter
+ a.SetItem( string('a'), 1 );
+ a.SetItem( string('b'), 2 );
+ a.SetItem( string('c'), 3 );
+ Assert.IsTrue(a.Length = 3); // this is a special property that does the same as: len(a) in Python
+ Assert.IsTrue(a.Length() = 3); // this is a special method that does the same as the special property
+ Assert.IsTrue(len(a) = 3);
+ Assert.IsTrue(a.GetItem(string('a')) = 1); // this is a special method that lets you do the same as: a[0] in Python
+ Assert.IsTrue(a.GetItem(string('b')) = 2);
+ Assert.IsTrue(a.GetItem(string('c')) = 3);
+
+
+ b := NewPythonDict;
+ Assert.IsTrue(VarIsPython(b));
+ Assert.IsTrue(VarIsPythonMapping(b));
+ Assert.IsTrue(VarIsPythonDict(b));
+ b.SetItem( string('d'), 4 );
+ b.SetItem( string('e'), 5 );
+ b.SetItem( string('f'), 6 );
+ Assert.IsTrue(b.Length = 3);
+ Assert.IsTrue(b.Length() = 3);
+ Assert.IsTrue(len(b) = 3);
+ Assert.IsTrue(b.GetItem(string('d')) = 4);
+ Assert.IsTrue(b.GetItem(string('e')) = 5);
+ Assert.IsTrue(b.GetItem(string('f')) = 6);
+
+ // copy
+ c := a;
+ Assert.IsTrue( c = a);
+ Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
+
+ // dict methods
+ Assert.IsTrue( Boolean(a.__contains__(string('a'))) );
+ Assert.IsTrue( not Boolean(a.__contains__('abc')) );
+ keys := BuiltinModule.list(a.keys());
+ keys.sort();
+ Assert.IsTrue( keys = VarPythonCreate(VarArrayOf(['a', 'b', 'c'])));
+ values := BuiltinModule.list(a.values());
+ values.sort();
+ Assert.IsTrue( values = VarPythonCreate(VarArrayOf([1, 2, 3])));
+ c := a;
+ c.DeleteItem(string('a'));
+ Assert.IsTrue( not Boolean(c.__contains__(string('a'))) );
+
+ // test string values
+ a := NewPythonDict;
+ a.SetItem( string('a'), 'Hello');
+ a.SetItem( string('b'), 'World!');
+ a.SetItem( string('c'), '');
+ Assert.IsTrue(a.GetItem(string('a')) = 'Hello');
+ Assert.IsTrue(a.GetItem(string('b')) = 'World!');
+ Assert.IsTrue(a.GetItem(string('c')) = '');
+end;
+
+procedure TVarPythTest.TestObjects;
+var
+ _main, f, a, b, c : Variant;
+ val : Integer;
+ _str : String;
+const
+ Script =
+ 'class XYZ(object):' + sLineBreak +
+ ' pass' + sLineBreak +
+ '' + sLineBreak +
+ 'class Foo:' + sLineBreak +
+ ' def __init__(Self, Value=0):' + sLineBreak +
+ ' Self.Value = Value' + sLineBreak +
+ ' def __del__(Self):' + sLineBreak +
+ ' print("delete", Self)' + sLineBreak +
+ ' def __add__(self, other):' + sLineBreak +
+ ' return Foo(self.Value + other.Value)' + sLineBreak +
+ ' def Inc(Self, AValue = 1):' + sLineBreak +
+ ' Self.Value = Self.Value + AValue' + sLineBreak +
+ ' def GetSelf(Self):' + sLineBreak +
+ ' return Self' + sLineBreak +
+ ' def GetValue(Self):' + sLineBreak +
+ ' return Self.Value' + sLineBreak +
+ ' def SetABC(Self, A, B, C):' + sLineBreak +
+ ' Self.A = A' + sLineBreak +
+ ' Self.B = B' + sLineBreak +
+ ' Self.C = C' + sLineBreak +
+ ' def Add(Self, AFooInst):' + sLineBreak +
+ ' Self.Value = Self.Value + AFooInst.Value' + sLineBreak +
+ 'class Bar(Foo):' + sLineBreak +
+ ' def Inc(Self, AValue = 1):' + sLineBreak +
+ ' Self.Value = Self.Value - AValue' + sLineBreak +
+ 'def Add(a, b):' + sLineBreak +
+ ' return a + b' + sLineBreak +
+ 'def MakeList(a, b, c, d):' + sLineBreak +
+ ' return [a, b, c, d]' + sLineBreak +
+ '' + sLineBreak +
+ 'f = Foo()' + sLineBreak +
+ 'print("Created", f)' + sLineBreak +
+ 'f.Inc()' + sLineBreak +
+ 'f.Inc(2)' + sLineBreak +
+ 'b = Bar()' + sLineBreak +
+ 'b.Inc()' + sLineBreak +
+ 'b.Inc(2)';
+
+begin
+ FPythonEngine.ExecString(Script);
+ _main := MainModule;
+ Assert.IsTrue( VarIsPythonModule(_main) );
+ Assert.IsTrue( VarIsPythonModule(SysModule) );
+ Assert.IsTrue( Import('sys').version = SysModule.version );
+ Log(SysModule.version);
+ Assert.IsTrue( Boolean(SysModule.modules.Contains(GetPythonEngine.ExecModule)) ); // if __main__ in sys.modules
+ Assert.IsTrue( VarIsSameType(_main, SysModule) );
+ Assert.IsTrue( _type(_main).__name__ = 'module');
+ Assert.IsTrue( BuiltinModule.type(_main).__name__ = 'module');
+
+ Assert.IsTrue( VarIsPythonClass(_main.Foo) );
+ Assert.IsTrue( VarIsPythonClass(_main.Bar) );
+ Assert.IsTrue( VarIsPythonClass(_main.XYZ) );
+ Assert.IsTrue( not VarIsPythonClass(_main.Foo.__add__) );
+ Assert.IsTrue( not VarIsPythonClass(_main.f) );
+ Assert.IsTrue( VarIsPythonCallable(_main.Foo) );
+ Assert.IsTrue( VarIsPythonCallable(_main.Foo) );
+ Assert.IsTrue( VarIsTrue(BuiltinModule.callable(_main.Foo)) );
+ Assert.IsTrue( VarIsSame(_main.f.__class__, _main.Foo) );
+ Assert.IsTrue( VarIsPythonMethod(_main.f.Inc) );
+ Assert.IsTrue( VarIsPythonCallable(_main.f.Inc) );
+ Assert.IsTrue( VarIsTrue(BuiltinModule.callable(_main.f.Inc)) );
+ Assert.IsTrue( VarIsPythonFunction(_main.Add) );
+ Assert.IsTrue( VarIsPythonCallable(_main.Add) );
+ Assert.IsTrue( VarIsInstanceOf(_main.f, _main.Foo) );
+ Assert.IsTrue( VarIsTrue(BuiltinModule.isinstance(_main.f, _main.Foo)) );
+ Assert.IsTrue( VarIsSubclassOf(_main.Bar, _main.Foo) );
+ Assert.IsTrue( VarIsTrue(BuiltinModule.issubclass(_main.Bar, _main.Foo)) );
+ Assert.IsTrue( not VarIsSubclassOf(_main.Foo, _main.Bar) );
+ Assert.IsTrue( VarIsInstanceOf(_main.b, _main.Foo) );
+ Assert.IsTrue( not VarIsInstanceOf(_main.f, _main.Bar) );
+ Assert.IsTrue( VarIsTrue( BuiltinModule.vars(_main).__contains__(string('f')) ) );
+ Assert.IsTrue( VarIsTrue( BuiltinModule.dir(_main).Contains(string('f')) ) );
+
+ f := _main.Foo(); // new instance of class Foo
+ Log('Instanciate class Foo: ' + f);
+ f.Inc(); // call a method without any arg, because there's a default arg.
+ f.Inc(2); // call a method with one arg, overriding the default arg.
+ Assert.IsTrue( VarIsPythonNumber(f.Value) );
+ Assert.IsTrue( VarIsPythonInteger(f.Value) );
+ Assert.IsTrue( f.Value = _main.f.Value ); // compare the result with what we did in the script
+ Assert.IsTrue( f.GetValue() = _main.f.GetValue() ); // compare the result with what we did in the script
+ Assert.IsTrue( VarIsPython( f.GetSelf() ) );
+ Assert.IsTrue( VarIsSame( f.GetSelf(), f ) );
+ Assert.IsTrue( BuiltinModule.getattr(f, 'Value') = f.Value );
+ // python (+) operator overloading
+ a := _main.Foo(10);
+ b := _main.Foo(5);
+ c := a + b;
+ Assert.IsTrue(a.Value = 10);
+ Assert.IsTrue(b.Value = 5);
+ Assert.IsTrue(c.Value = 15);
+ Log('Test -> a, b, c : ' + a.Value + ', ' + b.Value + ', ' + c.Value);
+ // cascading calls
+ Assert.IsTrue( f.GetSelf().GetSelf().GetSelf().GetSelf().GetValue() = _main.f.GetValue() );
+ Assert.IsTrue( Boolean(f.__dict__.__contains__('Value')) );
+ Assert.IsTrue( VarIsTrue( BuiltinModule.hasattr(f, 'Value') ) );
+ _str := 'Value';
+ Assert.IsTrue( Boolean(f.__dict__.__contains__(_str)) ); // check with a string var
+ Assert.IsTrue( Boolean( BuiltinModule.hasattr(f, _str) ) );
+ val := f.Value;
+ f.Add(f); // passing itself as an argument
+ Assert.IsTrue( f.Value = val*2 );
+ // check param order
+ f.SetABC(1, 2, 3);
+ Assert.IsTrue(f.A = 1);
+ Assert.IsTrue(f.B = 2);
+ Assert.IsTrue(f.C = 3);
+ // add a property to an instance
+ f.Z := 99;
+ Assert.IsTrue(f.Z = 99);
+ // add a var to a module
+ _main.Z := 99;
+ Assert.IsTrue(_main.Z = 99);
+ // check none
+ Assert.IsTrue( VarIsNone(None) );
+ Assert.IsTrue( VarIsNone(VarPythonCreate([1, Null, 3]).GetItem(1)) ); // Null is casted to None
+ Assert.IsTrue( VarIsNone(VarPythonCreate([1, None, 3]).GetItem(1)) );
+ Assert.IsTrue( VarIsNone(f.Inc()) );
+ Assert.IsTrue( f.Inc() = None );
+ Assert.IsTrue( not Boolean(None) ); // if not None:
+ Assert.IsTrue( not VarIsTrue(None) ); // if not None:
+ Assert.IsTrue( Boolean(f) ); // if f:
+ Assert.IsTrue( VarIsTrue(f) ); // if f:
+
+ // call a function
+ Assert.IsTrue( _main.Add(2, 2) = 4 );
+ // call a function with a mix of regular parameters and named parameters
+ f := _main.MakeList(1, 2, 3, 4);
+ Assert.IsTrue(VarIsPythonList(f));
+ Assert.IsTrue(f.Length = 4);
+ Assert.IsTrue(f.GetItem(0) = 1);
+ Assert.IsTrue(f.GetItem(1) = 2);
+ Assert.IsTrue(f.GetItem(2) = 3);
+ Assert.IsTrue(f.GetItem(3) = 4);
+ f := _main.MakeList(1, d:=3, c:=4, b:=2);
+ Assert.IsTrue(VarIsPythonList(f));
+ Assert.IsTrue(f.Length = 4);
+ Assert.IsTrue(f.GetItem(0) = 1);
+ Assert.IsTrue(f.GetItem(1) = 2);
+ Assert.IsTrue(f.GetItem(2) = 4);
+ Assert.IsTrue(f.GetItem(3) = 3);
+ f := _main.MakeList(1, 2, d:= 3, c:=4);
+ Assert.IsTrue(VarIsPythonList(f));
+ Assert.IsTrue(f.Length = 4);
+ Assert.IsTrue(f.GetItem(0) = 1);
+ Assert.IsTrue(f.GetItem(1) = 2);
+ Assert.IsTrue(f.GetItem(2) = 4);
+ Assert.IsTrue(f.GetItem(3) = 3);
+ f := _main.MakeList(1, 2, 3, d:=4);
+ Assert.IsTrue(VarIsPythonList(f));
+ Assert.IsTrue(f.Length = 4);
+ Assert.IsTrue(f.GetItem(0) = 1);
+ Assert.IsTrue(f.GetItem(1) = 2);
+ Assert.IsTrue(f.GetItem(2) = 3);
+ Assert.IsTrue(f.GetItem(3) = 4);
+ f := _main.MakeList(b:=1, a:=2, d:= 3, c:=4);
+ Assert.IsTrue(VarIsPythonList(f));
+ Assert.IsTrue(f.Length = 4);
+ Assert.IsTrue(f.GetItem(0) = 2);
+ Assert.IsTrue(f.GetItem(1) = 1);
+ Assert.IsTrue(f.GetItem(2) = 4);
+ Assert.IsTrue(f.GetItem(3) = 3);
+end;
+procedure TVarPythTest.TestSequences;
+var
+ a, b, c : Variant;
+ iter : Variant;
+ cpt : Integer;
+begin
+ // initialize the operands
+ // you can either use the overloaded function with an array of const
+ // or use the VarArrayOf function that returns an array of variants that will
+ // be casted to a Python list.
+ a := VarPythonCreate([1, 2, 3]);
+ Assert.IsTrue(VarIsPython(a));
+ Assert.IsTrue(VarIsPythonSequence(a));
+ Assert.IsTrue(VarIsPythonList(a));
+ Assert.IsTrue(a.Length = 3); // this is a special property that does the same as: len(a) in Python
+ Assert.IsTrue(a.Length() = 3); // this is a special method that does the same as the special property
+ Assert.IsTrue(len(a) = 3);
+ Assert.IsTrue(a.GetItem(0) = 1); // this is a special method that lets you do the same as: a[0] in Python
+ Assert.IsTrue(a.GetItem(1) = 2);
+ Assert.IsTrue(a.GetItem(2) = 3);
+ Assert.IsTrue(string(a) = '[1, 2, 3]');
+ // indexed access using brackets when the sequence is a property of an object (module, instance...)
+ MainModule.a := VarPythonCreate([1, 2, 3]);
+ Assert.IsTrue(MainModule.a[1] = 2);
+
+ b := VarPythonCreate(VarArrayOf([4, 5, 6]));
+ Assert.IsTrue(VarIsPython(b));
+ Assert.IsTrue(VarIsPythonSequence(b));
+ Assert.IsTrue(VarIsPythonList(b));
+ Assert.IsTrue(b.Length = 3);
+ Assert.IsTrue(b.Length() = 3);
+ Assert.IsTrue(len(b) = 3);
+ Assert.IsTrue(b.GetItem(0) = 4);
+ Assert.IsTrue(b.GetItem(1) = 5);
+ Assert.IsTrue(b.GetItem(2) = 6);
+ Assert.IsTrue(string(b) = '[4, 5, 6]');
+ // concatenation
+ c := a + b;
+ // check result of operation
+ Assert.IsTrue(string(c) = '[1, 2, 3, 4, 5, 6]');
+ // check that operation did not change the content of operands.
+ Assert.IsTrue(string(a) = '[1, 2, 3]');
+ Assert.IsTrue(string(b) = '[4, 5, 6]');
+ // now with a litteral: note that with D6 SP1, we can't concatenate a custom variant with an var array of variants
+ c := a + b + VarPythonCreate(['Hello', 'World!', 3.14]);
+ Assert.IsTrue( string(c) = '[1, 2, 3, 4, 5, 6, ''Hello'', ''World!'', 3.14]' );
+ c := a + VarPythonCreate(['Hello', 'World!', 3.14]) + b;
+ Assert.IsTrue( string(c) = '[1, 2, 3, ''Hello'', ''World!'', 3.14, 4, 5, 6]' );
+ c := VarPythonCreate(['Hello', 'World!', 3.14]) + a + b;
+ Assert.IsTrue( string(c) = '[''Hello'', ''World!'', 3.14, 1, 2, 3, 4, 5, 6]' );
+
+ // multiplication
+ c := a * 3; // in Python the multiplication of sequence concatenates n times the sequence
+ Assert.IsTrue( string(c) = '[1, 2, 3, 1, 2, 3, 1, 2, 3]' );
+
+ // comparisons
+ //------------
+
+ // equal
+ c := a = b;
+ Assert.IsTrue(c = False);
+ c := a = a;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( string(a) = '[1, 2, 3]');
+
+ // not equal
+ c := a <> b;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( not (c = b) );
+ c := a <> a;
+ Assert.IsTrue(c = False);
+ Assert.IsTrue( string(a) = '[1, 2, 3]');
+
+ // greater than
+ c := a > b; Assert.IsTrue(c = False);
+ c := b > a; Assert.IsTrue(c = True);
+ Assert.IsTrue( string(a) > '[1, 1, 1]');
+
+ // greater or equal than
+ c := a >= b; Assert.IsTrue(c = False);
+ c := b >= a; Assert.IsTrue(c = True);
+ c := a >= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( string(a) >= '[1, 2, 3]' );
+
+ // less than
+ c := a < b; Assert.IsTrue(c = True);
+ c := b < a; Assert.IsTrue(c = False);
+ Assert.IsTrue( string(a) < '[4, 4, 4]');
+
+ // less or equal than
+ c := a <= b; Assert.IsTrue(c = True);
+ c := b <= a; Assert.IsTrue(c = False);
+ c := a <= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( string(a) <= '[1, 2, 3]');
+
+ // copy
+ c := a;
+ Assert.IsTrue( c = a);
+ Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
+
+ // sequence methods:
+ c := b + a;
+ c.sort(); // note that you must you the parenthesis to distinguish the call between a method or a property.
+ Assert.IsTrue( c = (a+b) );
+
+ c := NewPythonList; // facility for building sequences
+ Assert.IsTrue( not VarIsTrue(c) ); // c is false because it's an empty collection
+ c.append(1);
+ c.append(2);
+ c.append(3);
+ Assert.IsTrue( VarIsTrue(c) ); // c is true because it's not an empty collection
+ Assert.IsTrue(c = a);
+ Assert.IsTrue( c.pop() = 3 );
+ Assert.IsTrue( string(c) = '[1, 2]');
+
+ c := NewPythonList(3); // facility for building sequences
+ c.SetItem(0, 1);
+ c.SetItem(1, 2);
+ c.SetItem(2, 3);
+ Assert.IsTrue(c = a);
+ c.DeleteItem(1);
+ Assert.IsTrue(c = VarPythonCreate([1,3]));
+
+ Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, 3) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:3]
+ Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, Ellipsis) = VarPythonCreate([2,3,4])); // same as x = [1,2,3,4]; x[1:]
+ Assert.IsTrue(VarPythonCreate([1,2,3,4]).GetSlice(1, -1) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:-1]
+ c := VarPythonCreate([1,2,3,4]);
+ c.SetSlice(1, 3, VarPythonCreate([7, 8, 9]));
+ Assert.IsTrue( c = VarPythonCreate([1, 7, 8, 9, 4]) );
+ Assert.IsTrue( Boolean(c.Contains( 7 )) ); // same as 7 in c
+ Assert.IsTrue( not Boolean(c.Contains( 77 )) );
+ c.DelSlice(1,3);
+ Assert.IsTrue( c = VarPythonCreate([1,9,4]) );
+
+ c := VarPythonCreate([1, 2, 3, 4], stTuple); // test a tuple
+ Assert.IsTrue( VarIsPythonTuple(c) );
+ Assert.IsTrue( VarIsPythonSequence(c) );
+ Assert.IsTrue( c.GetItem(1) = 2 );
+ Assert.IsTrue( c.Length = 4 );
+ c := NewPythonTuple(3);
+ c.SetItem(0, 1);
+ c.SetItem(1, 2);
+ c.SetItem(2, 3);
+ Assert.IsTrue( VarIsPythonTuple(c) );
+ Assert.IsTrue( VarIsPythonSequence(c) );
+ Assert.IsTrue( c.GetItem(1) = 2 );
+ Assert.IsTrue( c.Length = 3 );
+
+ // test iterator
+ iter := BuiltinModule.iter(VarPythonCreate([1, 2, 3, 4], stTuple));
+ Assert.IsTrue(VarIsPythonIterator(iter));
+ Assert.IsTrue(iter.__next__() = 1);
+ Assert.IsTrue(iter.__next__() = 2);
+ Assert.IsTrue(iter.__next__() = 3);
+ Assert.IsTrue(iter.__next__() = 4);
+ try
+ iter.__next__();
+ except
+ on E: EPyStopIteration do
+ begin
+ Assert.IsTrue(True); //Ok.
+ end
+ else
+ Assert.IsTrue(False, 'expected stop exception');
+ end;
+ cpt := 0;
+ iter := VarPyth.iter(VarPythonCreate([1, 2, 3, 4], stTuple));
+ Assert.IsTrue(VarIsPythonIterator(iter));
+ try
+ while True do
+ begin
+ a := iter.__next__();
+ Inc(cpt);
+ Assert.IsTrue(a = cpt);
+ end;
+ except
+ on E: EPyStopIteration do
+ begin
+ Assert.IsTrue(True); //Ok.
+ end
+ else
+ Assert.IsTrue(False, 'expected stop exception');
+ end;
+ Assert.IsTrue(cpt = 4);
+end;
+procedure TVarPythTest.TestStrings;
+var
+ a, b, c : Variant;
+ w : WideString;
+ _obj : PPyObject;
+begin
+ // initialize the operands
+ a := VarPythonCreate('abc');
+ Assert.IsTrue(VarIsPython(a));
+ Assert.IsTrue(VarIsPythonString(a));
+ Assert.IsTrue(string(a) = 'abc');
+ b := VarPythonCreate('def');
+ Assert.IsTrue(VarIsPython(b));
+ Assert.IsTrue(VarIsPythonString(b));
+ Assert.IsTrue(string(b) = 'def');
+ // concatenation
+ c := a + b;
+ // check result of operation
+ Assert.IsTrue( string(c) = 'abcdef' );
+ // check that operation did not change the content of operands.
+ Assert.IsTrue(string(a) = 'abc');
+ Assert.IsTrue(string(b) = 'def');
+ // now with a litteral
+ c := a + b + '!';
+ Assert.IsTrue( string(c) = 'abcdef!' );
+ c := a + '!' + b;
+ Assert.IsTrue( string(c) = 'abc!def' );
+ c := '!' + a + b;
+ Assert.IsTrue( string(c) = '!abcdef' );
+ // multiplication
+ c := a * 3; // in Python the multiplication of string concatenates n times the string
+ Assert.IsTrue( string(c) = 'abcabcabc' );
+ // comparisons
+ //------------
+ // equal
+ c := a = b;
+ Assert.IsTrue(c = False);
+ c := a = a;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( a = 'abc');
+ // not equal
+ c := a <> b;
+ Assert.IsTrue(c = True);
+ Assert.IsTrue( not (c = b) );
+ c := a <> a;
+ Assert.IsTrue(c = False);
+ Assert.IsTrue( a = 'abc');
+ // greater than
+ c := a > b; Assert.IsTrue(c = False);
+ c := b > a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a > 'aaa');
+ // greater or equal than
+ c := a >= b; Assert.IsTrue(c = False);
+ c := b >= a; Assert.IsTrue(c = True);
+ c := a >= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a >= 'abc' );
+ // less than
+ c := a < b; Assert.IsTrue(c = True);
+ c := b < a; Assert.IsTrue(c = False);
+ Assert.IsTrue( a < 'bbb');
+ // less or equal than
+ c := a <= b; Assert.IsTrue(c = True);
+ c := b <= a; Assert.IsTrue(c = False);
+ c := a <= a; Assert.IsTrue(c = True);
+ Assert.IsTrue( a <= 'abc');
+ // copy
+ c := a;
+ Assert.IsTrue( c = a);
+ Assert.IsTrue( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
+ // empty strings
+ a := VarPythonCreate('');
+ Assert.IsTrue(a.length = 0);
+ Assert.IsTrue(a = '');
+ Assert.IsTrue(string(a) = '');
+ // Unicode strings
+ b := VarPythonEval( 'u"Hello world!"' );
+ Assert.IsTrue( VarIsPythonUnicode(b) );
+ w := FPythonEngine.PyUnicodeAsString(ExtractPythonObjectFrom(b));
+ Assert.IsTrue( w = 'Hello world!');
+ Assert.IsTrue( b = 'Hello world!');
+ Assert.IsTrue( b <> a );
+ _obj := FPythonEngine.PyUnicodeFromString(w);
+ try
+ c := VarPythonCreate( _obj );
+ finally
+ FPythonEngine.Py_XDecRef(_obj);
+ end;
+ Assert.IsTrue(b = c);
+ Assert.IsTrue(c = w);
+ Assert.IsTrue( c = 'Hello world!');
+ w := b;
+ Assert.IsTrue( b = w);
+ Assert.IsTrue( w = 'Hello world!');
+ Assert.IsTrue( Length(w) = 12 );
+ Assert.IsTrue( Length(w) = b.Length() );
+ c := FPythonEngine.PyObjectAsVariant(ExtractPythonObjectFrom(b));
+ Assert.IsTrue( c = b );
+ Assert.IsTrue( c = w );
+ Assert.IsTrue( c = 'Hello world!');
+ Assert.IsTrue( VarType(c) and VarTypeMask = varUString );
+ c := VarPythonCreate(w);
+ Assert.IsTrue( c = 'Hello world!');
+ Assert.IsTrue( c = w );
+ c := VarPythonCreate([w]);
+ Assert.IsTrue( VarIsPythonUnicode(c.GetItem(0)) );
+ Assert.IsTrue( c.GetItem(0) = 'Hello world!');
+ Assert.IsTrue( c.GetItem(0) = w );
+ c := w;
+ b := VarPythonCreate(c);
+ Assert.IsTrue( VarIsPythonUnicode(b) );
+ Assert.IsTrue( b = c );
+ Assert.IsTrue( b = w );
+ // empty strings
+ a := VarPythonEval( 'u""' );
+ Assert.IsTrue(a.length = 0);
+ Assert.IsTrue(a = '');
+ Assert.IsTrue(string(a) = '');
+ Assert.IsTrue(WideString(a) = '');
+end;
+
+initialization
+ TDUnitX.RegisterTestFixture(TVarPythTest);
+
+end.
diff --git a/Tests/WrapDelphiEventHandlerTest.pas b/Tests/WrapDelphiEventHandlerTest.pas
index 9f3efdb5..d38c1d52 100644
--- a/Tests/WrapDelphiEventHandlerTest.pas
+++ b/Tests/WrapDelphiEventHandlerTest.pas
@@ -1,310 +1,310 @@
-unit WrapDelphiEventHandlerTest;
-
-interface
-
-uses
- Types,
- DUnitX.TestFramework,
- PythonEngine,
- WrapDelphi, System.Classes;
-
-type
- TTestGetObjectEvent = procedure(Sender: TObject; var AObject: TObject) of object;
- TTestGetValueEvent = procedure(Sender: TObject; var AValue: Double) of object;
-
- TTest = class(TComponent)
- private
- FObject: TObject;
- FValue: Double;
- FOnGetObject: TTestGetObjectEvent;
- FOnGetValue: TTestGetValueEvent;
-
- ProcessCalled: Boolean;
-
- public
- procedure Process;
-
- published
- property OnGetObject: TTestGetObjectEvent read FOnGetObject write FOnGetObject;
- property OnGetValue: TTestGetValueEvent read FOnGetValue write FOnGetValue;
- end;
-
-
- [TestFixture]
- TTestWrapDelphiEventHandlers = class(TObject)
- private
- PythonEngine: TPythonEngine;
- DelphiModule: TPythonModule;
- DelphiWrapper: TPyDelphiWrapper;
-
- public
- [SetupFixture]
- procedure SetupFixture;
-
- [TearDownFixture]
- procedure TearDownFixture;
-
- [Test]
- procedure TestProcessWithValue;
- [Test]
- procedure TestProcessWithObject;
- end;
-
-implementation
-
-uses
- TypInfo;
-
-type
- TTestRegistration = class(TRegisteredUnit)
- public
- function Name: string; override;
- procedure RegisterWrappers(APyDelphiWrapper: TPyDelphiWrapper); override;
- end;
-
- TTestGetValueEventHandler = class(TEventHandler)
- protected
- procedure DoEvent(Sender: TObject; var Value: Double);
- public
- constructor Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
- PropertyInfo: PPropInfo; Callable: PPyObject); override;
- class function GetTypeInfo: PTypeInfo; override;
- end;
-
- TTestGetObjectEventHandler = class(TEventHandler)
- protected
- procedure DoEvent(Sender: TObject; var Obj: TObject);
-
- public
- constructor Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
- PropertyInfo: PPropInfo; Callable: PPyObject); override;
- class function GetTypeInfo: PTypeInfo; override;
- end;
-
-
-{ TTestRegistration }
-
-function TTestRegistration.Name: string;
-begin
- Result := 'Test';
-end;
-
-procedure TTestRegistration.RegisterWrappers(APyDelphiWrapper: TPyDelphiWrapper);
-begin
- inherited;
- APyDelphiWrapper.EventHandlers.RegisterHandler(TTestGetValueEventHandler);
- APyDelphiWrapper.EventHandlers.RegisterHandler(TTestGetObjectEventHandler);
-end;
-
-
-{ TTestGetValueEventHandler }
-
-constructor TTestGetValueEventHandler.Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
- PropertyInfo: PPropInfo; Callable: PPyObject);
-var
- Method: TMethod;
-begin
- inherited;
- Method.Code := @TTestGetValueEventHandler.DoEvent;
- Method.Data := Self;
- SetMethodProp(Component, PropertyInfo, Method);
-end;
-
-procedure TTestGetValueEventHandler.DoEvent(Sender: TObject; var Value: Double);
-var
- PySender: PPyObject;
- PyValue: PPyObject;
- PyArgs: PPyObject;
- PyResult: PPyObject;
- PyValueVarParam: TPyDelphiVarParameter;
-begin
- if not Assigned(PyDelphiWrapper) or not Assigned(Callable) or not PythonOk then
- Exit;
- with PyDelphiWrapper.Engine do
- begin
- PySender := PyDelphiWrapper.Wrap(Sender);
- PyValue := CreateVarParam(PyDelphiWrapper, Value);
- PyValueVarParam := PythonToDelphi(PyValue) as TPyDelphiVarParameter;
- PyArgs := PyTuple_New(2);
- PyTuple_SetItem(PyArgs, 0, PySender);
- PyTuple_SetItem(PyArgs, 1, PyValue);
- try
- PyResult := PyObject_CallObject(Callable, PyArgs);
- if Assigned(PyResult) then
- begin
- Py_XDECREF(PyResult);
- Value := PyObjectAsVariant(PyValueVarParam.Value);
- end;
- finally
- Py_DECREF(PyArgs)
- end;
- CheckError;
- end;
-end;
-
-class function TTestGetValueEventHandler.GetTypeInfo: PTypeInfo;
-begin
- Result := System.TypeInfo(TTestGetValueEvent);
-end;
-
-
-{ TTestGetObjectEventHandler }
-
-constructor TTestGetObjectEventHandler.Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
- PropertyInfo: PPropInfo; Callable: PPyObject);
-var
- Method: TMethod;
-begin
- inherited;
- Method.Code := @TTestGetObjectEventHandler.DoEvent;
- Method.Data := Self;
- SetMethodProp(Component, PropertyInfo, Method);
-end;
-
-procedure TTestGetObjectEventHandler.DoEvent(Sender: TObject; var Obj: TObject);
-var
- PySender: PPyObject;
- PyObj: PPyObject;
- PyArgs: PPyObject;
- PyResult: PPyObject;
- PyObjVarParam: TPyDelphiVarParameter;
-begin
- if not Assigned(PyDelphiWrapper) or not Assigned(Callable) or not PythonOk then
- Exit;
- with PyDelphiWrapper.Engine do
- begin
- PySender := PyDelphiWrapper.Wrap(Sender);
- PyObj := CreateVarParam(PyDelphiWrapper, Obj);
- PyObjVarParam := PythonToDelphi(PyObj) as TPyDelphiVarParameter;
- PyArgs := PyTuple_New(2);
- PyTuple_SetItem(PyArgs, 0, PySender);
- PyTuple_SetItem(PyArgs, 1, PyObj);
- try
- PyResult := PyObject_CallObject(Callable, PyArgs);
- if Assigned(PyResult) then
- begin
- Py_XDECREF(PyResult);
- Obj := (PythonToDelphi(PyObjVarParam.Value) as TPyDelphiObject).DelphiObject;
- end;
- finally
- Py_DECREF(PyArgs)
- end;
- CheckError;
- end;
-end;
-
-class function TTestGetObjectEventHandler.GetTypeInfo: PTypeInfo;
-begin
- Result := System.TypeInfo(TTestGetObjectEvent);
-end;
-
-
-{ TTest }
-
-procedure TTest.Process;
-begin
- ProcessCalled := True;
- if Assigned(FOnGetObject) then
- FOnGetObject(Self, FObject);
- if Assigned(FOnGetValue) then
- FOnGetValue(Self, FValue);
-end;
-
-
-{ TTestWrapDelphiEventHandlers }
-
-procedure TTestWrapDelphiEventHandlers.SetupFixture;
-begin
- PythonEngine := TPythonEngine.Create(nil);
- PythonEngine.Name := 'PythonEngine';
- PythonEngine.AutoLoad := False;
- PythonEngine.FatalAbort := True;
- PythonEngine.FatalMsgDlg := True;
- PythonEngine.UseLastKnownVersion := True;
- PythonEngine.AutoFinalize := True;
- PythonEngine.InitThreads := True;
- PythonEngine.PyFlags := [pfInteractive];
- DelphiModule := TPythonModule.Create(nil);
-
- DelphiModule.Name := 'DelphiModule';
- DelphiModule.Engine := PythonEngine;
- DelphiModule.ModuleName := 'delphi';
-
- DelphiWrapper := TPyDelphiWrapper.Create(nil);
-
- DelphiWrapper.Name := 'PyDelphiWrapper';
- DelphiWrapper.Engine := PythonEngine;
- DelphiWrapper.Module := DelphiModule;
-
- PythonEngine.LoadDll;
-end;
-
-procedure TTestWrapDelphiEventHandlers.TearDownFixture;
-begin
- PythonEngine.Free;
- DelphiWrapper.Free;
- DelphiModule.Free;
-end;
-
-procedure TTestWrapDelphiEventHandlers.TestProcessWithValue;
-var
- Test: TTest;
- pyTest: PPyObject;
-begin
- Test := TTest.Create(nil);
- try
- pyTest := DelphiWrapper.Wrap(Test);
- DelphiModule.SetVar('test', pyTest);
- PythonEngine.Py_DECREF(pyTest);
- PythonEngine.ExecString(
- 'import delphi' + LF +
- '' + LF +
- 'def MyOnGetValue(sender, value):' + LF +
- ' value.Value = 3.14' + LF +
- '' + LF +
- 'delphi.test.OnGetValue = MyOnGetValue' + LF +
- 'delphi.test.Process()' + LF +
- ''
- );
- Assert.IsTrue(Test.ProcessCalled);
- Assert.AreEqual(Test.FValue, 3.14);
- finally
- Test.Free;
- end;
-end;
-
-
-procedure TTestWrapDelphiEventHandlers.TestProcessWithObject;
-var
- Test: TTest;
- pyTest: PPyObject;
-begin
- Test := TTest.Create(nil);
- try
- pyTest := DelphiWrapper.Wrap(Test);
- DelphiModule.SetVar('test', pyTest);
- PythonEngine.Py_DECREF(pyTest);
- PythonEngine.ExecString(
- 'import delphi' + LF +
- '' + LF +
- 'def MyOnGetObject(sender, value):' + LF +
- ' value.Value = sender' + LF +
- '' + LF +
- 'delphi.test.OnGetObject = MyOnGetObject' + LF +
- 'delphi.test.Process()' + LF +
- ''
- );
- Assert.IsTrue(Test.ProcessCalled);
- Assert.AreSame(Test, Test.FObject);
- finally
- Test.Free;
- end;
-end;
-
-initialization
-
-RegisteredUnits.Add(TTestRegistration.Create);
-
-TDUnitX.RegisterTestFixture(TTestWrapDelphiEventHandlers);
-
-end.
+unit WrapDelphiEventHandlerTest;
+
+interface
+
+uses
+ Types,
+ DUnitX.TestFramework,
+ PythonEngine,
+ WrapDelphi, System.Classes;
+
+type
+ TTestGetObjectEvent = procedure(Sender: TObject; var AObject: TObject) of object;
+ TTestGetValueEvent = procedure(Sender: TObject; var AValue: Double) of object;
+
+ TTest = class(TComponent)
+ private
+ FObject: TObject;
+ FValue: Double;
+ FOnGetObject: TTestGetObjectEvent;
+ FOnGetValue: TTestGetValueEvent;
+
+ ProcessCalled: Boolean;
+
+ public
+ procedure Process;
+
+ published
+ property OnGetObject: TTestGetObjectEvent read FOnGetObject write FOnGetObject;
+ property OnGetValue: TTestGetValueEvent read FOnGetValue write FOnGetValue;
+ end;
+
+
+ [TestFixture]
+ TTestWrapDelphiEventHandlers = class(TObject)
+ private
+ PythonEngine: TPythonEngine;
+ DelphiModule: TPythonModule;
+ DelphiWrapper: TPyDelphiWrapper;
+
+ public
+ [SetupFixture]
+ procedure SetupFixture;
+
+ [TearDownFixture]
+ procedure TearDownFixture;
+
+ [Test]
+ procedure TestProcessWithValue;
+ [Test]
+ procedure TestProcessWithObject;
+ end;
+
+implementation
+
+uses
+ TypInfo;
+
+type
+ TTestRegistration = class(TRegisteredUnit)
+ public
+ function Name: string; override;
+ procedure RegisterWrappers(APyDelphiWrapper: TPyDelphiWrapper); override;
+ end;
+
+ TTestGetValueEventHandler = class(TEventHandler)
+ protected
+ procedure DoEvent(Sender: TObject; var Value: Double);
+ public
+ constructor Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
+ PropertyInfo: PPropInfo; Callable: PPyObject); override;
+ class function GetTypeInfo: PTypeInfo; override;
+ end;
+
+ TTestGetObjectEventHandler = class(TEventHandler)
+ protected
+ procedure DoEvent(Sender: TObject; var Obj: TObject);
+
+ public
+ constructor Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
+ PropertyInfo: PPropInfo; Callable: PPyObject); override;
+ class function GetTypeInfo: PTypeInfo; override;
+ end;
+
+
+{ TTestRegistration }
+
+function TTestRegistration.Name: string;
+begin
+ Result := 'Test';
+end;
+
+procedure TTestRegistration.RegisterWrappers(APyDelphiWrapper: TPyDelphiWrapper);
+begin
+ inherited;
+ APyDelphiWrapper.EventHandlers.RegisterHandler(TTestGetValueEventHandler);
+ APyDelphiWrapper.EventHandlers.RegisterHandler(TTestGetObjectEventHandler);
+end;
+
+
+{ TTestGetValueEventHandler }
+
+constructor TTestGetValueEventHandler.Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
+ PropertyInfo: PPropInfo; Callable: PPyObject);
+var
+ Method: TMethod;
+begin
+ inherited;
+ Method.Code := @TTestGetValueEventHandler.DoEvent;
+ Method.Data := Self;
+ SetMethodProp(Component, PropertyInfo, Method);
+end;
+
+procedure TTestGetValueEventHandler.DoEvent(Sender: TObject; var Value: Double);
+var
+ PySender: PPyObject;
+ PyValue: PPyObject;
+ PyArgs: PPyObject;
+ PyResult: PPyObject;
+ PyValueVarParam: TPyDelphiVarParameter;
+begin
+ if not Assigned(PyDelphiWrapper) or not Assigned(Callable) or not PythonOk then
+ Exit;
+ with PyDelphiWrapper.Engine do
+ begin
+ PySender := PyDelphiWrapper.Wrap(Sender);
+ PyValue := CreateVarParam(PyDelphiWrapper, Value);
+ PyValueVarParam := PythonToDelphi(PyValue) as TPyDelphiVarParameter;
+ PyArgs := PyTuple_New(2);
+ PyTuple_SetItem(PyArgs, 0, PySender);
+ PyTuple_SetItem(PyArgs, 1, PyValue);
+ try
+ PyResult := PyObject_CallObject(Callable, PyArgs);
+ if Assigned(PyResult) then
+ begin
+ Py_XDECREF(PyResult);
+ Value := PyObjectAsVariant(PyValueVarParam.Value);
+ end;
+ finally
+ Py_DECREF(PyArgs)
+ end;
+ CheckError;
+ end;
+end;
+
+class function TTestGetValueEventHandler.GetTypeInfo: PTypeInfo;
+begin
+ Result := System.TypeInfo(TTestGetValueEvent);
+end;
+
+
+{ TTestGetObjectEventHandler }
+
+constructor TTestGetObjectEventHandler.Create(PyDelphiWrapper: TPyDelphiWrapper; Component: TObject;
+ PropertyInfo: PPropInfo; Callable: PPyObject);
+var
+ Method: TMethod;
+begin
+ inherited;
+ Method.Code := @TTestGetObjectEventHandler.DoEvent;
+ Method.Data := Self;
+ SetMethodProp(Component, PropertyInfo, Method);
+end;
+
+procedure TTestGetObjectEventHandler.DoEvent(Sender: TObject; var Obj: TObject);
+var
+ PySender: PPyObject;
+ PyObj: PPyObject;
+ PyArgs: PPyObject;
+ PyResult: PPyObject;
+ PyObjVarParam: TPyDelphiVarParameter;
+begin
+ if not Assigned(PyDelphiWrapper) or not Assigned(Callable) or not PythonOk then
+ Exit;
+ with PyDelphiWrapper.Engine do
+ begin
+ PySender := PyDelphiWrapper.Wrap(Sender);
+ PyObj := CreateVarParam(PyDelphiWrapper, Obj);
+ PyObjVarParam := PythonToDelphi(PyObj) as TPyDelphiVarParameter;
+ PyArgs := PyTuple_New(2);
+ PyTuple_SetItem(PyArgs, 0, PySender);
+ PyTuple_SetItem(PyArgs, 1, PyObj);
+ try
+ PyResult := PyObject_CallObject(Callable, PyArgs);
+ if Assigned(PyResult) then
+ begin
+ Py_XDECREF(PyResult);
+ Obj := (PythonToDelphi(PyObjVarParam.Value) as TPyDelphiObject).DelphiObject;
+ end;
+ finally
+ Py_DECREF(PyArgs)
+ end;
+ CheckError;
+ end;
+end;
+
+class function TTestGetObjectEventHandler.GetTypeInfo: PTypeInfo;
+begin
+ Result := System.TypeInfo(TTestGetObjectEvent);
+end;
+
+
+{ TTest }
+
+procedure TTest.Process;
+begin
+ ProcessCalled := True;
+ if Assigned(FOnGetObject) then
+ FOnGetObject(Self, FObject);
+ if Assigned(FOnGetValue) then
+ FOnGetValue(Self, FValue);
+end;
+
+
+{ TTestWrapDelphiEventHandlers }
+
+procedure TTestWrapDelphiEventHandlers.SetupFixture;
+begin
+ PythonEngine := TPythonEngine.Create(nil);
+ PythonEngine.Name := 'PythonEngine';
+ PythonEngine.AutoLoad := False;
+ PythonEngine.FatalAbort := True;
+ PythonEngine.FatalMsgDlg := True;
+ PythonEngine.UseLastKnownVersion := True;
+ PythonEngine.AutoFinalize := True;
+ PythonEngine.InitThreads := True;
+ PythonEngine.PyFlags := [pfInteractive];
+ DelphiModule := TPythonModule.Create(nil);
+
+ DelphiModule.Name := 'DelphiModule';
+ DelphiModule.Engine := PythonEngine;
+ DelphiModule.ModuleName := 'delphi';
+
+ DelphiWrapper := TPyDelphiWrapper.Create(nil);
+
+ DelphiWrapper.Name := 'PyDelphiWrapper';
+ DelphiWrapper.Engine := PythonEngine;
+ DelphiWrapper.Module := DelphiModule;
+
+ PythonEngine.LoadDll;
+end;
+
+procedure TTestWrapDelphiEventHandlers.TearDownFixture;
+begin
+ PythonEngine.Free;
+ DelphiWrapper.Free;
+ DelphiModule.Free;
+end;
+
+procedure TTestWrapDelphiEventHandlers.TestProcessWithValue;
+var
+ Test: TTest;
+ pyTest: PPyObject;
+begin
+ Test := TTest.Create(nil);
+ try
+ pyTest := DelphiWrapper.Wrap(Test);
+ DelphiModule.SetVar('test', pyTest);
+ PythonEngine.Py_DECREF(pyTest);
+ PythonEngine.ExecString(
+ 'import delphi' + LF +
+ '' + LF +
+ 'def MyOnGetValue(sender, value):' + LF +
+ ' value.Value = 3.14' + LF +
+ '' + LF +
+ 'delphi.test.OnGetValue = MyOnGetValue' + LF +
+ 'delphi.test.Process()' + LF +
+ ''
+ );
+ Assert.IsTrue(Test.ProcessCalled);
+ Assert.AreEqual(Test.FValue, 3.14);
+ finally
+ Test.Free;
+ end;
+end;
+
+
+procedure TTestWrapDelphiEventHandlers.TestProcessWithObject;
+var
+ Test: TTest;
+ pyTest: PPyObject;
+begin
+ Test := TTest.Create(nil);
+ try
+ pyTest := DelphiWrapper.Wrap(Test);
+ DelphiModule.SetVar('test', pyTest);
+ PythonEngine.Py_DECREF(pyTest);
+ PythonEngine.ExecString(
+ 'import delphi' + LF +
+ '' + LF +
+ 'def MyOnGetObject(sender, value):' + LF +
+ ' value.Value = sender' + LF +
+ '' + LF +
+ 'delphi.test.OnGetObject = MyOnGetObject' + LF +
+ 'delphi.test.Process()' + LF +
+ ''
+ );
+ Assert.IsTrue(Test.ProcessCalled);
+ Assert.AreSame(Test, Test.FObject);
+ finally
+ Test.Free;
+ end;
+end;
+
+initialization
+
+RegisteredUnits.Add(TTestRegistration.Create);
+
+TDUnitX.RegisterTestFixture(TTestWrapDelphiEventHandlers);
+
+end.
diff --git a/Tutorials/README.md b/Tutorials/README.md
index c2ccf162..d71b1791 100644
--- a/Tutorials/README.md
+++ b/Tutorials/README.md
@@ -1,10 +1,10 @@
-## Tutorials
-
-This folder contains text and video tutorials accompanied with slides and demo source code.
-
-- [Getting Started with Python4Delphi](https://youtu.be/hjY6lBgrHhM)
-- [Overview Video](https://youtu.be/jLuxTfct3CU)
-- [Webinar I](https://github.com/pyscripter/python4delphi/tree/master/Tutorials/Webinar%20I)
-- [Webinar II](https://github.com/pyscripter/python4delphi/tree/master/Tutorials/Webinar%20II)
-- [Introductory tutorial](https://github.com/pyscripter/python4delphi/wiki/Files/Chapter80Tutorial.pdf) by Dr K. R. Bond.
+## Tutorials
+
+This folder contains text and video tutorials accompanied with slides and demo source code.
+
+- [Getting Started with Python4Delphi](https://youtu.be/hjY6lBgrHhM)
+- [Overview Video](https://youtu.be/jLuxTfct3CU)
+- [Webinar I](https://github.com/pyscripter/python4delphi/tree/master/Tutorials/Webinar%20I)
+- [Webinar II](https://github.com/pyscripter/python4delphi/tree/master/Tutorials/Webinar%20II)
+- [Introductory tutorial](https://github.com/pyscripter/python4delphi/wiki/Files/Chapter80Tutorial.pdf) by Dr K. R. Bond.
- [Another tutorial](http://www.softwareschule.ch/download/maxbox_starter86.pdf) by Max Kleiner
\ No newline at end of file
diff --git a/Tutorials/Webinar I/README.md b/Tutorials/Webinar I/README.md
index cd9d054c..fee559c1 100644
--- a/Tutorials/Webinar I/README.md
+++ b/Tutorials/Webinar I/README.md
@@ -1,12 +1,12 @@
-
-# Webinar: – Python for Delphi Developers – Part I
-
-
-
-- [Webinar Info](https://blogs.embarcadero.com/?p=55050)
-
-- [Video replay](https://youtu.be/aCz5h96ObUM)
-
-- [Slides](https://www.slideshare.net/embarcaderotechnet/python-for-delphi-developers-part-1-introduction)
-
+
+# Webinar: – Python for Delphi Developers – Part I
+
+
+
+- [Webinar Info](https://blogs.embarcadero.com/?p=55050)
+
+- [Video replay](https://youtu.be/aCz5h96ObUM)
+
+- [Slides](https://www.slideshare.net/embarcaderotechnet/python-for-delphi-developers-part-1-introduction)
+
- Source code included in this folder
\ No newline at end of file
diff --git a/Unsupported/README.md b/Unsupported/README.md
index 4613dfaf..e72ff9c6 100644
--- a/Unsupported/README.md
+++ b/Unsupported/README.md
@@ -1,6 +1,6 @@
-# Unsupported folder contents
-
-This folder contains:
-- Old and to a large extent obsolete documentation (Old docs).
-- VCL components providing python wrappers for TDataset, TBDEDataset, TTable and TQuery.
+# Unsupported folder contents
+
+This folder contains:
+- Old and to a large extent obsolete documentation (Old docs).
+- VCL components providing python wrappers for TDataset, TBDEDataset, TTable and TQuery.
(VCL folder). Deprecated and unsupported. They are superseded by WrapDelphi and WrapFireDAC.
\ No newline at end of file
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy