This is a nice example, so I’ll run through the options in detail.
To summarise the problem, you have defined a Julia function myfunc(::Vector{Float64})
and then find that you cannot call it from Python (using JuliaCall) with a list
or numpy.ndarray
as the argument. This fails because of the default conversion rules when calling a Julia function from Python:
-
list
is converted toPyList{Py}
-
numpy.ndarray
is converted toPyArray{Float64,1}
(in this case)
Option 1 (highly recommended): As suggested in previous replies, make the signature of myfunc
more general, e.g. myfunc(::AbstractArray{<:Real})
. This is generally a good thing to do in Julia any, but in this case it means that it can be called with a PyArray{Floay64,1}
argument, so will work with numpy.ndarray
or any other Python array type. However it will still not work with list
because PyList{Py} <: AbstractVector{<:Real}
is false (because Py <: Real
is false).
Option 2: If you can’t do that, then write a Julia wrapper function
myfunc2(a::AbstractVector) = myfunc(convert(Vector{Float64}, a))
and call that instead.
Option 3: If you have done 2 or 3, then you can make it also work with lists by explicitly converting to a numpy array from Python:
jl.myfunc(np.asarray([1.0, 2.0, 3.0]))
Option 4: Or without any changes to myfunc
you could instead explicitly convert to a Vector{Float64}
from Python:
jl.myfunc(juliacall.convert(jl.Vector[jl.Float64], [1.0, 2.0, 3.0]))
Option 5: Or you can create a wrapper function which does the conversion on the Julia side:
myfunc = jl.seval("pyfunc((a::Py)->myfunc(pyconvert(Vector{Float64}, a)))")
To explain this a bit, pyfunc
wraps a Julia function into a Python function, but the arguments are not automatically converted (hence the a::Py
argument) and so you can call pyconvert
to convert them to the desired type. This option is mostly useful from the Julia side to create a Python callback function.
If I were you I’d do Option 1 and maybe Option 3. Or do Option 4.