# Assign types to a Dict returned by PyCall

**URL:** <https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113>\
**Category:** General Usage\
**Tags:** pycall\
**Created:** [February 9, 2022, 7:43pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113 "2022-02-09T19:43:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)\
**Post date:** [February 9, 2022, 7:43pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/1 "2022-02-09T19:43:41Z")

</div>

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](https://github.com/JuliaPy/PyCall.jl#pydict):

> 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
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:

```julia
PyCall v1.93.0
Julia 1.6.4

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 9, 2022, 7:47pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/2 "2022-02-09T19:47:37Z")

</div>

> [@milesf](#):
>
> `d = py"{'foo': 123, 'bar': 456}"`

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

---

<div class="post-metadata">

**Author:** ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)\
**Post date:** [February 9, 2022, 7:56pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/3 "2022-02-09T19:56:25Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 9, 2022, 8:08pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/4 "2022-02-09T20:08:44Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)\
**Post date:** [February 9, 2022, 8:10pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/5 "2022-02-09T20:10:45Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 9, 2022, 9:26pm UTC](https://discourse.julialang.org/t/assign-types-to-a-dict-returned-by-pycall/76113/6 "2022-02-09T21:26:50Z")

</div>

> [@jling](#):
>
> d = Dict{String, Int}(py"{‘foo’: 123, ‘bar’: 456}")

For reference,

```julia
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.)
