Skip to content

Commit

Permalink
Handle statically linked case in macOS as well
Browse files Browse the repository at this point in the history
It turned out macOS can have statically linked Python when it's
installed via conda:
#150 (comment)

So it seems `linked_libpython` (which calls `libdl`) is the only way
to reliably detect if the Python executable is statically linked or
not.  Since cd2e408 implements it for
Windows as well, we can now rely on `linked_libpython` everywhere
which simplifies core.py.
  • Loading branch information
tkf committed Oct 25, 2018
1 parent 5fc02df commit 77577f8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 19 deletions.
20 changes: 2 additions & 18 deletions julia/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
# this is python 3.3 specific
from types import ModuleType, FunctionType

from .find_libpython import find_libpython, normalize_path
from .find_libpython import find_libpython, linked_libpython, normalize_path

#-----------------------------------------------------------------------------
# Classes and funtions
Expand Down Expand Up @@ -260,11 +260,7 @@ def isafunction(julia, julia_name, mod_name=""):

def determine_if_statically_linked():
"""Determines if this python executable is statically linked"""
# Windows and OS X are generally always dynamically linked
if not sys.platform.startswith('linux'):
return False
lddoutput = subprocess.check_output(["ldd",sys.executable])
return not (b"libpython" in lddoutput)
return linked_libpython() is None


JuliaInfo = namedtuple(
Expand Down Expand Up @@ -356,18 +352,6 @@ def is_compatible_exe(jlinfo, _debug=lambda *_: None):
_debug("libpython cannot be read from PyCall/deps/deps.jl")
return False

if determine_if_statically_linked():
_debug(sys.executable, "is statically linked.")
return False

# Note that the following check is OK since statically linked case
# is already excluded.
if is_same_path(jlinfo.pyprogramname, sys.executable):
# In macOS and Windows, find_libpython does not work as good
# as in Linux. We add this shortcut so that PyJulia can work
# in those environments.
return True

py_libpython = find_libpython()
jl_libpython = normalize_path(jlinfo.libpython)
_debug("py_libpython =", py_libpython)
Expand Down
20 changes: 19 additions & 1 deletion test/test_find_libpython.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import subprocess
import sys

from julia.find_libpython import finding_libpython, linked_libpython
from julia.core import determine_if_statically_linked

try:
unicode
Expand All @@ -14,6 +16,22 @@ def test_finding_libpython_yield_type():
# let's just check returned type of finding_libpython.


def determine_if_statically_linked():
"""Determines if this python executable is statically linked"""
if not sys.platform.startswith('linux'):
# Assuming that Windows and OS X are generally always
# dynamically linked. Note that this is not the case in
# Python installed via conda:
# https://github.com/JuliaPy/pyjulia/issues/150#issuecomment-432912833
# However, since we do not use conda in our CI, this function
# is OK to use in tests.
return False
lddoutput = subprocess.check_output(["ldd", sys.executable])
return not (b"libpython" in lddoutput)


def test_linked_libpython():
# TODO: Special-case conda (check `sys.version`). See the above
# comments in `determine_if_statically_linked.
if not determine_if_statically_linked():
assert linked_libpython() is not None

0 comments on commit 77577f8

Please sign in to comment.