You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PyJulia does not work with Julia 1.0 & 0.7 with Python installed via Conda/Ubuntu/(what else?) #185
I'm writing down the issue so that it is easy to find by the users.
At the moment, for PyJulia to load Julia >= 0.7, two conditions have to be met:
Python interpreter configured for PyCall.jl and Python interpreter used to import PyJulia have to use identical libpython (once Support virtualenv/venv without separate cache #190 is merged) have exactly identical paths.
The Python interpreter have to be dynamically linked (which is usually the case in Windows and macOS according to this comment)
I think I know how to fix it #173. But likely not in next weeks. I can't grant anything :) If I were to do it I want to do it after dropping Julia 0.6 (which requires PyJulia to be released soon).
Reacted by Xiang Hong, Páll Haraldsson, Philippe Roy and Brandon H. Gomes
It implements the private DEPOT_PATH hack mentioned in #173 but does so per-virtualenv basis. This let us use different Python executables without recompiling PyCall.jl all the time. On top of creating a private DEPOT_PATH, it installs a CLI julia-venv which acts like the normal julia interpreter (by invoking it via C API from Python). This way, we can run PyCall.jl always in "PyJulia-mode" so that the issue with Python in Ubuntu/Debian and Conda can be avoided (https://github.com/tkf/julia-venv#how-it-works). As a nice side-effect, you can also use PyCall.jl with different Python executable and different set of Python libraries.
Edit: Actually, julia-venv probably still doesn't work with Conda (and probably also with Ubuntu): tkf/julia-venv#2 Edit^2: It works now.
@tkf ,thanks for your awesome work. The new package works on Ubuntu 16.04 with anaconda. It really helps.
There are some minor suggestions (or some misunderstanding of me).
third-party packages need to be re-compiled/re-installed
for test purpose, I test from julia import NPZ, while NPZ is already added in original julia environment. But it failed.
and the following code works:
from julia import Pkg
Pkg.add("NPZ")
#... some install outputs
from julia import NPZ
data = NPZ.npzread("path")
It seems that pyjulia and julia of system is using different package cache? I think re-install packages is not a problem and it might be a valuable feature. I only suggest add some doc for this
convenient broadcast call
broadcast is commonly used in julia, but Main.abs.([1,2,3]) is a SyntaxError in python.
in README.md of pyjulia, there is
Main.eval("sin.(xs)")
which seems that pyjulia will not expose broadcast method to python level. I'm not sure if I am right, but if it is true, I'm thinking is it possible to adding some special syntax like Main.abs.broadcast([1,2,3]) or in short Main.abs.b([1,2,3]) (although may introduce some confusing to sum_b for python version sum!).
InterruptException() handling
When I press ctrl-C in python REPL, there would be a small problem.
If I'm using a pure python REPL, it should work like this
>>> # presss ctrl-C here
KeyboardInterrupt
>>>
But in a python REPL which loaded julia, it would work like this:
>>> # press ctrl-C here
and nothing happens, after that if I enter next command
>>> # Ctrl - C, and nothing happens
>>> Main.xs = [1,2,3] # Enter, change line and type new command and Enter I got:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "(path_anaconda)/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 140, in __setattr__
self._julia.eval(setter)(value)
File "(path_anaconda)/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 606, in eval
ans = self._call(src)
File "(path_anaconda)/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 562, in _call
self.check_exception(src)
File "(path_anaconda)/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 589, in check_exception
.format(exception, src))
julia.core.JuliaError: Exception 'InterruptException' occurred while calling julia code:
PyCall.pyfunctionret(
(x) -> eval(Main, :(xs = $x)),
Any,
PyCall.PyAny)
It seems the InterruptException is send to julia in one delayed statement?
@Hong-Xiang Hey, thanks for the feedback. Are you using julia-venv in Ubuntu or Debian? Did it actually work?
I think re-install packages is not a problem and it might be a valuable feature.
Yeah, something like virtualenv's --system-site-packages would be nice. I actually did that in first versions but stopped doing that since I encountered with some quirks in julia's package handling. It it actually as "easy" as replacing depots = filter(!isequal(default_depot1), __py_julia_venv_orig_DEPOT_PATH) with depots = copy(__py_julia_venv_orig_DEPOT_PATH).
convenient broadcast call
I started experimenting more numpy-like interface on top of PyJulia (i.e., broadcast operations on arrays by default):
But if you want to leverage Julia, I think it's better to just use Julia syntax. If you don't want to use global variable (of course), you can do:
Main.eval("(xs) -> sin.(exp.(xs) .+ 1)")(xs)
or equivalently
Main.eval("(xs) -> @. sin(exp(xs) + 1)")(xs)
Unlike numpy.exp etc., it doesn't allocate intermediate arrays.
InterruptException
Hmm... I didn't notice that. But yes, I can reproduce it. Actually, I just noticed that it's reported in #189. Let's track the issue there.
It looks like IPython 7 (development version) handle ctrl-C differently and it doesn't have this problem. I've been using it so I didn't notice the problem.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
and actually it's Ubuntu Mate.
conda:
$ conda --version
conda 4.3.30
python(in conda virutal env, withjulia-venv)
$ source activate juliaenv
(juliaenv) $ which python
(home path)/anaconda3/envs/juliaenv/bin/python
(juliaenv) $ python
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from julia_venv import get_julia
>>> get_julia()
<julia.core.Julia object at 0x7f66c6cc7f28>
>>> from julia import Main
it worked, without error.
python(in conda virtual env, withoutjulia-venv)
(juliaenv) $ python
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from julia import Main
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 646, in _load_unlocked
File "<frozen importlib._bootstrap>", line 616, in _load_backward_compatible
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 172, in load_module
JuliaMainModule(self, fullname))
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 77, in __init__
self._julia = loader.julia
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 164, in julia
self.__class__.julia = julia = Julia()
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 496, in __init__
"\"lib\", \"pyjulia%s-v$(VERSION.major).$(VERSION.minor)\"))" % sys.version_info[0])
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 562, in _call
self.check_exception(src)
File "(home path)/anaconda3/envs/juliaenv/lib/python3.6/site-packages/julia/core.py", line 589, in check_exception
.format(exception, src))
julia.core.JuliaError: Exception 'UndefVarError' occurred while calling julia code:
unshift!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot(),"lib", "pyjulia3-v$(VERSION.major).$(VERSION.minor)"))
>>>
tests like using standard libraries, basic array operations and even third-party packages like NPZ is performed, and it seems just worked, as mentioned above.
Is there any further tests I can do for this?
Thanks. Interesting... Actually, the problem I thought I had was already fixed tkf/julia-venv#2. My guess was that it was some kind of IO caching issue (compilation file was not properly written before exiting the problem). It then maybe explains why it's machine-dependent.
For Ubuntu/Debian users, probably the cleanest and relatively easy way to use PyJulia at the moment is to install (build) Python using pyenv. But you need to pass --enable-shared manually.
@ExpandingMan@mprogram So it turned out static linking is just the default behavior of Python's ./configure script (see my message above #185 (comment)). I guess Debian is not doing anything particularly evil here.
Thanks, @tkf for your last two comments. I'm a fan of deb-based system and my thought would be that Debian needs to look at those. If I'll be up to recompile Python (for the sake of optimization with MKL, for example as Julia does), I would include the --enable-shared option in my build.
This problem is not going to go away, Debian is not going to change it and lots and lots of people are going to try this as debian distros are the most popular (though I prefer Arch I still have to use them often myself). My first question is how other languages solve this problem. We can't be the first people ever to want to use a dynamically linked Python executable. It would be good to see how Scala and Java solve this, though I haven't started looking yet.
I think at a minimum what we need is a very clear set of the simplest possible steps that one would take to get pyjulia running on debian in a very visible location right in the packages readme or documentation. Thanks to @tkf to taking the first steps to this with his pyenv setup, I'm going to try it myself when I get a chance.
Reacted by Noah Stier, Zachary Sunberg, Philippe Roy, Brandon H. Gomes and Jasha Sommer-Simpson
If you are using Conda you are already not using the system Python binaries. In the other cases, I agree there is still need for python-jl. Also, there can still be issues with python-jl#208.
@bstellato Thanks!. This is a good news! So I guess conda-forge distributes a Python executable dynamically linked to libpython. I'll add it to the documentation.
@ExpandingMan Yeah, I think python-jl should stay. Another benefit of python-jl is that signal handler is slightly well behaved this way (libjulia "steals" signal handler from python#211).
/Users/xxx/miniconda3/envs/testpyjulia37/bin/python:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1153.18.0)
@rpath/libpython3.7m.dylib (compatibility version 3.7.0, current version 3.7.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
I just merged #256 to master. I think PyJulia is now usable with many CPython executables if you can compile a custom system image with python3 -m julia.sysimage command. The bonus point is that this makes PyJulia startup virtually instantaneous. See: https://pyjulia.readthedocs.io/en/latest/sysimage.html
Hi @tkf - it's annoying having to deal with this issue. Do you know which Linux distro (ideally docker container) that provides a dynamically linked Python?
IIRC, the official python docker works. It's a bit old, but here is an example for setting up PyJulia in Docker: https://github.com/tkf/docker-pyjulia
Also, just FYI, I started working on compile-time preference integration for PyCall JuliaPy/PyCall.jl#835. If it works as I expected, PyJulia should just work without any hacks in Julia 1.6 and above. Obviously, there are still some unknowns as I haven't finished implementing all. So, let's see ;)
Just FYI, it seems that also python-build-standalone is considering switching to static builds of python for performance gains: astral-sh/python-build-standalone#540 .
Just FYI, it seems that also python-build-standalone is considering switching to static builds of python for performance gains: astral-sh/python-build-standalone#540 .
Ah, it seems that this package is now deprecated, so it may not be a big problem: #556 .
Activity
mprogram commentedon Aug 18, 2018
This was very helpful; thank you, @tkf
I must say I was very-very surprised by not finding
libpython3in myldd $(which python3)output.Debian/Ubuntu packagers are the known strong advocates against linking things statically; but doing so in
python/3?!?!tkf commentedon Aug 19, 2018
Yeah, I was surprised too. I thought it was just conda (in which static compilation maybe makes sense).
Hong-Xiang commentedon Aug 21, 2018
@tkf Thanks for your reply. But there are still some questions:
Thanks.
tkf commentedon Aug 21, 2018
I think there are three ways to use Python with Julia 1.0 on Ubuntu/Debian/etc. at the moment:
IPython.jl/src/core.jl.I think I know how to fix it #173. But likely not in next weeks. I can't grant anything :) If I were to do it I want to do it after dropping Julia 0.6 (which requires PyJulia to be released soon).
tkf commentedon Sep 5, 2018
I made an experimental package
julia-venv: https://github.com/tkf/julia-venvIt implements the private
DEPOT_PATHhack mentioned in #173 but does so per-virtualenv basis. This let us use different Python executables without recompiling PyCall.jl all the time. On top of creating a privateDEPOT_PATH, it installs a CLIjulia-venvwhich acts like the normaljuliainterpreter (by invoking it via C API from Python). This way, we can run PyCall.jl always in "PyJulia-mode" so that the issue with Python in Ubuntu/Debian and Conda can be avoided (https://github.com/tkf/julia-venv#how-it-works). As a nice side-effect, you can also use PyCall.jl with different Python executable and different set of Python libraries.Edit: Actually,Edit^2: It works now.julia-venvprobably still doesn't work with Conda (and probably also with Ubuntu): tkf/julia-venv#2Hong-Xiang commentedon Sep 5, 2018
@tkf ,thanks for your awesome work. The new package works on Ubuntu 16.04 with anaconda. It really helps.
There are some minor suggestions (or some misunderstanding of me).
third-party packages need to be re-compiled/re-installed
for test purpose, I test
from julia import NPZ, whileNPZis already added in original julia environment. But it failed.and the following code works:
It seems that pyjulia and julia of system is using different package cache? I think re-install packages is not a problem and it might be a valuable feature. I only suggest add some doc for this
convenient broadcast call
broadcast is commonly used in julia, but
Main.abs.([1,2,3])is aSyntaxErrorin python.in
README.mdof pyjulia, there iswhich seems that pyjulia will not expose broadcast method to python level. I'm not sure if I am right, but if it is true, I'm thinking is it possible to adding some special syntax like
Main.abs.broadcast([1,2,3])or in shortMain.abs.b([1,2,3])(although may introduce some confusing tosum_bfor python versionsum!).InterruptException()handlingWhen I press
ctrl-Cin python REPL, there would be a small problem.If I'm using a pure python REPL, it should work like this
But in a python REPL which loaded julia, it would work like this:
and nothing happens, after that if I enter next command
It seems the
InterruptExceptionis send to julia in one delayed statement?tkf commentedon Sep 5, 2018
@Hong-Xiang Hey, thanks for the feedback. Are you using
julia-venvin Ubuntu or Debian? Did it actually work?Yeah, something like
virtualenv's--system-site-packageswould be nice. I actually did that in first versions but stopped doing that since I encountered with some quirks injulia's package handling. It it actually as "easy" as replacingdepots = filter(!isequal(default_depot1), __py_julia_venv_orig_DEPOT_PATH)withdepots = copy(__py_julia_venv_orig_DEPOT_PATH).I started experimenting more numpy-like interface on top of PyJulia (i.e., broadcast operations on arrays by default):
https://ipyjulia-hacks.readthedocs.io/en/latest/
Not sure if it is suitable for PyJulia, though.
But if you want to leverage Julia, I think it's better to just use Julia syntax. If you don't want to use global variable (of course), you can do:
or equivalently
Unlike
numpy.expetc., it doesn't allocate intermediate arrays.Hmm... I didn't notice that. But yes, I can reproduce it. Actually, I just noticed that it's reported in #189. Let's track the issue there.
It looks like IPython 7 (development version) handle ctrl-C differently and it doesn't have this problem. I've been using it so I didn't notice the problem.
Hong-Xiang commentedon Sep 5, 2018
@tkf my system/environment info is:
and actually it's Ubuntu Mate.
conda:
python(in conda virutal env, with
julia-venv)it worked, without error.
python(in conda virtual env, without
julia-venv)tests like using standard libraries, basic array operations and even third-party packages like
NPZis performed, and it seems just worked, as mentioned above.Is there any further tests I can do for this?
tkf commentedon Sep 5, 2018
Thanks. Interesting... Actually, the problem I thought I had was already fixed tkf/julia-venv#2. My guess was that it was some kind of IO caching issue (compilation file was not properly written before exiting the problem). It then maybe explains why it's machine-dependent.
Anyway, I'm glad that it worked in your machine!
tkf commentedon Sep 12, 2018
For Ubuntu/Debian users, probably the cleanest and relatively easy way to use PyJulia at the moment is to install (build) Python using pyenv. But you need to pass
--enable-sharedmanually.tkf commentedon Sep 12, 2018
Or you can switch to Arch Linux 😆
It uses
--enable-shared: https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/python&id=68e188a1f975dcc6798072bcda4ef35abfe162ed#n57tkf commentedon Sep 12, 2018
@ExpandingMan @mprogram So it turned out static linking is just the default behavior of Python's
./configurescript (see my message above #185 (comment)). I guess Debian is not doing anything particularly evil here.mprogram commentedon Sep 12, 2018
Thanks, @tkf for your last two comments. I'm a fan of deb-based system and my thought would be that Debian needs to look at those. If I'll be up to recompile Python (for the sake of optimization with MKL, for example as Julia does), I would include the
--enable-sharedoption in my build.tkf commentedon Sep 12, 2018
@mprogram It looks like pyenv does something more than passing
--enable-sharedto./configure:I didn't check if
./configure --enable-sharedwas enough when building withoutpyenv.ExpandingMan commentedon Sep 12, 2018
This problem is not going to go away, Debian is not going to change it and lots and lots of people are going to try this as debian distros are the most popular (though I prefer Arch I still have to use them often myself). My first question is how other languages solve this problem. We can't be the first people ever to want to use a dynamically linked Python executable. It would be good to see how Scala and Java solve this, though I haven't started looking yet.
I think at a minimum what we need is a very clear set of the simplest possible steps that one would take to get
pyjuliarunning on debian in a very visible location right in the packages readme or documentation. Thanks to @tkf to taking the first steps to this with his pyenv setup, I'm going to try it myself when I get a chance.8 remaining items
bstellato commentedon Oct 25, 2018
If you are using Conda you are already not using the system Python binaries. In the other cases, I agree there is still need for
python-jl. Also, there can still be issues withpython-jl#208.ExpandingMan commentedon Oct 25, 2018
Agreed, let's just aim to document as many options as possible and people will be able to select whatever solution works best for them.
tkf commentedon Oct 25, 2018
@bstellato Thanks!. This is a good news! So I guess
conda-forgedistributes a Python executable dynamically linked to libpython. I'll add it to the documentation.@ExpandingMan Yeah, I think
python-jlshould stay. Another benefit ofpython-jlis that signal handler is slightly well behaved this way (libjulia "steals" signal handler frompython#211).tkf commentedon Oct 26, 2018
It's a bit strange. 3.7.0 from conda-forge is statically linked:
But
conda-forge::python=3.6is dynamically linked.bstellato commentedon Oct 26, 2018
Version 3.7.0 is still dynamically linked for me on mac os.
I get
Also,
tkf commentedon Oct 26, 2018
Interesting. I asked the question in conda-forge: conda-forge/python-feedstock#222
tkf commentedon Oct 26, 2018
I wrote README in #210 and you can read it here: https://github.com/tkf/pyjulia/blob/readme/README.md
@ExpandingMan If you are interested, have a look at Troubleshooting and pre-compilation mechanism sections:
https://github.com/tkf/pyjulia/blob/readme/README.md#troubleshooting
https://github.com/tkf/pyjulia/blob/readme/README.md#pre-compilation-mechanism-in-julia-10
tkf commentedon Apr 12, 2019
I just merged #256 to master. I think PyJulia is now usable with many CPython executables if you can compile a custom system image with
python3 -m julia.sysimagecommand. The bonus point is that this makes PyJulia startup virtually instantaneous. See: https://pyjulia.readthedocs.io/en/latest/sysimage.htmltk3369 commentedon Sep 25, 2020
Hi @tkf - it's annoying having to deal with this issue. Do you know which Linux distro (ideally docker container) that provides a dynamically linked Python?
tkf commentedon Sep 25, 2020
It works in Arch Linux :)
IIRC, the official
pythondocker works. It's a bit old, but here is an example for setting up PyJulia in Docker: https://github.com/tkf/docker-pyjuliaAlso, just FYI, I started working on compile-time preference integration for PyCall JuliaPy/PyCall.jl#835. If it works as I expected, PyJulia should just work without any hacks in Julia 1.6 and above. Obviously, there are still some unknowns as I haven't finished implementing all. So, let's see ;)
Ge0rges commentedon Nov 1, 2022
What's the status of this issue? I am trying to run PyJulia in Ubuntu 22 but python is statically linked.
EmanuelCastanho commentedon Aug 16, 2023
Is it possible to build my own Python with
--enable-sharedin Conda?mkitti commentedon Aug 16, 2023
I think that might be a question for conda-forge. If you are going to compile it yourself, do you actually need conda though?
Perhaps we could use https://github.com/JuliaBinaryWrappers/Python_jll.jl
traversaro commentedon Feb 27, 2025
Just FYI, it seems that also
python-build-standaloneis considering switching to static builds of python for performance gains: astral-sh/python-build-standalone#540 .traversaro commentedon Feb 27, 2025
Ah, it seems that this package is now deprecated, so it may not be a big problem: #556 .