View Issue Details

IDProjectCategoryView StatusLast Update
0020849FPCRTLpublic2021-01-31 21:28
ReporterKiriakos Assigned ToMarco van de Voort  
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.4.4 
Fixed in Version3.3.1 
Summary0020849: VarCast fails on Custom Variants
DescriptionVar
  MyV, V : Variants;

begin
  //Set My to a custom variant that implements Cast and CastTo and knows how
  // to convert itself to an integer
  VarCast(V1, MyV, varinteger); // <-- raises an exception (Type Mismatch)

The reason is that VariantToLongInt (and all similar routines) in cvarutil.inc do not take account of custom variants. If you look at the implementation of the corresponding function in Delphi _VarToInteger if the simple conversion fails, it calls VarToIntCustom that then calls the CastTo function of the custom variant. Delphi implements a series of VarToXXXCustom that handle simple type conversions.

This issue reduces drastically the usability of Custom Variants, since you cannot convert their values to simple types.

The same issue also exists in FPC 2.5.1.
Tagscustom variants, variants
Fixed in Revision48477
FPCOldBugId
FPCTarget-
Attached Files

Relationships

related to 0038429 closedSven Barth TCustomVariantType.CastTo() is not called 

Activities

Marco van de Voort

2011-12-09 10:57

manager   ~0054860

2.5.1 is a development version, and ca be a lot. From when is your 2.5.1?
Does it work with 2.6.0RC1 or trunk (2.7.1) ?

_OR_

do you have a compiling example so we can easily test/triage this ourselves

Marco van de Voort

2012-01-04 15:49

manager   ~0055475

See above.

Kiriakos

2012-01-30 21:39

reporter   ~0056174

The issue exists in trunk.
i.e.
in VarCast (variants.pp)

       varInteger: SysVarFromInt(Variant(aDest), VariantToLongInt(aSource), -4);

in cvarutil.inc
Function VariantToLongInt(const VargSrc : TVarData) : LongInt;
..
  with VargSrc do
    case vType and not varTypeMask of
      0: case vType of
        varEmpty : Result := 0;
        varSmallInt : Result := vSmallInt;
        varShortInt : Result := vShortInt;
        varInteger : Result := vInteger;
{$ifndef FPUNONE}
        varSingle : Result := longint(Round(vSingle));
        varDouble : Result := longint(Round(vDouble));
        varDate : Result := longint(Round(vDate));
{$endif}
        varCurrency : Result := longint(Round(vCurrency));
        varBoolean : Result := SmallInt(vBoolean);
        varVariant : Result := VariantToLongInt(PVarData(vPointer)^);
        varByte : Result := vByte;
        varWord : Result := vWord;
        varLongWord : Result := longint(vLongWord);
        varInt64 : Result := longint(vInt64);
        varQword : Result := longint(vQWord);
        varOleStr : Result := WStrToLongInt(vOleStr);
        varString : Result := LStrToLongInt(vString);
        varUString : Result := UStrToLongInt(vString);
      else
        VariantTypeMismatch(vType, varInteger);
      end;
...

i.e. no effort is made to convert VargSrc to integer if it is a custom variant.

Sergei Gorelkin

2012-01-31 07:14

developer   ~0056182

The problem here is bad design of surrounding code. Handling custom variants in varutils will create circular dependence on variants unit. Handling them in variants can only be inserted before handling standard types, but this will harm performance of standard types.

The correct way would be to rewrite VariantToxxx routines in varutils so they return a error code instead of raising an exception, and handle custom variants in variants unit *after* the standard ones. I have this planned for a while already, but didn't come to it closer yet.

cjrh

2014-02-06 02:51

reporter   ~0072871

[I did not yet check whether current trunk has this fixed, but it is occurring in my FPC 2.6.2 in Lazarus 1.2RC2]

I suspect this issue might also affect the FPC support in the python4delphi project. You can see it in the demo project in path

PythonForDelphi/Demos/FPC/Demo25

In unit1.pas, in the following lines [56]:

procedure TForm1.btnTestIntegersClick(Sender: TObject);
var
  a, b, c : Variant;
  big : Int64;
