Assign types to a Dict returned by PyCall

I’m attempting to call a Python function from Julia which returns a dictionary with known types. I’d like to efficiently get a Julia dictionary with these correct types.

It seems like there should be a way to provide the expected return types, although I may be misinterpreting this section of the readme:

By default, a PyDict is an Any => Any dictionary (or actually PyAny => PyAny ) that performs runtime type inference, but if your Python dictionary has known, fixed types you can instead use PyDict{K,V} given the key and value types K and V respectively.

julia> using PyCall

julia> d = py"{'foo': 123, 'bar': 456}"
Dict{Any, Any} with 2 entries:
  "bar" => 456
  "foo" => 123

julia> d = py"{'foo': 123, 'bar': 456}" :: Dict{String, Int64}
ERROR: TypeError: in typeassert, expected Dict{String, Int64}, got a value of type Dict{Any, Any}
Stacktrace:
 [1] top-level scope
   @ ~/.julia/packages/PyCall/L0fLP/src/pyeval.jl:232

julia> d = py"{'foo': 123, 'bar': 456}" :: PyDict{String, Int64}
ERROR: TypeError: in typeassert, expected PyDict{String, Int64, isdict} where isdict, got a value of type Dict{Any, Any}
Stacktrace:
 [1] top-level scope
   @ ~/.julia/packages/PyCall/L0fLP/src/pyeval.jl:232

Versions:

PyCall v1.93.0
Julia 1.6.4

d = Dict{String, Int}(py"{‘foo’: 123, ‘bar’: 456}")

1 Like

Thanks, I was concerned that passing the pycall result to a constructor or convert would cause two copies:

  1. Python dict → Julia Dict{Any, Any}
  2. Julia Dict{Any, Any} → Julia Dict{String, Int64}

Any suggestions on how to confirm whether this is the case?

Does it matter? Like do you really care this little overhead on the grand schemes of things like you’re using python?

Probably doesn’t matter. Just trying to be efficient where possible and have a better understanding of what the code is doing.

For reference,

PyDict{String, Int}(py"{'foo': 123, 'bar': 456}"o)

make no copies at all — it’s just a thin wrapper around the underlying Python dictionary. (Note the py"..."o, where the o suppresses automatic conversion and instead gives a raw Python object.)

3 Likes