JuliaPy / PyCall.jl

Package to call Python functions from the Julia language
MIT License
1.45k stars 186 forks source link

Add `pip` support in `pyimport_conda`? #1028

Open mlhetland opened 1 year ago

mlhetland commented 1 year ago

My motivation for this is using Z3. It seems the existing wrappers for Z3^1 are stale and outdated, and at least for now, using the official Python wrappers via PyCall is a reasonable approach.

It would then be useful to be able to have it installed on demand, with pyimport_conda, but the official package is a pip package, so that doesn't currently work. However, Conda.jl supports pip.

I'm not sure one could automatically determine whether to use pip or not, based on the package, but … one could perhaps do something like the following? I've added a boolean keyword argument pip, with an associated conditional that uses Conda.pip instead of Conda.add.

function pyimport_conda(modulename::AbstractString, condapkg::AbstractString,
                        channel::AbstractString=""; pip::Bool=false)
    try
        pyimport(modulename)
    catch e
        if conda
            @info "Installing $modulename via the $(pip ? "pip" : "Conda") $condapkg package..."
            if pip
                @assert isempty(channel)
                Conda.pip_interop(true)
                Conda.pip("install", condapkg)
            else
                isempty(channel) || Conda.add_channel(channel)
                Conda.add(condapkg)
            end
            pyimport(modulename)
        else
            …
        end
    end
end

If this is a reasonable way of doing this, I'd be happy to make a PR. (Or feel free to use/adapt the suggestion above, for that matter.) Or perhaps there is some other way of achieving the same result?




mlhetland commented 1 year ago

I guess one would want to update the message in the else part, too – such as how to install things manually, etc. Not sure exactly what that should say. (E.g., one might not want a channel there either – unless I'm mistaken about the @assert, too; and one presumably should run pip via conda, rather than directly?)