Fable icon indicating copy to clipboard operation
Fable copied to clipboard

[Python] KeyValuePair object in Array is handled as only key(?)

Open HLWeil opened this issue 1 year ago • 2 comments

Description

When calling Seq.toArray on a generic Dictionary. The resulting values are typed as KeyValuePair, but only contain the key. Accessing .Key and .Value properties is transpiled as .[0] and .[1], therefore returning the first and second element of the key value, instead of returning key and value. In the case of a string key, these are the first and second char:

Repro code

test.fsx

// We start by creating a dictionary
let dict : Dictionary<string,int> = System.Collections.Generic.Dictionary()
dict.Add("one", 0)
dict.Add("two", 1)
dict.Add("three", 2)


// Full Dictionary
printfn "%A" dict
// {'one': 0, 'two': 1, 'three': 2}

// Full Array
printfn "%A" (dict |> Seq.toArray)
// ['one', 'two', 'three']

// Iter Array
dict
|> Seq.toArray
|> Array.map (fun kv -> 
    printfn "map: %s, value: %i" kv.Key kv.Value
    kv
)
|> Array.head
|> printfn "Head: %A"
// map: o, value: n
// map: t, value: w
// map: t, value: h
// Head: one

// Iter List
dict
|> Seq.toList
|> List.map (fun kv -> 
    printfn "map: %s, value: %i" kv.Key kv.Value
    kv
)
|> List.head
|> printfn "Head: %A"
// map: one, value: 0
// map: two, value: 1
// map: three, value: 2
// Head: ('one', 0)

test.cmd

dotnet fable . --lang python
python test.py

Expected and actual results

For the array case, expecting the same result as for the list case.

Related information

  • dotnet fable --version: 4.13.0
  • dotnet tool list/update/install: 4.13.0
  • Windows11

We got a performant workaround skipping the toArray step and instead initiating an Array using Array.zeroCreate.

@freymaurer

HLWeil avatar Feb 26 '24 14:02 HLWeil

I have investigated this and it's because in Fable we translate Dictionary to Python dict which will only give you the keys when you iterate it. I don't want to wrap it, so need to figure out how we can intercept the Seq.toList and know we are dealing with a Dictionary. It's currently not obvious for me how to fix this.

dbrattli avatar Apr 10 '24 05:04 dbrattli

@dbrattli Seq.toList dict results in Coerce (i.e. TypeCast) expr from Dictionary<K,V> to IEnumerable<KeyValuePair<K, V>>, so you should be able to intercept it by inspecting the left and right types in the casting around here in Fable2Python.

ncave avatar Apr 10 '24 14:04 ncave