Skip to content

Commit

Permalink
improve logic to determine python exe location
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Oct 30, 2017
1 parent 04087b9 commit da32baf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
23 changes: 17 additions & 6 deletions psutil/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
__all__ = [
# constants
'APPVEYOR', 'DEVNULL', 'GLOBAL_TIMEOUT', 'MEMORY_TOLERANCE', 'NO_RETRIES',
'PYPY', 'PYTHON', 'ROOT_DIR', 'SCRIPTS_DIR', 'TESTFILE_PREFIX',
'PYPY', 'PYTHON_EXE', 'ROOT_DIR', 'SCRIPTS_DIR', 'TESTFILE_PREFIX',
'TESTFN', 'TESTFN_UNICODE', 'TOX', 'TRAVIS', 'VALID_PROC_STATUSES',
'VERBOSITY',
"HAS_CPU_AFFINITY", "HAS_CPU_FREQ", "HAS_ENVIRON", "HAS_PROC_IO_COUNTERS",
Expand Down Expand Up @@ -168,7 +168,18 @@

# --- misc

PYTHON = os.path.realpath(sys.executable)

def _get_py_exe():
exe = os.path.realpath(sys.executable)
if not os.path.exists(exe):
# It seems this only occurs on OSX.
exe = which("python%s.%s" % sys.version_info[:2])
if not exe or not os.path.exists(exe):
ValueError("can't find python exe real abspath")
return exe


PYTHON_EXE = _get_py_exe()
DEVNULL = open(os.devnull, 'r+')
VALID_PROC_STATUSES = [getattr(psutil, x) for x in dir(psutil)
if x.startswith('STATUS_')]
Expand Down Expand Up @@ -288,7 +299,7 @@ def get_test_subprocess(cmd=None, **kwds):
pyline = "from time import sleep;" \
"open(r'%s', 'w').close();" \
"sleep(60);" % _TESTFN
cmd = [PYTHON, "-c", pyline]
cmd = [PYTHON_EXE, "-c", pyline]
sproc = subprocess.Popen(cmd, **kwds)
_subprocesses_started.add(sproc)
wait_for_file(_TESTFN, delete=True, empty=True)
Expand All @@ -310,13 +321,13 @@ def create_proc_children_pair():
_TESTFN2 = os.path.basename(_TESTFN) + '2' # need to be relative
s = textwrap.dedent("""\
import subprocess, os, sys, time
PYTHON = os.path.realpath(sys.executable)
PYTHON_EXE = os.path.realpath(sys.executable)
s = "import os, time;"
s += "f = open('%s', 'w');"
s += "f.write(str(os.getpid()));"
s += "f.close();"
s += "time.sleep(60);"
subprocess.Popen([PYTHON, '-c', s])
subprocess.Popen([PYTHON_EXE, '-c', s])
time.sleep(60)
""" % _TESTFN2)
# On Windows if we create a subprocess with CREATE_NO_WINDOW flag
Expand Down Expand Up @@ -384,7 +395,7 @@ def pyrun(src, **kwds):
_testfiles_created.add(f.name)
f.write(src)
f.flush()
subp = get_test_subprocess([PYTHON, f.name], **kwds)
subp = get_test_subprocess([PYTHON_EXE, f.name], **kwds)
wait_for_pid(subp.pid)
return subp

Expand Down
4 changes: 2 additions & 2 deletions psutil/tests/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from psutil.tests import get_kernel_version
from psutil.tests import get_test_subprocess
from psutil.tests import mock
from psutil.tests import PYTHON
from psutil.tests import PYTHON_EXE
from psutil.tests import reap_children
from psutil.tests import retry_before_failing
from psutil.tests import run_test_module_by_name
Expand Down Expand Up @@ -90,7 +90,7 @@ class TestProcess(unittest.TestCase):

@classmethod
def setUpClass(cls):
cls.pid = get_test_subprocess([PYTHON, "-E", "-O"],
cls.pid = get_test_subprocess([PYTHON_EXE, "-E", "-O"],
stdin=subprocess.PIPE).pid
wait_for_pid(cls.pid)

Expand Down
33 changes: 17 additions & 16 deletions psutil/tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from psutil.tests import HAS_THREADS
from psutil.tests import mock
from psutil.tests import PYPY
from psutil.tests import PYTHON
from psutil.tests import PYTHON_EXE
from psutil.tests import reap_children
from psutil.tests import retry_before_failing
from psutil.tests import run_test_module_by_name
Expand Down Expand Up @@ -167,7 +167,7 @@ def test_wait(self):

# check sys.exit() code
code = "import time, sys; time.sleep(0.01); sys.exit(5);"
sproc = get_test_subprocess([PYTHON, "-c", code])
sproc = get_test_subprocess([PYTHON_EXE, "-c", code])
p = psutil.Process(sproc.pid)
self.assertEqual(p.wait(), 5)
self.assertFalse(p.is_running())
Expand All @@ -176,7 +176,7 @@ def test_wait(self):
# It is not supposed to raise NSP when the process is gone.
# On UNIX this should return None, on Windows it should keep
# returning the exit code.
sproc = get_test_subprocess([PYTHON, "-c", code])
sproc = get_test_subprocess([PYTHON_EXE, "-c", code])
p = psutil.Process(sproc.pid)
self.assertEqual(p.wait(), 5)
self.assertIn(p.wait(), (5, None))
Expand Down Expand Up @@ -317,7 +317,7 @@ def test_io_counters(self):

# test reads
io1 = p.io_counters()
with open(PYTHON, 'rb') as f:
with open(PYTHON_EXE, 'rb') as f:
f.read()
io2 = p.io_counters()
if not BSD and not AIX:
Expand Down Expand Up @@ -692,12 +692,12 @@ def test_exe(self):
sproc = get_test_subprocess()
exe = psutil.Process(sproc.pid).exe()
try:
self.assertEqual(exe, PYTHON)
self.assertEqual(exe, PYTHON_EXE)
except AssertionError:
if WINDOWS and len(exe) == len(PYTHON):
if WINDOWS and len(exe) == len(PYTHON_EXE):
# on Windows we don't care about case sensitivity
normcase = os.path.normcase
self.assertEqual(normcase(exe), normcase(PYTHON))
self.assertEqual(normcase(exe), normcase(PYTHON_EXE))
else:
# certain platforms such as BSD are more accurate returning:
# "/usr/local/bin/python2.7"
Expand All @@ -708,7 +708,7 @@ def test_exe(self):
ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
try:
self.assertEqual(exe.replace(ver, ''),
PYTHON.replace(ver, ''))
PYTHON_EXE.replace(ver, ''))
except AssertionError:
# Tipically OSX. Really not sure what to do here.
pass
Expand All @@ -717,7 +717,7 @@ def test_exe(self):
self.assertEqual(out, 'hey')

def test_cmdline(self):
cmdline = [PYTHON, "-c", "import time; time.sleep(60)"]
cmdline = [PYTHON_EXE, "-c", "import time; time.sleep(60)"]
sproc = get_test_subprocess(cmdline)
try:
self.assertEqual(' '.join(psutil.Process(sproc.pid).cmdline()),
Expand All @@ -730,12 +730,12 @@ def test_cmdline(self):
# XXX - AIX truncates long arguments in /proc/pid/cmdline
if NETBSD or OPENBSD or AIX:
self.assertEqual(
psutil.Process(sproc.pid).cmdline()[0], PYTHON)
psutil.Process(sproc.pid).cmdline()[0], PYTHON_EXE)
else:
raise

def test_name(self):
sproc = get_test_subprocess(PYTHON)
sproc = get_test_subprocess(PYTHON_EXE)
name = psutil.Process(sproc.pid).name().lower()
pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
assert pyexe.startswith(name), (pyexe, name)
Expand Down Expand Up @@ -864,7 +864,8 @@ def test_cwd(self):
self.assertEqual(p.cwd(), os.getcwd())

def test_cwd_2(self):
cmd = [PYTHON, "-c", "import os, time; os.chdir('..'); time.sleep(60)"]
cmd = [PYTHON_EXE, "-c",
"import os, time; os.chdir('..'); time.sleep(60)"]
sproc = get_test_subprocess(cmd)
p = psutil.Process(sproc.pid)
call_until(p.cwd, "ret == os.path.dirname(os.getcwd())")
Expand Down Expand Up @@ -949,7 +950,7 @@ def test_open_files(self):

# another process
cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN
sproc = get_test_subprocess([PYTHON, "-c", cmdline])
sproc = get_test_subprocess([PYTHON_EXE, "-c", cmdline])
p = psutil.Process(sproc.pid)

for x in range(100):
Expand Down Expand Up @@ -1506,7 +1507,7 @@ def test_misc(self):
# XXX this test causes a ResourceWarning on Python 3 because
# psutil.__subproc instance doesn't get propertly freed.
# Not sure what to do though.
cmd = [PYTHON, "-c", "import time; time.sleep(60);"]
cmd = [PYTHON_EXE, "-c", "import time; time.sleep(60);"]
with psutil.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as proc:
proc.name()
Expand All @@ -1517,7 +1518,7 @@ def test_misc(self):
proc.terminate()

def test_ctx_manager(self):
with psutil.Popen([PYTHON, "-V"],
with psutil.Popen([PYTHON_EXE, "-V"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE) as proc:
Expand All @@ -1531,7 +1532,7 @@ def test_kill_terminate(self):
# subprocess.Popen()'s terminate(), kill() and send_signal() do
# not raise exception after the process is gone. psutil.Popen
# diverges from that.
cmd = [PYTHON, "-c", "import time; time.sleep(60);"]
cmd = [PYTHON_EXE, "-c", "import time; time.sleep(60);"]
with psutil.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as proc:
proc.terminate()
Expand Down

0 comments on commit da32baf

Please sign in to comment.