begin
  // initialize the operands
  a := VarPythonCreate(2);
  Assert(VarIsPython(a));
  Assert(VarIsPythonNumber(a));
  Assert(VarIsPythonInteger(a));
  Assert(Integer(a) = 2); // <=== *** ERROR ***

  b := VarPythonCreate(3);
  Assert(VarIsPython(b));
  Assert(VarIsPythonNumber(b));
  Assert(VarIsPythonInteger(b));
  Assert(Integer(b) = 3); // <=== *** ERROR ***

The error states:

Project project1.exe raised exception class 'EVariantError' with message:
Invalid variant type cast

In file '.\Sources\Core\VarPyth.pas' at line 366:
Result := (TVarData(AValue).VType and varTypeMask) = VarPython;

By the way, the rest of the python4delphi functionality (based on these demo projects) works pretty well in lazarus. It seems to be just these variant issues.

Kiriakos

2020-02-16 05:44

reporter   ~0121116

Still present in version 3.04. No progress in resolving this issue six years after reporting it. Very disappointing.

Regarding replication see previous comment. Install Python4Delphi from https://github.com/pyscripter/python4delphi and run PythonForDelphi/Demos/FPC/Demo25.

NoName

2020-02-16 13:47

reporter   ~0121121

I assume it would help if you attach a small test project without any dependencies which shows the wrong behaviour instead of pointing to a huge 3rd party project.
Who knows, maybe the bug is simply in the code from python4delphi.

Florian

2020-02-16 13:53

administrator   ~0121122

No reason to be disappointed, FPC is open source, everyone can fix bugs. Just go ahead and make a patch.

Marco van de Voort

2020-03-28 16:32

manager   ~0121745

Last edited: 2020-03-28 18:05

View 2 revisions

- still no easy reproduction.

I tried to compile python4delphi as directed (with FPC 3.2 stable branch), but it fails on variants being passed to "nativeint" parameters, varpyth.setobjectitem (lines 1464 and 66 and 70) methods pylist_setitem, PyTuple_SetItem and PySequence_SetItem

zbyna

2020-12-27 19:31

reporter   ~0127835

I had a simillar problem during compiling pytnon4delphi. This helped me: https://github.com/zbyna/python4delphi/commit/2fd1b9d207ebac2301350d25318f5b5695c53c8c

Sven Barth

2021-01-31 21:28

manager   ~0128717

This should be fixed with the fix for 0038429 as well.

Please test and close if okay.

Issue History

Date Modified Username Field Change
2011-12-09 05:19 Kiriakos New Issue
2011-12-09 10:57 Marco van de Voort Note Added: 0054860
2012-01-04 15:49 Marco van de Voort Note Added: 0055475
2012-01-04 15:49 Marco van de Voort Status new => feedback
2012-01-30 21:39 Kiriakos Note Added: 0056174
2012-01-31 07:14 Sergei Gorelkin Note Added: 0056182
2014-02-06 02:51 cjrh Note Added: 0072871
2020-02-16 05:44 Kiriakos Note Added: 0121116
2020-02-16 05:44 Kiriakos Status feedback => new
2020-02-16 13:47 NoName Note Added: 0121121
2020-02-16 13:53 Florian Note Added: 0121122
2020-03-28 16:32 Marco van de Voort Assigned To => Marco van de Voort
2020-03-28 16:32 Marco van de Voort Status new => feedback
2020-03-28 16:32 Marco van de Voort FPCTarget => -
2020-03-28 16:32 Marco van de Voort Note Added: 0121745
2020-03-28 18:05 Marco van de Voort Note Edited: 0121745 View Revisions
2020-12-27 19:31 zbyna Note Added: 0127835
2021-01-31 17:50 Sven Barth Tag Attached: variants
2021-01-31 17:50 Sven Barth Tag Attached: custom variants
2021-01-31 17:53 Sven Barth Relationship added related to 0038429
2021-01-31 21:28 Sven Barth Status feedback => resolved
2021-01-31 21:28 Sven Barth Resolution open => fixed
2021-01-31 21:28 Sven Barth Fixed in Version => 3.3.1
2021-01-31 21:28 Sven Barth Fixed in Revision => 48477
2021-01-31 21:28 Sven Barth Note Added: 0128717