[pypy-commit] pypy default: merge the app_main-refactor branch, which moves part of the logic to interp-level and kills the nanos hack. This greatly helps py3k
antocuni
noreply at buildbot.pypy.org
Mon Jun 11 16:01:18 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r55583:fdbbeda51739
Date: 2012-06-11 16:00 +0200
http://bitbucket.org/pypy/pypy/changeset/fdbbeda51739/
Log: merge the app_main-refactor branch, which moves part of the logic to
interp-level and kills the nanos hack. This greatly helps py3k
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -659,7 +659,7 @@
def mul((str1, int2)): # xxx do we want to support this
getbookkeeper().count("str_mul", str1, int2)
- return SomeString()
+ return SomeString(no_nul=str1.no_nul)
class __extend__(pairtype(SomeUnicodeString, SomeInteger)):
def getitem((str1, int2)):
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -2138,6 +2138,15 @@
assert isinstance(s, annmodel.SomeString)
assert s.no_nul
+ def test_mul_str0(self):
+ def f(s):
+ return s*10
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [annmodel.SomeString(no_nul=True)])
+ assert isinstance(s, annmodel.SomeString)
+ assert s.no_nul
+
+
def test_non_none_and_none_with_isinstance(self):
class A(object):
pass
@@ -3780,6 +3789,26 @@
e = py.test.raises(Exception, a.build_types, f, [])
assert 'object with a __call__ is not RPython' in str(e.value)
+ def test_os_getcwd(self):
+ import os
+ def fn():
+ return os.getcwd()
+ a = self.RPythonAnnotator()
+ s = a.build_types(fn, [])
+ assert isinstance(s, annmodel.SomeString)
+ assert s.no_nul
+
+ def test_os_getenv(self):
+ import os
+ def fn():
+ return os.environ.get('PATH')
+ a = self.RPythonAnnotator()
+ s = a.build_types(fn, [])
+ assert isinstance(s, annmodel.SomeString)
+ assert s.no_nul
+
+
+
def g(n):
return [0,1,2,n]
diff --git a/pypy/bin/py.py b/pypy/bin/py.py
--- a/pypy/bin/py.py
+++ b/pypy/bin/py.py
@@ -89,12 +89,12 @@
space.setitem(space.sys.w_dict, space.wrap('executable'),
space.wrap(argv[0]))
- # call pypy_initial_path: the side-effect is that it sets sys.prefix and
+ # call pypy_find_stdlib: the side-effect is that it sets sys.prefix and
# sys.exec_prefix
- srcdir = os.path.dirname(os.path.dirname(pypy.__file__))
- space.appexec([space.wrap(srcdir)], """(srcdir):
+ executable = argv[0]
+ space.appexec([space.wrap(executable)], """(executable):
import sys
- sys.pypy_initial_path(srcdir)
+ sys.pypy_find_stdlib(executable)
""")
# set warning control options (if any)
diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py
--- a/pypy/jit/codewriter/policy.py
+++ b/pypy/jit/codewriter/policy.py
@@ -48,8 +48,6 @@
mod = func.__module__ or '?'
if mod.startswith('pypy.rpython.module.'):
return True
- if mod == 'pypy.translator.goal.nanos': # more helpers
- return True
return False
def look_inside_graph(self, graph):
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
@@ -44,7 +44,9 @@
'warnoptions' : 'state.get(space).w_warnoptions',
'builtin_module_names' : 'space.w_None',
'pypy_getudir' : 'state.pypy_getudir', # not translated
- 'pypy_initial_path' : 'state.pypy_initial_path',
+ 'pypy_find_stdlib' : 'initpath.pypy_find_stdlib',
+ 'pypy_find_executable' : 'initpath.pypy_find_executable',
+ 'pypy_resolvedirof' : 'initpath.pypy_resolvedirof',
'_getframe' : 'vm._getframe',
'_current_frames' : 'currentframes._current_frames',
diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/sys/initpath.py
@@ -0,0 +1,155 @@
+"""
+Logic to find sys.executable and the initial sys.path containing the stdlib
+"""
+
+import sys
+import os
+import stat
+import errno
+from pypy.rlib import rpath
+from pypy.rlib.objectmodel import we_are_translated
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.module.sys.state import get as get_state
+
+platform = sys.platform
+IS_WINDOWS = sys.platform == 'win32'
+
+def find_executable(executable):
+ """
+ Return the absolute path of the executable, by looking into PATH and the
+ current directory. If it cannot be found, return ''.
+ """
+ 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 = rpath.rabspath(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
+
+
+def readlink_maybe(filename):
+ if not IS_WINDOWS:
+ return os.readlink(filename)
+ raise NotImplementedError
+
+def resolvedirof(filename):
+ try:
+ filename = rpath.rabspath(filename)
+ except OSError:
+ pass
+ dirname = rpath.rabspath(os.path.join(filename, '..'))
+ if os.path.islink(filename):
+ try:
+ link = readlink_maybe(filename)
+ except OSError:
+ pass
+ else:
+ return resolvedirof(os.path.join(dirname, link))
+ return dirname
+
+def find_stdlib(state, executable):
+ """
+ Find and compute the stdlib path, starting from the directory where
+ ``executable`` is and going one level up until we find it. Return a tuple
+ (path, prefix), where ``prefix`` is the root directory which contains the
+ stdlib.
+ If it cannot be found, return (None, None).
+ """
+ search = executable
+ while True:
+ dirname = resolvedirof(search)
+ if dirname == search:
+ return None, None # not found :-(
+ newpath = compute_stdlib_path_maybe(state, dirname)
+ if newpath is not None:
+ return newpath, dirname
+ search = dirname # walk to the parent directory
+
+
+
+def checkdir(path):
+ st = os.stat(path)
+ if not stat.S_ISDIR(st[0]):
+ raise OSError(errno.ENOTDIR, path)
+
+def compute_stdlib_path(state, prefix):
+ """
+ Compute the paths for the stdlib rooted at ``prefix``. ``prefix`` must at
+ least contain a directory called ``lib-python/X.Y`` and another one called
+ ``lib_pypy``. If they cannot be found, it raises OSError.
+ """
+ from pypy.module.sys.version import CPYTHON_VERSION
+ dirname = '%d.%d' % (CPYTHON_VERSION[0],
+ CPYTHON_VERSION[1])
+ lib_python = os.path.join(prefix, 'lib-python')
+ python_std_lib = os.path.join(lib_python, dirname)
+ checkdir(python_std_lib)
+
+ lib_pypy = os.path.join(prefix, 'lib_pypy')
+ checkdir(lib_pypy)
+
+ importlist = []
+ #
+ if state is not None: # 'None' for testing only
+ lib_extensions = os.path.join(lib_pypy, '__extensions__')
+ state.w_lib_extensions = state.space.wrap(lib_extensions)
+ importlist.append(lib_extensions)
+ #
+ importlist.append(lib_pypy)
+ importlist.append(python_std_lib)
+ #
+ lib_tk = os.path.join(python_std_lib, 'lib-tk')
+ importlist.append(lib_tk)
+ #
+ # List here the extra platform-specific paths.
+ if platform != 'win32':
+ importlist.append(os.path.join(python_std_lib, 'plat-'+platform))
+ if platform == 'darwin':
+ platmac = os.path.join(python_std_lib, 'plat-mac')
+ importlist.append(platmac)
+ importlist.append(os.path.join(platmac, 'lib-scriptpackages'))
+ #
+ return importlist
+
+def compute_stdlib_path_maybe(state, prefix):
+ """
+ Return the stdlib path rooted at ``prefix``, or None if it cannot be
+ found.
+ """
+ try:
+ return compute_stdlib_path(state, prefix)
+ except OSError:
+ return None
+
+ at unwrap_spec(executable='str0')
+def pypy_find_executable(space, executable):
+ return space.wrap(find_executable(executable))
+
+ at unwrap_spec(filename='str0')
+def pypy_resolvedirof(space, filename):
+ return space.wrap(resolvedirof(filename))
+
+ at unwrap_spec(executable='str0')
+def pypy_find_stdlib(space, executable):
+ path, prefix = find_stdlib(get_state(space), executable)
+ if path is None:
+ return space.w_None
+ else:
+ space.setitem(space.sys.w_dict, space.wrap('prefix'),
+ space.wrap(prefix))
+ space.setitem(space.sys.w_dict, space.wrap('exec_prefix'),
+ space.wrap(prefix))
+ return space.newlist([space.wrap(p) for p in path])
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
@@ -1,11 +1,8 @@
"""
Implementation of interpreter-level 'sys' routines.
"""
+import os
import pypy
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import unwrap_spec
-
-import sys, os, stat, errno
# ____________________________________________________________
#
@@ -20,67 +17,14 @@
self.w_argv = space.newlist([])
self.setinitialpath(space)
- def setinitialpath(self, space):
+ def setinitialpath(self, space):
+ from pypy.module.sys.initpath import compute_stdlib_path
# Initialize the default path
pypydir = os.path.dirname(os.path.abspath(pypy.__file__))
srcdir = os.path.dirname(pypydir)
- path = getinitialpath(self, srcdir)
+ path = compute_stdlib_path(self, srcdir)
self.w_path = space.newlist([space.wrap(p) for p in path])
-def checkdir(path):
- st = os.stat(path)
- if not stat.S_ISDIR(st[0]):
- raise OSError(errno.ENOTDIR, path)
-
-
-platform = sys.platform
-
-def getinitialpath(state, prefix):
- from pypy.module.sys.version import CPYTHON_VERSION
- dirname = '%d.%d' % (CPYTHON_VERSION[0],
- CPYTHON_VERSION[1])
- lib_python = os.path.join(prefix, 'lib-python')
- python_std_lib = os.path.join(lib_python, dirname)
- checkdir(python_std_lib)
-
- lib_pypy = os.path.join(prefix, 'lib_pypy')
- checkdir(lib_pypy)
-
- importlist = []
- #
- if state is not None: # 'None' for testing only
- lib_extensions = os.path.join(lib_pypy, '__extensions__')
- state.w_lib_extensions = state.space.wrap(lib_extensions)
- importlist.append(lib_extensions)
- #
- importlist.append(lib_pypy)
- importlist.append(python_std_lib)
- #
- lib_tk = os.path.join(python_std_lib, 'lib-tk')
- importlist.append(lib_tk)
- #
- # List here the extra platform-specific paths.
- if platform != 'win32':
- importlist.append(os.path.join(python_std_lib, 'plat-'+platform))
- if platform == 'darwin':
- platmac = os.path.join(python_std_lib, 'plat-mac')
- importlist.append(platmac)
- importlist.append(os.path.join(platmac, 'lib-scriptpackages'))
- #
- return importlist
-
- at unwrap_spec(srcdir='str0')
-def pypy_initial_path(space, srcdir):
- try:
- path = getinitialpath(get(space), srcdir)
- except OSError:
- return space.w_None
- else:
- space.setitem(space.sys.w_dict, space.wrap('prefix'),
- space.wrap(srcdir))
- space.setitem(space.sys.w_dict, space.wrap('exec_prefix'),
- space.wrap(srcdir))
- return space.newlist([space.wrap(p) for p in path])
def get(space):
return space.fromcache(State)
@@ -115,3 +59,4 @@
(should be removed from interpleveldefs before translation)"""
from pypy.tool.udir import udir
return space.wrap(str(udir))
+
diff --git a/pypy/module/sys/test/test_initialpath.py b/pypy/module/sys/test/test_initialpath.py
deleted file mode 100644
--- a/pypy/module/sys/test/test_initialpath.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import py
-from pypy.module.sys.state import getinitialpath
-from pypy.module.sys.version import PYPY_VERSION, CPYTHON_VERSION
-
-def build_hierarchy(prefix):
- dirname = '%d.%d' % CPYTHON_VERSION[:2]
- a = prefix.join('lib_pypy').ensure(dir=1)
- b = prefix.join('lib-python', dirname).ensure(dir=1)
- return a, b
-
-
-def test_stdlib_in_prefix(tmpdir):
- dirs = build_hierarchy(tmpdir)
- path = getinitialpath(None, str(tmpdir))
- # we get at least 'dirs', and maybe more (e.g. plat-linux2)
- assert path[:len(dirs)] == map(str, dirs)
-
-def test_include_libtk(tmpdir):
- lib_pypy, lib_python = build_hierarchy(tmpdir)
- lib_tk = lib_python.join('lib-tk')
- path = getinitialpath(None, str(tmpdir))
- assert lib_tk in path
diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/sys/test/test_initpath.py
@@ -0,0 +1,95 @@
+import py
+import os.path
+from pypy.module.sys.initpath import (compute_stdlib_path, find_executable, find_stdlib,
+ resolvedirof)
+from pypy.module.sys.version import PYPY_VERSION, CPYTHON_VERSION
+
+def build_hierarchy(prefix):
+ dirname = '%d.%d' % CPYTHON_VERSION[:2]
+ a = prefix.join('lib_pypy').ensure(dir=1)
+ b = prefix.join('lib-python', dirname).ensure(dir=1)
+ return a, b
+
+def test_find_stdlib(tmpdir):
+ bin_dir = tmpdir.join('bin').ensure(dir=True)
+ pypy = bin_dir.join('pypy').ensure(file=True)
+ build_hierarchy(tmpdir)
+ path, prefix = find_stdlib(None, str(pypy))
+ assert prefix == tmpdir
+
+ at py.test.mark.skipif('not hasattr(os, "symlink")')
+def test_find_stdlib_follow_symlink(tmpdir):
+ pypydir = tmpdir.join('opt', 'pypy-xxx')
+ pypy = pypydir.join('bin', 'pypy').ensure(file=True)
+ build_hierarchy(pypydir)
+ pypy_sym = tmpdir.join('pypy_sym')
+ os.symlink(str(pypy), str(pypy_sym))
+ path, prefix = find_stdlib(None, str(pypy_sym))
+ assert prefix == pypydir
+
+
+def test_compute_stdlib_path(tmpdir):
+ dirs = build_hierarchy(tmpdir)
+ path = compute_stdlib_path(None, str(tmpdir))
+ # we get at least 'dirs', and maybe more (e.g. plat-linux2)
+ assert path[:len(dirs)] == map(str, dirs)
+
+def test_include_libtk(tmpdir):
+ lib_pypy, lib_python = build_hierarchy(tmpdir)
+ lib_tk = lib_python.join('lib-tk')
+ path = compute_stdlib_path(None, str(tmpdir))
+ assert lib_tk in path
+
+
+def test_find_executable(tmpdir, monkeypatch):
+ from pypy.module.sys import initpath
+ # /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(initpath, 'we_are_translated', lambda: True)
+ monkeypatch.setattr(initpath, 'IS_WINDOWS', True)
+ monkeypatch.setenv('PATH', str(a))
+ a.join('pypy.exe').ensure(file=True)
+ assert find_executable('pypy') == a.join('pypy.exe')
+
+def test_resolvedirof(tmpdir):
+ foo = tmpdir.join('foo').ensure(dir=True)
+ bar = tmpdir.join('bar').ensure(dir=True)
+ myfile = foo.join('myfile').ensure(file=True)
+ assert resolvedirof(str(myfile)) == foo
+ if hasattr(myfile, 'mksymlinkto'):
+ myfile2 = bar.join('myfile')
+ myfile2.mksymlinkto(myfile)
+ assert resolvedirof(str(myfile2)) == foo
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -158,6 +158,8 @@
if isinstance(x, r_singlefloat):
self._wrap_not_rpython(x)
if isinstance(x, list):
+ if x == []: # special case: it is used e.g. in sys/__init__.py
+ return w_some_obj()
self._wrap_not_rpython(x)
return w_some_obj()
wrap._annspecialcase_ = "specialize:argtype(1)"
diff --git a/pypy/rlib/rpath.py b/pypy/rlib/rpath.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/rpath.py
@@ -0,0 +1,20 @@
+"""
+Minimal (and limited) RPython version of some functions contained in os.path.
+"""
+
+import os.path
+from pypy.rlib import rposix
+
+if os.name == 'posix':
+ # the posix version is already RPython, just use it
+ rabspath = os.path.abspath
+elif os.name == 'nt':
+ def rabspath(path):
+ if path == '':
+ path = os.getcwd()
+ try:
+ return rposix._getfullpathname(path)
+ except OSError:
+ return path
+else:
+ raise ImportError('Unsupported os: %s' % os.name)
diff --git a/pypy/rlib/test/test_rpath.py b/pypy/rlib/test/test_rpath.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/test_rpath.py
@@ -0,0 +1,18 @@
+import py
+import os
+from pypy.rlib import rpath
+
+IS_WINDOWS = os.name == 'nt'
+
+def test_rabspath_relative(tmpdir):
+ tmpdir.chdir()
+ assert rpath.rabspath('foo') == tmpdir.join('foo')
+
+ at py.test.mark.skipif("IS_WINDOWS")
+def test_rabspath_absolute_posix():
+ assert rpath.rabspath('/foo') == '/foo'
+
+ at py.test.mark.skipif("not IS_WINDOWS")
+def test_rabspath_absolute_nt():
+ curdrive, _ = os.path.splitdrive(os.getcwd())
+ assert rpath.rabspath('\\foo') == '%s\\foo' % curdrive
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -1114,7 +1114,7 @@
def os_getcwd_oofakeimpl():
return OOSupport.to_rstr(os.getcwd())
- return extdef([], str,
+ return extdef([], str0,
"ll_os.ll_os_getcwd", llimpl=os_getcwd_llimpl,
oofakeimpl=os_getcwd_oofakeimpl)
diff --git a/pypy/rpython/module/ll_os_environ.py b/pypy/rpython/module/ll_os_environ.py
--- a/pypy/rpython/module/ll_os_environ.py
+++ b/pypy/rpython/module/ll_os_environ.py
@@ -67,7 +67,7 @@
rffi.free_charp(l_name)
return result
-register_external(r_getenv, [str0], annmodel.SomeString(can_be_None=True),
+register_external(r_getenv, [str0], annmodel.SomeString(can_be_None=True, no_nul=True),
export_name='ll_os.ll_os_getenv',
llimpl=getenv_llimpl)
diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -213,69 +213,19 @@
# ____________________________________________________________
# Main entry point
-# see nanos.py for explainment why we do not import os here
-# CAUTION!
-# remember to update nanos.py if you are using more functions
-# from os or os.path!
-# Running test/test_nanos.py might be helpful as well.
-
def we_are_translated():
# app-level, very different from pypy.rlib.objectmodel.we_are_translated
return hasattr(sys, 'pypy_translation_info')
if 'nt' in sys.builtin_module_names:
IS_WINDOWS = True
- DRIVE_LETTER_SEP = ':'
else:
IS_WINDOWS = False
-def get_library_path(executable):
- search = executable
- while 1:
- dirname = resolvedirof(search)
- if dirname == search:
- # not found! let's hope that the compiled-in path is ok
- print >> sys.stderr, """\
-debug: WARNING: Library path not found, using compiled-in sys.path.
-debug: WARNING: 'sys.prefix' will not be set.
-debug: WARNING: Make sure the pypy binary is kept inside its tree of files.
-debug: WARNING: It is ok to create a symlink to it from somewhere else."""
- newpath = sys.path[:]
- break
- newpath = sys.pypy_initial_path(dirname)
- if newpath is None:
- search = dirname # walk to the parent directory
- continue
- break # found!
- return newpath
-def setup_sys_executable(executable, nanos):
- # a substituted os if we are translated
- global os
- os = nanos
- # find the full path to the executable, assuming that if there is no '/'
- # in the provided one then we must look along the $PATH
- if we_are_translated() and IS_WINDOWS and not executable.lower().endswith('.exe'):
- executable += '.exe'
- if os.sep in executable or (IS_WINDOWS and DRIVE_LETTER_SEP in executable):
- pass # the path is already more than just an executable name
- else:
- path = os.getenv('PATH')
- if path:
- for dir in path.split(os.pathsep):
- fn = os.path.join(dir, executable)
- if os.path.isfile(fn):
- executable = fn
- break
- sys.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(sys.executable):
- sys.executable = ''
-
-def setup_initial_paths(ignore_environment=False, **extra):
- newpath = get_library_path(sys.executable)
+def setup_and_fix_paths(ignore_environment=False, **extra):
+ import os
+ newpath = sys.path[:]
readenv = not ignore_environment
path = readenv and os.getenv('PYTHONPATH')
if path:
@@ -294,7 +244,15 @@
except ImportError:
if sys.version_info < (2, 7):
return
- import ctypes # HACK: while running on top of CPython
+ # HACK: while running on top of CPython, and make sure to import
+ # CPython's ctypes (because at this point sys.path has already been
+ # set to the pypy one)
+ pypy_path = sys.path
+ try:
+ sys.path = sys.cpython_path
+ import ctypes
+ finally:
+ sys.path = pypy_path
set_file_encoding = ctypes.pythonapi.PyFile_SetEncodingAndErrors
set_file_encoding.argtypes = [ctypes.py_object, ctypes.c_char_p, ctypes.c_char_p]
else:
@@ -417,6 +375,7 @@
def parse_command_line(argv):
+ import os
options = default_options.copy()
options['warnoptions'] = []
#
@@ -496,6 +455,7 @@
# but we need more in the translated PyPy for the compiler package
if '__pypy__' not in sys.builtin_module_names:
sys.setrecursionlimit(5000)
+ import os
if unbuffered:
set_unbuffered_io()
@@ -624,7 +584,7 @@
# on the command-line.
filename = sys.argv[0]
mainmodule.__file__ = filename
- sys.path.insert(0, resolvedirof(filename))
+ sys.path.insert(0, sys.pypy_resolvedirof(filename))
# assume it's a pyc file only if its name says so.
# CPython goes to great lengths to detect other cases
# of pyc file format, but I think it's ok not to care.
@@ -669,28 +629,46 @@
return status
-def resolvedirof(filename):
- try:
- filename = os.path.abspath(filename)
- except OSError:
- pass
- dirname = os.path.dirname(filename)
- if os.path.islink(filename):
- try:
- link = os.readlink(filename)
- except OSError:
- pass
- else:
- return resolvedirof(os.path.join(dirname, link))
- return dirname
-
def print_banner():
print 'Python %s on %s' % (sys.version, sys.platform)
print ('Type "help", "copyright", "credits" or '
'"license" for more information.')
-def entry_point(executable, argv, nanos):
- setup_sys_executable(executable, nanos)
+STDLIB_WARNING = """\
+debug: WARNING: Library path not found, using compiled-in sys.path.
+debug: WARNING: 'sys.prefix' will not be set.
+debug: WARNING: Make sure the pypy binary is kept inside its tree of files.
+debug: WARNING: It is ok to create a symlink to it from somewhere else."""
+
+def setup_bootstrap_path(executable):
+ """
+ Try to to as little as possible and to have the stdlib in sys.path. In
+ particular, we cannot use any unicode at this point, because lots of
+ unicode operations require to be able to import encodings.
+ """
+ # at this point, sys.path is set to the compiled-in one, based on the
+ # location where pypy was compiled. This is set during the objspace
+ # initialization by module.sys.state.State.setinitialpath.
+ #
+ # Now, we try to find the absolute path of the executable and the stdlib
+ # path
+ executable = sys.pypy_find_executable(executable)
+ stdlib_path = sys.pypy_find_stdlib(executable)
+ if stdlib_path is None:
+ print >> sys.stderr, STDLIB_WARNING
+ else:
+ sys.path[:] = stdlib_path
+ # from this point on, we are free to use all the unicode stuff we want,
+ # This is important for py3k
+ sys.executable = executable
+
+def entry_point(executable, argv):
+ # note that before calling setup_bootstrap_path, we are limited because we
+ # cannot import stdlib modules. In particular, we cannot use unicode
+ # stuffs (because we need to be able to import encodings) and we cannot
+ # import os, which is used a bit everywhere in app_main, but only imported
+ # *after* setup_bootstrap_path
+ setup_bootstrap_path(executable)
try:
cmdline = parse_command_line(argv)
except CommandLineError, e:
@@ -698,24 +676,33 @@
return 2
except SystemExit, e:
return e.code or 0
- setup_initial_paths(**cmdline)
+ setup_and_fix_paths(**cmdline)
return run_command_line(**cmdline)
if __name__ == '__main__':
- import autopath
- import nanos
# obscure! try removing the following line, see how it crashes, and
# guess why...
ImStillAroundDontForgetMe = sys.modules['__main__']
# debugging only
- def pypy_initial_path(s):
- from pypy.module.sys.state import getinitialpath
- try:
- return getinitialpath(None, s)
- except OSError:
- return None
+ def pypy_find_executable(s):
+ import os
+ return os.path.abspath(s)
+
+ def pypy_find_stdlib(s):
+ from os.path import abspath, join, dirname as dn
+ thisfile = abspath(__file__)
+ root = dn(dn(dn(dn(thisfile))))
+ return [join(root, 'lib-python', '2.7'),
+ join(root, 'lib_pypy')]
+
+ def pypy_resolvedirof(s):
+ # we ignore the issue of symlinks; for tests, the executable is always
+ # translator/goal/app_main.py anyway
+ import os
+ return os.path.abspath(os.path.join(s, '..'))
+
# add an emulator for these pypy-only or 2.7-only functions
# (for test_pyc_commandline_argument)
@@ -738,25 +725,27 @@
imp._run_compiled_module = _run_compiled_module
imp._getimporter = _getimporter
- # stick the current sys.path into $PYTHONPATH, so that CPython still
- # finds its own extension modules :-/
import os
- os.environ['PYTHONPATH'] = ':'.join(sys.path)
reset = []
if 'PYTHONINSPECT_' in os.environ:
reset.append(('PYTHONINSPECT', os.environ.get('PYTHONINSPECT', '')))
os.environ['PYTHONINSPECT'] = os.environ['PYTHONINSPECT_']
+ if 'PYTHONWARNINGS_' in os.environ:
+ reset.append(('PYTHONWARNINGS', os.environ.get('PYTHONWARNINGS', '')))
+ os.environ['PYTHONWARNINGS'] = os.environ['PYTHONWARNINGS_']
+ del os # make sure that os is not available globally, because this is what
+ # happens in "real life" outside the tests
# no one should change to which lists sys.argv and sys.path are bound
old_argv = sys.argv
old_path = sys.path
- from pypy.module.sys.version import PYPY_VERSION
- sys.pypy_version_info = PYPY_VERSION
- sys.pypy_initial_path = pypy_initial_path
- os = nanos.os_module_for_testing
+ sys.pypy_find_executable = pypy_find_executable
+ sys.pypy_find_stdlib = pypy_find_stdlib
+ sys.pypy_resolvedirof = pypy_resolvedirof
+ sys.cpython_path = sys.path[:]
try:
- sys.exit(int(entry_point(sys.argv[0], sys.argv[1:], os)))
+ sys.exit(int(entry_point(sys.argv[0], sys.argv[1:])))
finally:
# restore the normal prompt (which was changed by _pypy_interact), in
# case we are dropping to CPython's prompt
diff --git a/pypy/translator/goal/nanos.py b/pypy/translator/goal/nanos.py
deleted file mode 100644
--- a/pypy/translator/goal/nanos.py
+++ /dev/null
@@ -1,290 +0,0 @@
-"""
-Not An os or Nano os :-)
-
-Implementation of a few methods needed for starting up
-PyPy in app_main without importing os there.
-
-At startup time, app_main wants to find out about itself,
-sys.executable, the path to its library etc.
-This is done the easiest using os.py, but since this
-is a python module, we have a recurrence problem.
-
-Importing it at compile time would work, partially,
-but the way os is initialized will cause os.getenv
-to malfunction, due to caching problems.
-
-The solution taken here implements a minimal os using
-app-level code that is created at compile-time. Only
-the few needed functions are implemented in a tiny os module
-that contains a tiny path module.
-
-os.getenv got a direct implementation to overcome the caching
-problem.
-
-Please adjust the applevel code below, if you need to support
-more from os and os.path.
-"""
-
-from pypy.interpreter.gateway import applevel, interp2app
-import os, py
-
-if os.name == 'posix':
- # code copied from posixpath.py
- app_os_path = applevel("""
- def dirname(p):
- i = p.rfind('/') + 1
- head = p[:i]
- if head and head != '/'*len(head):
- head = head.rstrip('/')
- return head
-
- def join(path, b):
- if b.startswith('/'):
- path = b
- elif path == '' or path.endswith('/'):
- path += b
- else:
- path += '/' + b
- return path
-
- def normpath(path):
- if path == '':
- return '.'
- initial_slashes = path.startswith('/')
- # POSIX allows one or two initial slashes, but treats three or more
- # as single slash.
- if (initial_slashes and
- path.startswith('//') and not path.startswith('///')):
- initial_slashes = 2
- comps = path.split('/')
- new_comps = []
- for comp in comps:
- if comp in ('', '.'):
- continue
- if (comp != '..' or (not initial_slashes and not new_comps) or
- (new_comps and new_comps[-1] == '..')):
- new_comps.append(comp)
- elif new_comps:
- new_comps.pop()
- comps = new_comps
- path = '/'.join(comps)
- if initial_slashes:
- path = '/'*initial_slashes + path
- return path or '.'
-
- def abspath(path):
- if not path.startswith('/'):
- import posix
- cwd = posix.getcwd()
- path = join(cwd, path)
- return normpath(path)
-
- def isfile(path):
- import posix
- try:
- st = posix.stat(path)
- except posix.error:
- return False
- return (st.st_mode & 0170000) == 0100000 # S_ISREG
-
- def islink(path):
- import posix
- try:
- st = posix.lstat(path)
- except posix.error:
- return False
- return (st.st_mode & 0170000) == 0120000 # S_ISLNK
-
- """, filename=__file__)
-
- app_os = applevel("""
- sep = '/'
- pathsep = ':'
- name = 'posix'
-
- def readlink(fn):
- import posix
- return posix.readlink(fn)
- """, filename=__file__)
-
-elif os.name == 'nt':
- # code copied from ntpath.py
- app_os_path = applevel(r"""
- def splitdrive(p):
- if p[1:2] == ':':
- return p[0:2], p[2:]
- return '', p
-
- def isabs(s):
- s = splitdrive(s)[1]
- return s != '' and s[:1] in '/\\'
-
- def dirname(p):
- d, p = splitdrive(p)
- # set i to index beyond p's last slash
- i = len(p)
- while i and p[i-1] not in '/\\':
- i = i - 1
- head = p[:i]
- # remove trailing slashes from head, unless it's all slashes
- head2 = head
- while head2 and head2[-1] in '/\\':
- head2 = head2[:-1]
- head = head2 or head
- return d + head
-
- def join(path, b):
- b_wins = 0 # set to 1 iff b makes path irrelevant
- if path == "":
- b_wins = 1
-
- elif isabs(b):
- # This probably wipes out path so far. However, it's more
- # complicated if path begins with a drive letter:
- # 1. join('c:', '/a') == 'c:/a'
- # 2. join('c:/', '/a') == 'c:/a'
- # But
- # 3. join('c:/a', '/b') == '/b'
- # 4. join('c:', 'd:/') = 'd:/'
- # 5. join('c:/', 'd:/') = 'd:/'
- if path[1:2] != ":" or b[1:2] == ":":
- # Path doesn't start with a drive letter, or cases 4 and 5.
- b_wins = 1
-
- # Else path has a drive letter, and b doesn't but is absolute.
- elif len(path) > 3 or (len(path) == 3 and
- path[-1] not in "/\\"):
- # case 3
- b_wins = 1
-
- if b_wins:
- path = b
- else:
- # Join, and ensure there's a separator.
- assert len(path) > 0
- if path[-1] in "/\\":
- if b and b[0] in "/\\":
- path += b[1:]
- else:
- path += b
- elif path[-1] == ":":
- path += b
- elif b:
- if b[0] in "/\\":
- path += b
- else:
- path += "\\" + b
- else:
- # path is not empty and does not end with a backslash,
- # but b is empty; since, e.g., split('a/') produces
- # ('a', ''), it's best if join() adds a backslash in
- # this case.
- path += '\\'
-
- return path
-
- def normpath(path):
- if path.startswith(('\\\\.\\', '\\\\?\\')):
- # in the case of paths with these prefixes:
- # \\.\ -> device names
- # \\?\ -> literal paths
- # do not do any normalization, but return the path unchanged
- return path
- path = path.replace('/', '\\')
- prefix, path = splitdrive(path)
- # We need to be careful here. If the prefix is empty, and
- # the path starts with a backslash, it could either be an
- # absolute path on the current drive (\dir1\dir2\file) or a
- # UNC filename (\\server\mount\dir1\file). It is therefore
- # imperative NOT to collapse multiple backslashes blindly in
- # that case. The code below preserves multiple backslashes
- # when there is no drive letter. This means that the invalid
- # filename \\\a\b is preserved unchanged, where a\\\b is
- # normalised to a\b. It's not clear that there is any better
- # behaviour for such edge cases.
- if prefix == '':
- # No drive letter - preserve initial backslashes
- while path[:1] == "\\":
- prefix = prefix + '\\'
- path = path[1:]
- else:
- # We have a drive letter - collapse initial backslashes
- if path.startswith("\\"):
- prefix = prefix + '\\'
- path = path.lstrip("\\")
- comps = path.split("\\")
- i = 0
- while i < len(comps):
- if comps[i] in ('.', ''):
- del comps[i]
- elif comps[i] == '..':
- if i > 0 and comps[i-1] != '..':
- del comps[i-1:i+1]
- i -= 1
- elif i == 0 and prefix.endswith("\\"):
- del comps[i]
- else:
- i += 1
- else:
- i += 1
- # If the path is now empty, substitute '.'
- if not prefix and not comps:
- comps.append('.')
- return prefix + '\\'.join(comps)
-
- def abspath(path):
- import nt
- if path: # Empty path must return current working directory.
- try:
- path = nt._getfullpathname(path)
- except WindowsError:
- pass # Bad path - return unchanged.
- else:
- path = nt.getcwd()
- return normpath(path)
-
- def isfile(path):
- import nt
- try:
- st = nt.stat(path)
- except nt.error:
- return False
- return (st.st_mode & 0170000) == 0100000 # S_ISREG
-
- def islink(path):
- return False
-
- """, filename=__file__)
-
- app_os = applevel(r"""
- sep = '\\'
- pathsep = ';'
- name = 'nt'
- """, filename=__file__)
-
-else:
- raise NotImplementedError("os.name == %r" % (os.name,))
-
-def getenv(space, w_name):
- name = space.str0_w(w_name)
- return space.wrap(os.environ.get(name))
-getenv_w = interp2app(getenv)
-
-def setup_nanos(space):
- w_os = space.wrap(app_os.buildmodule(space, 'os'))
- w_os_path = space.wrap(app_os_path.buildmodule(space, 'path'))
- space.setattr(w_os, space.wrap('path'), w_os_path)
- space.setattr(w_os, space.wrap('getenv'), space.wrap(getenv_w))
- return w_os
-
-
-# in order to be able to test app_main without the pypy interpreter
-# we create the nanos module with the same names here like it would
-# be created while translation
-path_module_for_testing = type(os)("os.path")
-os_module_for_testing = type(os)("os")
-os_module_for_testing.path = path_module_for_testing
-os_module_for_testing.getenv = os.getenv
-eval(py.code.Source(app_os_path.source).compile(), path_module_for_testing.__dict__)
-eval(py.code.Source(app_os.source).compile(), os_module_for_testing.__dict__)
-
diff --git a/pypy/translator/goal/targetpypystandalone.py b/pypy/translator/goal/targetpypystandalone.py
--- a/pypy/translator/goal/targetpypystandalone.py
+++ b/pypy/translator/goal/targetpypystandalone.py
@@ -8,7 +8,6 @@
from pypy.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE
from pypy.config.config import ConflictConfigError
from pypy.tool.option import make_objspace
-from pypy.translator.goal.nanos import setup_nanos
thisdir = py.path.local(__file__).dirpath()
@@ -27,7 +26,6 @@
w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel'))
w_call_finish_gateway = space.wrap(gateway.interp2app(call_finish))
w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup))
- w_os = setup_nanos(space)
withjit = space.config.objspace.usemodules.pypyjit
def entry_point(argv):
@@ -56,7 +54,7 @@
w_executable = space.wrap(argv[0])
w_argv = space.newlist([space.wrap(s) for s in argv[1:]])
space.timer.start("w_entry_point")
- w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_os)
+ w_exitcode = space.call_function(w_entry_point, w_executable, w_argv)
space.timer.stop("w_entry_point")
exitcode = space.int_w(w_exitcode)
# try to pull it all in
diff --git a/pypy/translator/goal/test2/test_app_main.py b/pypy/translator/goal/test2/test_app_main.py
--- a/pypy/translator/goal/test2/test_app_main.py
+++ b/pypy/translator/goal/test2/test_app_main.py
@@ -200,6 +200,11 @@
http://pexpect.sourceforge.net/
"""
+ def setup_class(cls):
+ # some tests need to be able to import test2, change the cwd
+ goal_dir = os.path.abspath(os.path.join(autopath.this_dir, '..'))
+ os.chdir(goal_dir)
+
def _spawn(self, *args, **kwds):
try:
import pexpect
@@ -221,7 +226,7 @@
pexpect.__version__,))
kwds.setdefault('timeout', 10)
- print 'SPAWN:', args, kwds
+ print 'SPAWN:', ' '.join([args[0]] + args[1]), kwds
child = pexpect.spawn(*args, **kwds)
child.logfile = sys.stdout
return child
@@ -319,7 +324,8 @@
child.sendline('import sys; sys.argv')
child.expect(re.escape("['-c']"))
- def test_options_i_c_crashing(self):
+ def test_options_i_c_crashing(self, monkeypatch):
+ monkeypatch.setenv('PYTHONPATH', None)
child = self.spawn(['-i', '-c', 'x=666;foobar'])
child.expect('NameError')
idx = child.expect(['>>> ', re.escape(banner)])
@@ -351,28 +357,25 @@
sys.stdin = old
child.expect('foobye')
- def test_pythonstartup(self):
- old = os.environ.get('PYTHONSTARTUP', '')
- try:
- os.environ['PYTHONSTARTUP'] = crashing_demo_script
- child = self.spawn([])
- child.expect(re.escape(banner))
- child.expect('Traceback')
- child.expect('NameError')
- child.expect('>>> ')
- child.sendline('[myvalue2]')
- child.expect(re.escape('[11]'))
- child.expect('>>> ')
+ def test_pythonstartup(self, monkeypatch):
+ monkeypatch.setenv('PYTHONPATH', None)
+ monkeypatch.setenv('PYTHONSTARTUP', crashing_demo_script)
+ child = self.spawn([])
+ child.expect(re.escape(banner))
+ child.expect('Traceback')
+ child.expect('NameError')
+ child.expect('>>> ')
+ child.sendline('[myvalue2]')
+ child.expect(re.escape('[11]'))
+ child.expect('>>> ')
- child = self.spawn(['-i', demo_script])
- for line in ['hello', 'goodbye', '>>> ']:
- idx = child.expect([line, 'Hello2'])
- assert idx == 0 # no PYTHONSTARTUP run here
- child.sendline('myvalue2')
- child.expect('Traceback')
- child.expect('NameError')
- finally:
- os.environ['PYTHONSTARTUP'] = old
+ child = self.spawn(['-i', demo_script])
+ for line in ['hello', 'goodbye', '>>> ']:
+ idx = child.expect([line, 'Hello2'])
+ assert idx == 0 # no PYTHONSTARTUP run here
+ child.sendline('myvalue2')
+ child.expect('Traceback')
+ child.expect('NameError')
def test_ignore_python_startup(self):
old = os.environ.get('PYTHONSTARTUP', '')
@@ -420,7 +423,7 @@
p = os.path.join(autopath.this_dir, 'mymodule.py')
p = os.path.abspath(p)
child = self.spawn(['-i',
- '-m', 'pypy.translator.goal.test2.mymodule',
+ '-m', 'test2.mymodule',
'extra'])
child.expect('mymodule running')
child.expect('Name: __main__')
@@ -431,9 +434,9 @@
child.expect(re.escape(repr("foobar")))
child.expect('>>> ')
child.sendline('import sys')
- child.sendline('"pypy.translator.goal.test2" in sys.modules')
+ child.sendline('"test2" in sys.modules')
child.expect('True')
- child.sendline('"pypy.translator.goal.test2.mymodule" in sys.modules')
+ child.sendline('"test2.mymodule" in sys.modules')
child.expect('False')
child.sendline('sys.path[0]')
child.expect("''")
@@ -513,7 +516,7 @@
print 'A five ounce bird could not carry a one pound coconut.'
""")
py_py = os.path.join(autopath.pypydir, 'bin', 'py.py')
- child = self._spawn(sys.executable, [py_py, path])
+ child = self._spawn(sys.executable, [py_py, '-S', path])
child.expect('Are you suggesting coconuts migrate?', timeout=120)
child.sendline('Not at all. They could be carried.')
child.expect('A five ounce bird could not carry a one pound coconut.')
@@ -524,7 +527,7 @@
child = self.spawn(['-cprint "hel" + "lo"'])
child.expect('hello')
- child = self.spawn(['-mpypy.translator.goal.test2.mymodule'])
+ child = self.spawn(['-mtest2.mymodule'])
child.expect('mymodule running')
def test_ps1_only_if_interactive(self):
@@ -607,33 +610,28 @@
data = self.run('-c "print 6**5"')
assert '7776' in data
- def test_no_pythonstartup(self):
- old = os.environ.get('PYTHONSTARTUP', '')
- try:
- os.environ['PYTHONSTARTUP'] = crashing_demo_script
- data = self.run('"%s"' % (demo_script,))
- assert 'Hello2' not in data
- data = self.run('-c pass')
- assert 'Hello2' not in data
- finally:
- os.environ['PYTHONSTARTUP'] = old
+ def test_no_pythonstartup(self, monkeypatch):
+ monkeypatch.setenv('PYTHONSTARTUP', crashing_demo_script)
+ data = self.run('"%s"' % (demo_script,))
+ assert 'Hello2' not in data
+ data = self.run('-c pass')
+ assert 'Hello2' not in data
- def test_pythonwarnings(self):
- old = os.environ.get('PYTHONWARNINGS', '')
- try:
- os.environ['PYTHONWARNINGS'] = "once,error"
- data = self.run('-W ignore -W default '
- '-c "import sys; print sys.warnoptions"')
- assert "['ignore', 'default', 'once', 'error']" in data
- finally:
- os.environ['PYTHONWARNINGS'] = old
+ def test_pythonwarnings(self, monkeypatch):
+ # PYTHONWARNINGS_ is special cased by app_main: we cannot directly set
+ # PYTHONWARNINGS because else the warnings raised from within pypy are
+ # turned in errors.
+ monkeypatch.setenv('PYTHONWARNINGS_', "once,error")
+ data = self.run('-W ignore -W default '
+ '-c "import sys; print sys.warnoptions"')
+ assert "['ignore', 'default', 'once', 'error']" in data
def test_option_m(self):
if not hasattr(runpy, '_run_module_as_main'):
skip("requires CPython >= 2.6")
p = os.path.join(autopath.this_dir, 'mymodule.py')
p = os.path.abspath(p)
- data = self.run('-m pypy.translator.goal.test2.mymodule extra')
+ data = self.run('-m test2.mymodule extra')
assert 'mymodule running' in data
assert 'Name: __main__' in data
# ignoring case for windows. abspath behaves different from autopath
@@ -740,6 +738,7 @@
assert data == p + os.sep + '\n'
def test_getfilesystemencoding(self):
+ py.test.skip("this has been failing since forever, but it's not tested nightly because buildbot uses python2.6 :-(")
if sys.version_info < (2, 7):
skip("test requires Python >= 2.7")
p = getscript_in_dir("""
@@ -821,9 +820,9 @@
class AppTestAppMain:
def setup_class(self):
- # ------------------------------------
- # setup code for test_get_library_path
- # ------------------------------------
+ # ----------------------------------------
+ # setup code for test_setup_bootstrap_path
+ # ----------------------------------------
from pypy.module.sys.version import CPYTHON_VERSION, PYPY_VERSION
cpy_ver = '%d.%d' % CPYTHON_VERSION[:2]
@@ -840,37 +839,58 @@
self.w_fake_exe = self.space.wrap(str(fake_exe))
self.w_expected_path = self.space.wrap(expected_path)
self.w_trunkdir = self.space.wrap(os.path.dirname(autopath.pypydir))
+ #
+ foo_py = prefix.join('foo.py').write("pass")
+ self.w_foo_py = self.space.wrap(str(foo_py))
- def test_get_library_path(self):
+ def test_setup_bootstrap_path(self):
import sys
import os
+ old_sys_path = sys.path[:]
sys.path.append(self.goal_dir)
try:
import app_main
- app_main.os = os
- newpath = app_main.get_library_path('/tmp/pypy-c') # stdlib not found
- assert newpath == sys.path
- newpath = app_main.get_library_path(self.fake_exe)
+ app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found
+ sys.path == old_sys_path
+ assert sys.executable == ''
+ #
+ app_main.setup_bootstrap_path(self.fake_exe)
+ assert sys.executable == self.fake_exe
+ newpath = sys.path[:]
if newpath[0].endswith('__extensions__'):
newpath = newpath[1:]
# we get at least 'expected_path', and maybe more (e.g.plat-linux2)
assert newpath[:len(self.expected_path)] == self.expected_path
finally:
- sys.path.pop()
+ sys.path[:] = old_sys_path
def test_trunk_can_be_prefix(self):
import sys
import os
+ old_sys_path = sys.path[:]
sys.path.append(self.goal_dir)
try:
import app_main
- app_main.os = os
pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c')
- newpath = app_main.get_library_path(pypy_c)
+ app_main.setup_bootstrap_path(pypy_c)
+ newpath = sys.path[:]
# we get at least lib_pypy
# lib-python/X.Y.Z, and maybe more (e.g. plat-linux2)
assert len(newpath) >= 2
for p in newpath:
assert p.startswith(self.trunkdir)
finally:
- sys.path.pop()
+ sys.path[:] = old_sys_path
+
+ def test_entry_point(self):
+ import sys
+ import os
+ old_sys_path = sys.path[:]
+ sys.path.append(self.goal_dir)
+ try:
+ import app_main
+ pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c')
+ app_main.entry_point(pypy_c, [self.foo_py])
+ # assert it did not crash
+ finally:
+ sys.path[:] = old_sys_path
diff --git a/pypy/translator/goal/test2/test_nanos.py b/pypy/translator/goal/test2/test_nanos.py
deleted file mode 100644
--- a/pypy/translator/goal/test2/test_nanos.py
+++ /dev/null
@@ -1,85 +0,0 @@
-"""
-Tests for the entry point of pypy-c, whether nanos.py is supplying
-the needed names for app_main.py.
-"""
-import os
-
-from pypy.translator.goal import app_main
-this_dir = os.path.dirname(app_main.__file__)
-
-from pypy.objspace.std import Space
-from pypy.translator.goal.targetpypystandalone import create_entry_point
-from pypy.tool.udir import udir
-
-
-class TestNanos:
- def getnanos(self):
- from pypy.translator.goal.nanos import os_module_for_testing
- return os_module_for_testing
-
- def test_exists(self):
- os1 = self.getnanos()
- assert os1.name == os.name
- assert os1.sep == os.sep
- assert os1.pathsep == os.pathsep
-
- def test_dirname(self):
- p1 = os.path
- p2 = self.getnanos().path
- path = str(udir.join('baz'))
- assert p1.dirname(path) == p2.dirname(path)
- assert p1.dirname(path + os.sep) == p2.dirname(path + os.sep)
- assert p1.dirname(path + 2*os.sep) == p2.dirname(path + 2*os.sep)
- assert p1.dirname(p1.dirname(path)) == p2.dirname(p2.dirname(path))
-
- def test_join(self):
- p1 = os.path
- p2 = self.getnanos().path
- base = str(udir)
- assert p1.join(base, '') == p2.join(base, '')
- assert p1.join(base, 'baz') == p2.join(base, 'baz')
- assert p1.join(base + os.sep, 'baz') == p2.join(base + os.sep, 'baz')
- assert p1.join(base, 'baz' + os.sep) == p2.join(base, 'baz' + os.sep)
- assert p1.join(base, base) == p2.join(base, base)
-
- def test_abspath(self):
- p2 = self.getnanos().path
- base = str(udir)
- assert p2.abspath(base) == base
- assert p2.abspath('x') == os.path.join(os.getcwd(), 'x')
-
- def test_abspath_uses_normpath(self):
- p1 = os.path
- p2 = self.getnanos().path
- base = str(udir)
- assert p2.abspath(p1.join(base, '.')) == base
- assert p2.abspath(p1.join(base, '.', '.', '.')) == base
- assert p2.abspath(p1.join(base, 'foo', '..')) == base
-
- def test_isfile(self):
- p2 = self.getnanos().path
- udir.join('test_isfile').write('\n')
- base = str(udir)
- assert p2.isfile(p2.join(base, 'test_isfile'))
- assert not p2.isfile(p2.join(base, 'test_isfile.DOES.NOT.EXIST'))
- assert not p2.isfile(base)
-
-
-def test_nanos():
- space = Space()
- # manually imports app_main.py
- filename = os.path.join(this_dir, 'app_main.py')
- w_dict = space.newdict()
- space.exec_(open(filename).read(), w_dict, w_dict)
- entry_point = create_entry_point(space, w_dict)
-
- # check that 'os' is not in sys.modules
- assert not space.is_true(
- space.call_method(space.sys.get('modules'),
- '__contains__', space.wrap('os')))
- # But that 'sys' is still present
- assert space.is_true(
- space.call_method(space.sys.get('modules'),
- '__contains__', space.wrap('sys')))
-
- entry_point(['', '-c', 'print 42'])
More information about the pypy-commit
mailing list