[Lazarus] Python4Delphi/Lazarus: VarPyth: VarDataClear.. not yet supported?

Robert kxroberto at googlemail.com
Sun May 31 22:42:23 CEST 2009

Michael Van Canneyt wrote:
> On Sat, 30 May 2009, Robert wrote:
>> Michael Van Canneyt wrote:
>>> On Sat, 30 May 2009, Robert wrote:
>>>> I tried to use current http://code.google.com/p/python4delphi with
>>>> Lazarus. Did somebody use P4D successfully with recent Lazarus?
>>>> Patches? I face a few problems.
>>>> What about this problem, and what could be a workaround?
>>>> http://code.google.com/p/python4delphi/source/browse/trunk/PythonForDelphi/Components/Sources/Core/VarPyth.pas 
>>>> ### from variants.pp #########
>>>> procedure TCustomVariantType.VarDataClear(var Dest: TVarData);
>>>> begin
>>>>    NotSupported('TCustomVariantType.VarDataClear');
>>>> end;
>>>> ...
>>>> #########################
>>> I implemented some methods in TCustomVariantType (subversion of 
>>> today), but there are still quite some missing. Please test to see 
>>> if it gets you any further.
>> thanks, I took&compiled only the new variants.pp into the RTL
>> Then VarPyth.Import worked and walking/calling the Python object tree 
>> works now.
>> But any assignments to or from Python and argument passing fail.
>> pp := Import('pp');
>> pp.x.y();     // works!
>> i := pp.f();  // EVariantTypeCastError (i:Integer or LongInt)
> This needs investigation.

I used the latest laz0.9.27+fpc2.3.1 build of today 31May2009
Same problem:

  v := pp.a;        // works so far; Python-Integer to Variant
  i := v;           // Invalid Variant type cast! ; Variant to 

#0 fpc_raiseexception at :0
#3 ?? at :0
#4 ?? at :0
#5 ?? at :0
#6 $FORMS$_Ld22 at :0
#8 ?? at :0
#9 ?? at :0
#10 SYSTEM_assign$VARIANT$$LONGINT at :0
#11 ?? at :0
#12 TFORM1__FORMCREATE(0xa9048, 0xa9048) at main.pas:124
#13 TCUSTOMFORM__DOCREATE(0xa9048) at .\include\customform.inc:684
#14 TCUSTOMFORM__CREATE(0x9e1c0, 0x0, 0xa9048) at 
#15 TFORM__CREATE(0x9e1c0, 0x1, 0xa9048) at .\include\customform.inc:2371
#16 TAPPLICATION__CREATEFORM(<incomplete type>, void, 0x9e1c0) at 

A breakpoint at TPythonVariantType.DispInvoke doesn't grip here, so the 
compiler does not invoke VarPyth.pas for the conversion to Pascal.

when the returned Variant is passed back to Python as Variant, it goes 
correctly through:

  v := pp.a;        // works so far; Python-Integer to Variant
  pp.f(v);          // works!

Also it works the hard way:

  if VarIsPythonNumber(v) then
    i := PE.PyInt_AsLong( ExtractPythonObjectFrom(v) )
    raise EPyTypeError.Create('type error');

Just the Python Variant cast to Pascal type doesn't work.

>> pp.a := 99;   // TCustomVariantType.RaiseDispError not supported
>> pp.f(6);      // TCustomVariantType.RaiseDispError not supported
> These are caused by what is still missing in custom variants :-)

Yes, but the underlying problem was in VarPyth.pas, a $IFDEF FPC (Line 
~1057) due to a former FPC  restriction is dispensable meanwhile

The := 99 assignment then worked too.


And only after a strange change in VarPyth.pas of line

  //if (Length(Arguments) = 1) and VarDataIsEmptyParam(Arguments[0])


  if (Length(Arguments) = 1) and VarIsEmptyParam(Variant((Arguments[0])))

the call with paramater now works also. Before always empty parameters 
were passed to Python, though given.
VarDataIsEmptyParam() in variants.pp should do the very same simple 
transition, but it is either not reflected in the compiled unit. Or 
there is something very strange going on. When I recompile variants.pp 
in my project folder, the checksums (&number of symbols) change 
unfortunately critically...


For more than 2 arguments "pp.f(6,7)", the reverse order f(7,6) arrived 
in Python: in FPC the last argument is the first item in DispInvoke's 
´Params´ (array of TVarData).  I made a FPC-conditional inversion in 
VarPyth.pas.  Is this right? or should FPC turn to use the same internal 
1:1 ordering like Delphi ?


Named arguments "pp.f(6,7, z:=88);  "pp.f(z:=88)""  are compiled and 
executed, but it has no effect: behavior just positional, as if "z:=" 
would be not there.  The compiler-passed ´CallDesc.namedargcount´ is 
always 0.


furthermore,  while


works correctly as call, with

  v := pp.f();

the function is not called at all, but v becomes the function object 
itself !?
CallDesc^.CallType is not CDoMethod (1) , but CPropertyGet(2)
But with one or more arguments

  v := pp.f(11,22);

the function is again called correctly and v becomes correctly the 
returned thing.
>> Does it help to take more of current SVN ? or a principal problem 
>> with Typecasts?
> I'll need to check what is still missing. The variants unit could use 
> some
> cleaning up.

Thanks so far. Would be really great if the few remaining things, mainly 
the cast of Python-Variants to Pascal vars, and the assignment upon 
no-arg-call become principally possible. That Python-Lazarus bridge 
would open many doors.


More information about the Lazarus mailing list