JuliaPy / PyCall.jl

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

PyCall hardcodes paths in ~/.julia so copying packages to another workstation with different username fails #370

Open fasiha opened 7 years ago

fasiha commented 7 years ago

The Julia manual says

For machines with no Internet connection, packages may be installed by copying the package root directory… from a machine with the same operating system and environment.

I interpreted “environment” here to mean things like GCC version, etc., but not, e.g., username.

If I install PyCall (tested on ancient CentOS 6.5, with Julia 0.5.1) for a user named fasih and then copy the resulting ~/.julia/v0.5 package to another computer where my username is fasiha (an extra a at the end), PyCall doesn’t work because the old username has been hardcoded:

[fasiha@localhost bin]$ ./julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.1 (2017-03-05 13:25 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-pc-linux-gnu

julia> using PyCall
ERROR: InitError: error compiling __init__: could not load library "/home/fasih/.julia/v0.5/Conda/deps/usr/lib/libpython2.7"
/home/fasih/.julia/v0.5/Conda/deps/usr/lib/libpython2.7.so: cannot open shared object file: Permission denied
 in _include_from_serialized(::String) at ./loading.jl:150
 in _require_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at ./loading.jl:187
 in _require_search_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at ./loading.jl:217
 in require(::Symbol) at ./loading.jl:371
during initialization of module PyCall

Note the error messages references fasih (the original username).

Ideally, PyCall and relatives can be copied from a networked computer to a computer without network access, as promised by the manual, without having to synchronize usernames.

If I try a brute-force search-and-replace, viz., in ~/.julia/v0.5/PyCall, running $ find -type f -print0 | xargs -0 sed -i 's/fasih/fasiha/g', on one system using PyCall segfaulted, though on my test virtual machine, this seems to work.

So, as far as the goal of installing PyCall (and PyPlot) on a non-networked computer, is a search-and-replace the recommended way to work around this problem, or is it possible for PyCall to avoid hardcoding paths?

Thank you!

stevengj commented 7 years ago

It would be possible for the PyCall build script to convert libpython etc. to a relative path if it is within the Pkg.dir() directory, I think.

alhirzel commented 2 years ago

Note, I have had to work around this by removing the conda/deps.jl file.