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

Trouble Converting Collections from Python to Julia #231

Closed
mrufsvold opened this issue Oct 12, 2022 · 4 comments
Closed

Trouble Converting Collections from Python to Julia #231

mrufsvold opened this issue Oct 12, 2022 · 4 comments

Comments

@mrufsvold
Copy link

I'm sure I'm just overlooking something in the docs, so I'm sorry for the redundant question!

I have a dictionary in Python that I'd like to pass into a Julia function. But it is getting converted to type PyCall.PyDict{Pycall.Py,Pycall.Py}. I tried to explicitly convert using PyCall.convert(Dict{String, Any}, my_python_dict) but it throws:

MethodError: Cannot `convert` an object of type PythonCall.Py to an object of type String

MWE:

from juliacall import Main as jl
d = {"a" : 1}
jl.typeof(d)
# <jl PythonCall.PyDict{PythonCall.Py, PythonCall.Py}>

Just to double check, I also tried jl.typeof("a") and got String back.

Any thoughts on how to get the dictionary into a Julia Dict?

@cjdoris
Copy link
Collaborator

cjdoris commented Oct 12, 2022

You want PythonCall.pyconvert, or its equivalent juliacall.convert from Python.

@mrufsvold
Copy link
Author

Thank you!

@ShuhuaGao
Copy link
Contributor

Could you please give a specific example? @cjdoris
For example, I have a d = {"Hello": [1, 2, 3, 4]} in Python, and I want to pass it into a Julia function

function examine(d::AbstractDict{<:AbstractString,<:AbstractVector})
    return length(first(d).second)
end

Did not figure out how to do it.

@cjdoris
Copy link
Collaborator

cjdoris commented Mar 19, 2023

@ShuhuaGao your issue is that the type signature is too specific:

>>> from juliacall import Main as jl
>>> d = {"Hello": [1, 2, 3, 4]}
>>> jl.typeof(d)
Julia: PythonCall.PyDict{Any, Any}

As you can see, the dict is automatically converted to a PyDict{Any,Any}, which does not match the type signature of your function.

You can use juliacall.convert to instead convert to a specific type:

>>> from juliacall import convert as jlconvert
>>> jl.typeof(jlconvert(jl.PythonCall.PyDict[jl.String, jl.Vector[jl.Int]], d))
Julia: PythonCall.PyDict{String, Vector{Int64}}

(replace jl.PythonCall.PyDict with jl.Dict if you like).

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