Fable
Fable copied to clipboard
[Python] KeyValuePair object in Array is handled as only key(?)
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.0dotnet 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
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
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.