Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
HLWeil opened this issue Feb 26, 2024 · 2 comments
Open

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

HLWeil opened this issue Feb 26, 2024 · 2 comments

Comments

@HLWeil
Copy link

HLWeil commented Feb 26, 2024

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

@dbrattli
Copy link
Collaborator

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.

@ncave
Copy link
Collaborator

ncave commented Apr 10, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants