diff --git a/.travis.yml b/.travis.yml index 127b5324..1c032ac7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ python: env: matrix: - JULIA_VERSION=0.6.4 CROSS_VERSION=1 - - JULIA_VERSION=0.7.0-rc2 + - JULIA_VERSION=1.0.0 # - JULIA_VERSION=nightly global: - TOXENV=py @@ -17,7 +17,7 @@ matrix: - language: generic env: - PYTHON=python2 - - JULIA_VERSION=0.7.0-rc2 + - JULIA_VERSION=1.0.0 # - JULIA_VERSION=nightly os: osx - language: generic @@ -29,7 +29,7 @@ matrix: - language: generic env: - PYTHON=python3 - - JULIA_VERSION=0.7.0-rc2 + - JULIA_VERSION=1.0.0 # - JULIA_VERSION=nightly os: osx - language: generic @@ -54,7 +54,7 @@ before_script: - which $PYTHON - $PYTHON -m pip --version - $PYTHON -m pip install --quiet tox - - julia -e 'Pkg.add("PyCall")' + - julia --color=yes -e 'VERSION >= v"0.7.0-DEV.5183" && using Pkg; Pkg.add("PyCall")' script: # "py,py27" below would be redundant when the main interpreter is diff --git a/appveyor.yml b/appveyor.yml index 193efc50..85651094 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -63,7 +63,15 @@ build_script: # - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.add(\"PyCall\"); Pkg.init(); Pkg.resolve()" # - C:\projects\julia\bin\julia -e "using PyCall; @assert isdefined(:PyCall); @assert typeof(PyCall) === Module" - "SET PYTHON=%PYTHONDIR%\\python.exe" - - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.add(\"PyCall\")" + - C:\projects\julia\bin\julia -e " + if VERSION >= v\"0.7.0-DEV.3630\"; + using InteractiveUtils; + versioninfo(verbose=true); + else + versioninfo(true); + end; + VERSION >= v\"0.7.0-DEV.5183\" && using Pkg; + Pkg.add(\"PyCall\")" - "%PYTHONDIR%\\python.exe -m pip install --quiet tox" test_script: diff --git a/julia/core.py b/julia/core.py index 959d8d96..b97f033c 100644 --- a/julia/core.py +++ b/julia/core.py @@ -262,14 +262,21 @@ def juliainfo(runtime='julia'): [runtime, "-e", """ println(VERSION < v"0.7.0-DEV.3073" ? JULIA_HOME : Base.Sys.BINDIR) + if VERSION >= v"0.7.0-DEV.3630" + using Libdl + using Pkg + end println(Libdl.dlpath(string("lib", splitext(Base.julia_exename())[1]))) println(unsafe_string(Base.JLOptions().image_file)) - PyCall_depsfile = Pkg.dir("PyCall","deps","deps.jl") - if isfile(PyCall_depsfile) - eval(Module(:__anon__), - Expr(:toplevel, - :(Main.Base.include($PyCall_depsfile)), - :(println(pyprogramname)))) + if VERSION < v"0.7.0" + PyCall_depsfile = Pkg.dir("PyCall","deps","deps.jl") + else + modpath = Base.locate_package(Base.identify_package("PyCall")) + PyCall_depsfile = joinpath(dirname(modpath),"..","deps","deps.jl") + end + if PyCall_depsfile !== nothing && isfile(PyCall_depsfile) + include(PyCall_depsfile) + println(pyprogramname) end """]) args = output.decode("utf-8").rstrip().split("\n") @@ -342,7 +349,7 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None, runtime = jl_runtime_path else: runtime = 'julia' - JULIA_HOME, libjulia_path, image_file, depsjlexe = juliainfo() + JULIA_HOME, libjulia_path, image_file, depsjlexe = juliainfo(runtime) self._debug("pyprogramname =", depsjlexe) self._debug("sys.executable =", sys.executable) exe_differs = is_different_exe(depsjlexe, sys.executable) diff --git a/julia/with_rebuilt.py b/julia/with_rebuilt.py index 7c4b7cac..902adfd4 100644 --- a/julia/with_rebuilt.py +++ b/julia/with_rebuilt.py @@ -8,6 +8,7 @@ from __future__ import print_function, absolute_import import os +import signal import subprocess import sys from contextlib import contextmanager @@ -21,7 +22,12 @@ def maybe_rebuild(rebuild, julia): env = os.environ.copy() info = juliainfo(julia) - build = [julia, '-e', 'Pkg.build("PyCall")'] + build = [julia, '-e', """ + if VERSION >= v"0.7.0-DEV.3630" + using Pkg + end + Pkg.build("PyCall") + """] print('Building PyCall.jl with PYTHON =', sys.executable) print(*build) sys.stdout.flush() @@ -29,6 +35,7 @@ def maybe_rebuild(rebuild, julia): try: yield finally: + print() # clear out messages from py.test print('Restoring previous PyCall.jl build...') print(*build) if info.pyprogramname: @@ -42,8 +49,29 @@ def maybe_rebuild(rebuild, julia): yield +@contextmanager +def ignoring(sig): + """ + Context manager for ignoring signal `sig`. + + For example,:: + + with ignoring(signal.SIGINT): + do_something() + + would ignore user's ctrl-c during ``do_something()``. This is + useful when launching interactive program (in which ctrl-c is a + valid keybinding) from Python. + """ + s = signal.signal(sig, signal.SIG_IGN) + try: + yield + finally: + signal.signal(sig, s) + + def with_rebuilt(rebuild, julia, command): - with maybe_rebuild(rebuild, julia): + with maybe_rebuild(rebuild, julia), ignoring(signal.SIGINT): print('Execute:', *command) return subprocess.call(command) diff --git a/test/test_core.py b/test/test_core.py index ed998d9b..b1760342 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -12,6 +12,8 @@ import sys import os +import pytest + python_version = sys.version_info @@ -56,7 +58,7 @@ def add(a, b): self.assertTrue(all(x == y for x, y in zip([11, 11, 11], julia.map(lambda x: x + 1, array.array('I', [10, 10, 10]))))) - self.assertEqual(6, julia.foldr(add, 0, [1, 2, 3])) + self.assertEqual(6, julia.reduce(add, [1, 2, 3])) def test_call_python_with_julia_args(self): self.assertEqual(6, sum(julia.eval('(1, 2, 3)'))) @@ -95,10 +97,12 @@ def test_from_import_non_existing_julia_name(self): assert not spamspamspam def test_julia_module_bang(self): - from julia import Base - xs = [1, 2, 3] - ys = Base.scale_b(xs[:], 2) - assert all(x * 2 == y for x, y in zip(xs, ys)) + from julia.Base import Channel, put_b, take_b + chan = Channel(1) + sent = 123 + put_b(chan, sent) + received = take_b(chan) + assert sent == received def test_import_julia_submodule(self): from julia.Base import Enums @@ -121,6 +125,10 @@ def test_module_dir(self): from julia import Base assert 'resize_b' in dir(Base) + @pytest.mark.skipif( + "JULIA_EXE" in orig_env, + reason=("cannot be tested with custom Julia executable;" + " JULIA_EXE is set to {}".format(orig_env.get("JULIA_EXE")))) def test_import_without_setup(self): command = [sys.executable, '-c', 'from julia import Base'] print('Executing:', *command)