[pypy-commit] pypy app_main-refactor: port the logic to find sys.executable from app_main to interp-level and test
antocuni
noreply at buildbot.pypy.org
Fri Jun 8 17:33:11 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: app_main-refactor
Changeset: r55506:54e164d970a6
Date: 2012-06-08 13:41 +0200
http://bitbucket.org/pypy/pypy/changeset/54e164d970a6/
Log: port the logic to find sys.executable from app_main to interp-level
and test it thoughtfully. This is not yet complete, because
os.path.abspath is not RPython on windows (but it is on posix)
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -45,6 +45,7 @@
'builtin_module_names' : 'space.w_None',
'pypy_getudir' : 'state.pypy_getudir', # not translated
'pypy_initial_path' : 'state.pypy_initial_path',
+ 'pypy_find_executable' : 'state.pypy_find_executable',
'_getframe' : 'vm._getframe',
'_current_frames' : 'currentframes._current_frames',
diff --git a/pypy/module/sys/state.py b/pypy/module/sys/state.py
--- a/pypy/module/sys/state.py
+++ b/pypy/module/sys/state.py
@@ -2,6 +2,7 @@
Implementation of interpreter-level 'sys' routines.
"""
import pypy
+from pypy.rlib.objectmodel import we_are_translated
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import unwrap_spec
@@ -115,3 +116,32 @@
(should be removed from interpleveldefs before translation)"""
from pypy.tool.udir import udir
return space.wrap(str(udir))
+
+
+IS_WINDOWS = 'nt' in sys.builtin_module_names
+
+def find_executable(executable):
+ if we_are_translated() and IS_WINDOWS and not executable.lower().endswith('.exe'):
+ executable += '.exe'
+ if os.sep in executable or (IS_WINDOWS and ':' in executable):
+ pass # the path is already more than just an executable name
+ else:
+ path = os.environ.get('PATH')
+ if path:
+ for dir in path.split(os.pathsep):
+ fn = os.path.join(dir, executable)
+ if os.path.isfile(fn):
+ executable = fn
+ break
+ executable = os.path.abspath(executable)
+ #
+ # 'sys.executable' should not end up being an non-existing file;
+ # just use '' in this case. (CPython issue #7774)
+ if not os.path.isfile(executable):
+ executable = ''
+ return executable
+
+ at unwrap_spec(executable='str0')
+def pypy_find_executable(space, executable):
+ executable = find_executable(executable)
+ return space.wrap()
diff --git a/pypy/module/sys/test/test_initialpath.py b/pypy/module/sys/test/test_initialpath.py
--- a/pypy/module/sys/test/test_initialpath.py
+++ b/pypy/module/sys/test/test_initialpath.py
@@ -1,5 +1,6 @@
import py
-from pypy.module.sys.state import getinitialpath
+import os.path
+from pypy.module.sys.state import getinitialpath, find_executable
from pypy.module.sys.version import PYPY_VERSION, CPYTHON_VERSION
def build_hierarchy(prefix):
@@ -20,3 +21,47 @@
lib_tk = lib_python.join('lib-tk')
path = getinitialpath(None, str(tmpdir))
assert lib_tk in path
+
+
+def test_find_executable(tmpdir, monkeypatch):
+ from pypy.module.sys import state
+ # /tmp/a/pypy
+ # /tmp/b/pypy
+ # /tmp/c
+ a = tmpdir.join('a').ensure(dir=True)
+ b = tmpdir.join('b').ensure(dir=True)
+ c = tmpdir.join('c').ensure(dir=True)
+ a.join('pypy').ensure(file=True)
+ b.join('pypy').ensure(file=True)
+ #
+ # if there is already a slash, don't do anything
+ monkeypatch.chdir(tmpdir)
+ assert find_executable('a/pypy') == a.join('pypy')
+ #
+ # if path is None, try abspath (if the file exists)
+ monkeypatch.setenv('PATH', None)
+ monkeypatch.chdir(a)
+ assert find_executable('pypy') == a.join('pypy')
+ monkeypatch.chdir(tmpdir) # no pypy there
+ assert find_executable('pypy') == ''
+ #
+ # find it in path
+ monkeypatch.setenv('PATH', str(a))
+ assert find_executable('pypy') == a.join('pypy')
+ #
+ # find it in the first dir in path
+ monkeypatch.setenv('PATH', '%s%s%s' % (b, os.pathsep, a))
+ assert find_executable('pypy') == b.join('pypy')
+ #
+ # find it in the second, because in the first it's not there
+ monkeypatch.setenv('PATH', '%s%s%s' % (c, os.pathsep, a))
+ assert find_executable('pypy') == a.join('pypy')
+ # if pypy is found but it's not a file, ignore it
+ c.join('pypy').ensure(dir=True)
+ assert find_executable('pypy') == a.join('pypy')
+ #
+ monkeypatch.setattr(state, 'we_are_translated', lambda: True)
+ monkeypatch.setattr(state, 'IS_WINDOWS', True)
+ monkeypatch.setenv('PATH', str(a))
+ a.join('pypy.exe').ensure(file=True)
+ assert find_executable('pypy') == a.join('pypy.exe')
More information about the pypy-commit
mailing list