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

Working with type instabilities, coming from PyJulia #441

Open
MilesCranmer opened this issue Jan 21, 2024 · 4 comments
Open

Working with type instabilities, coming from PyJulia #441

MilesCranmer opened this issue Jan 21, 2024 · 4 comments

Comments

@MilesCranmer
Copy link
Contributor

MilesCranmer commented Jan 21, 2024

@cjdoris Is there an automatic way to force type conversions when passing Python objects to methods? Or, in other words, is there a way to automatically convert Python arguments to their Julia counterparts?

For example I am running into this issue right now when I pass a list of integers:

>>> from juliacall import Main as jl
>>> jl.seval("f(x) = (@show typeof(x); nothing)")
Julia: f (generic function with 1 method)
>>> jl.f([1, 2, 3])
typeof(x) = PyList{Any}

which causes some issues as now f is unaware of the element type of this vector.

However, in PyJulia, arguments seem to somehow get converted automatically:

>>> from julia import Main as jl
>>> jl.eval("f(x) = (@show typeof(x); nothing)")
<PyCall.jlwrap f>
>>> jl.f([1, 2, 3])
typeof(x) = Vector{Int64}

Is there a way to get this same behavior in PythonCall?


Possibly related to #439

@MilesCranmer
Copy link
Contributor Author

Okay it seems like this was all explained here: https://juliapy.github.io/PythonCall.jl/stable/pythoncall/#Conversion-between-Julia-and-Python

and is the expected behavior. So I simply need to run a pyconvert(Vector, ...) for any mutable vector inputs when calling.

It would be great if this could be the default behavior instead of PyList{Any} - I think it is more in-line with the user expectations to have it converted to a Vector{Float32}, and of course this is what PyJulia does, so it would maintain compatibility with packages that are switching.

@cjdoris
Copy link
Collaborator

cjdoris commented Jan 25, 2024

See also https://juliapy.github.io/PythonCall.jl/stable/juliacall-reference/#juliacall.convert, which allows you to convert the object Python-side before passing it into the Julia function.

@cjdoris
Copy link
Collaborator

cjdoris commented Jan 25, 2024

Thinking more hard about the default conversion behaviour of containers is on the roadmap for PythonCall/JuliaCall v1.0. The original intent was to use wrapper types for speed and mutability, but this forces the eltype to be Any which turns out to not be useful. So 1.0 may indeed convert lists to vectors.

@MilesCranmer
Copy link
Contributor Author

MilesCranmer commented Jan 26, 2024

I think converting lists to vectors by default would be the better option for a variety of reasons. The inexperienced users are the ones most likely to shoot themselves in the foot by passing mutable objects to a Julia call, and also the least aware of the issues caused by type instability.

Experienced users will find a way to mutate lists if they need to so I think the default interface should just create a vector.

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

2 participants