88using Compat
99import Conda
1010
11- PYTHONIOENCODING = get (ENV , " PYTHONIOENCODING" , nothing )
12- PYTHONHOME = get (ENV , " PYTHONHOME" , nothing )
1311immutable UseCondaPython <: Exception end
1412
15- try # save/restore environment vars
16-
17- # set PYTHONIOENCODING when running python executable, so that
18- # we get UTF-8 encoded text as output (this is not the default on Windows).
19- ENV [" PYTHONIOENCODING" ] = " UTF-8"
13+ try # make sure deps.jl file is removed on error
2014
2115# ########################################################################
2216
23- pyconfigvar (python:: AbstractString , var:: AbstractString ) = chomp (readstring (` $python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('$var '))"` ))
17+ # Fix the environment for running `python`, and setts IO encoding to UTF-8.
18+ # If cmd is the Conda python, then additionally removes all PYTHON* and
19+ # CONDA* environment variables.
20+ function pythonenv (cmd:: Cmd )
21+ env = copy (ENV )
22+ if dirname (cmd. exec[1 ]) == abspath (Conda. PYTHONDIR)
23+ pythonvars = Compat. UTF8String[]
24+ for var in keys (env)
25+ if startswith (var, " CONDA" ) || startswith (var, " PYTHON" )
26+ push! (pythonvars, var)
27+ end
28+ end
29+ for var in pythonvars
30+ pop! (env, var)
31+ end
32+ end
33+ # set PYTHONIOENCODING when running python executable, so that
34+ # we get UTF-8 encoded text as output (this is not the default on Windows).
35+ env[" PYTHONIOENCODING" ] = " UTF-8"
36+ setenv (cmd, env)
37+ end
38+
39+ pyconfigvar (python:: AbstractString , var:: AbstractString ) = chomp (readstring (pythonenv (` $python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('$var '))"` )))
2440pyconfigvar (python, var, default) = let v = pyconfigvar (python, var)
2541 v == " None" ? default : v
2642end
2743
28- pysys (python:: AbstractString , var:: AbstractString ) = chomp (readstring (` $python -c "import sys; print(sys.$var )"` ))
44+ pysys (python:: AbstractString , var:: AbstractString ) = chomp (readstring (pythonenv ( ` $python -c "import sys; print(sys.$var )"` ) ))
2945
3046# ########################################################################
3147
@@ -58,24 +74,6 @@ function find_libpython(python::AbstractString)
5874
5975 error_strings = Compat. String[]
6076
61- if ! haskey (ENV , " PYTHONHOME" )
62- # PYTHONHOME tells python where to look for both pure python
63- # and binary modules. When it is set, it replaces both
64- # `prefix` and `exec_prefix` and we thus need to set it to
65- # both in case they differ. This is also what the
66- # documentation recommends. However, they are documented
67- # to always be the same on Windows, where it causes
68- # problems if we try to include both.
69- ENV [" PYTHONHOME" ] = is_windows () ? exec_prefix : pysys (python, " prefix" ) * " :" * exec_prefix
70- # Unfortunately, setting PYTHONHOME screws up Canopy's Python distro?
71- try
72- run (pipeline (` $python -c "import site"` , stdout = DevNull, stderr = DevNull))
73- catch e
74- push! (error_strings, string (" $python -c \" import site\" ==> " , e))
75- pop! (ENV , " PYTHONHOME" )
76- end
77- end
78-
7977 # TODO : other paths? python-config output? pyconfigvar("LDFLAGS")?
8078
8179 # find libpython (we hope):
@@ -133,13 +131,13 @@ function find_libpython(python::AbstractString)
133131
134132 The python executable we tried was $python (= version $v );
135133 the library names we tried were $libs
136- and the library paths we tried were $libpaths
137- """ )
134+ and the library paths we tried were $libpaths """ )
138135end
139136
140137# ########################################################################
141138
142139include (" depsutils.jl" )
140+
143141# ########################################################################
144142
145143const python = try
179177const (libpython, libpy_name) = find_libpython (python)
180178const programname = pysys (python, " executable" )
181179
180+ # Get PYTHONHOME, either from the environment or from Python
181+ # itself (if it is not in the environment or if we are using Conda)
182+ PYTHONHOME = if ! haskey (ENV , " PYTHONHOME" ) || use_conda
183+ # PYTHONHOME tells python where to look for both pure python
184+ # and binary modules. When it is set, it replaces both
185+ # `prefix` and `exec_prefix` and we thus need to set it to
186+ # both in case they differ. This is also what the
187+ # documentation recommends. However, they are documented
188+ # to always be the same on Windows, where it causes
189+ # problems if we try to include both.
190+ exec_prefix = pysys (python, " exec_prefix" )
191+ is_windows () ? exec_prefix : pysys (python, " prefix" ) * " :" * exec_prefix
192+ else
193+ ENV [" PYTHONHOME" ]
194+ end
195+
182196# cache the Python version as a Julia VersionNumber
183- const pyversion = convert (VersionNumber, split (Py_GetVersion (libpython))[1 ])
197+ const pyversion = withenv (" PYTHONHOME" => PYTHONHOME) do
198+ convert (VersionNumber, split (Py_GetVersion (libpython))[1 ])
199+ end
184200
185201info (" PyCall is using $python (Python $pyversion ) at $programname , libpython = $libpy_name " )
186202
@@ -196,8 +212,6 @@ wstringconst(s) =
196212 string (" wstring(\" " , escape_string (s), " \" )" ) :
197213 string (" Base.cconvert(Cwstring, \" " , escape_string (s), " \" )" )
198214
199- PYTHONHOMEENV = get (ENV , " PYTHONHOME" , " " )
200-
201215# we write configuration files only if they change, both
202216# to prevent unnecessary recompilation and to minimize
203217# problems in the unlikely event of read-only directories.
@@ -216,8 +230,8 @@ writeifchanged("deps.jl", """
216230 const pyprogramname = "$(escape_string (programname)) "
217231 const wpyprogramname = $(wstringconst (programname))
218232 const pyversion_build = $(repr (pyversion))
219- const PYTHONHOME = "$(escape_string (PYTHONHOMEENV )) "
220- const wPYTHONHOME = $(wstringconst (PYTHONHOMEENV ))
233+ const PYTHONHOME = "$(escape_string (PYTHONHOME )) "
234+ const wPYTHONHOME = $(wstringconst (PYTHONHOME ))
221235
222236 "True if we are using the Python distribution in the Conda package."
223237 const conda = $use_conda
@@ -233,10 +247,6 @@ catch
233247# remove deps.jl (if it exists) on an error, so that PyCall will
234248# not load until it is properly configured.
235249isfile (" deps.jl" ) && rm (" deps.jl" )
236-
237- finally # restore env vars
238-
239- PYTHONIOENCODING != nothing ? (ENV [" PYTHONIOENCODING" ] = PYTHONIOENCODING) : pop! (ENV , " PYTHONIOENCODING" )
240- PYTHONHOME != nothing ? (ENV [" PYTHONHOME" ] = PYTHONHOME) : pop! (ENV , " PYTHONHOME" , " " )
250+ rethrow ()
241251
242252end
0 commit comments