From d80067ea3f0a541f5b17acf537ccfcf3a59db359 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 21 Oct 2018 09:59:59 -0700 Subject: [PATCH] Add test_venv.jl --- src/pyinit.jl | 16 +++++++++--- test/runtests.jl | 1 + test/test_venv.jl | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 test/test_venv.jl diff --git a/src/pyinit.jl b/src/pyinit.jl index 955185d3..555b771c 100644 --- a/src/pyinit.jl +++ b/src/pyinit.jl @@ -106,14 +106,22 @@ function pythonhome_of(pyprogramname::AbstractString) """ # https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHOME end - cmd = `$pyprogramname -c $script` + return read(python_cmd(`-c $script`), String) +end + +""" + python_cmd(args::Cmd = ``) :: Cmd + +Create an appropriate `Cmd` for running Python program with command +line arguments `args`. +""" +function python_cmd(args::Cmd = ``) + cmd = `$pyprogramname $args` # For Windows: env = copy(ENV) env["PYTHONIOENCODING"] = "UTF-8" - cmd = setenv(cmd, env) - - return read(cmd, String) + return setenv(cmd, env) end function find_libpython(python::AbstractString) diff --git a/test/runtests.jl b/test/runtests.jl index a1951214..5f207fcf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -667,3 +667,4 @@ def try_call(f): end include("test_pyfncall.jl") +include("test_venv.jl") diff --git a/test/test_venv.jl b/test/test_venv.jl new file mode 100644 index 00000000..60d57fc8 --- /dev/null +++ b/test/test_venv.jl @@ -0,0 +1,63 @@ +using PyCall, Compat, Compat.Test +using Compat: @info + + +@testset "fuzz PyCall._leak" begin + N = 10000 + + @testset "_leak(Cstring, ...)" begin + for i in 1:N + x = String(rand('A':'z', rand(1:1000))) + y = Base.unsafe_string(PyCall._leak(Cstring, x)) + @test x == y + end + end + + @testset "_leak(Cwstring, ...)" begin + for i in 1:N + x = String(rand('A':'z', rand(1:1000))) + a = Base.cconvert(Cwstring, x) + ptr = PyCall._leak(a) + z = unsafe_wrap(Array, ptr, size(a)) + @test z[end] == 0 + y = transcode(String, z)[1:end-1] + @test x == y + end + end +end + + +@testset "venv activation" begin + if PyCall.conda + @info "Skip venv test with conda." + elseif !success(PyCall.python_cmd(`-c "import venv"`)) + @info "Skip venv test since venv package is missing." + else + mktempdir() do path + # Create a new virtualenv + run(PyCall.python_cmd(`-m venv $path`)) + newpython = joinpath(path, "bin", "python") + if Sys.iswindows() + newpython *= ".exe" + end + @test isfile(newpython) + + # Run a fresh Julia process with new Python environment + if VERSION < v"0.7.0-" + setup_code = "" + else + setup_code = Base.load_path_setup_code() + end + code = """ + $setup_code + using PyCall + print(PyCall.pyimport("sys")[:executable]) + """ + env = copy(ENV) + env["PYCALL_JL_RUNTIME_PYTHON"] = newpython + jlcmd = setenv(`$(Base.julia_cmd()) -e $code`, env) + output = read(jlcmd, String) + @test newpython == output + end + end +end