[pypy-svn] r48996 - in pypy/branch/windows48396/pypy/translator/goal: . test2
tismer at codespeak.net
tismer at codespeak.net
Fri Nov 23 19:05:18 CET 2007
Author: tismer
Date: Fri Nov 23 19:05:18 2007
New Revision: 48996
Added:
pypy/branch/windows48396/pypy/translator/goal/nanos.py (contents, props changed)
pypy/branch/windows48396/pypy/translator/goal/test2/test_nanos.py (contents, props changed)
Modified:
pypy/branch/windows48396/pypy/translator/goal/app_main.py
pypy/branch/windows48396/pypy/translator/goal/targetpypystandalone.py
Log:
a final solution to the import problem in app_main.py
Actually quite elegant and minimal
Modified: pypy/branch/windows48396/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/branch/windows48396/pypy/translator/goal/app_main.py (original)
+++ pypy/branch/windows48396/pypy/translator/goal/app_main.py Fri Nov 23 19:05:18 2007
@@ -144,64 +144,27 @@
# ____________________________________________________________
# Main entry point
-# faking os, until we really are able to import it from source
-"""
-Why reload_os ?
----------------
-
-When pypy is starting, the builtin modules are there, but os.path
-is a Python module. The current startup code depends on os.py,
-which had the side effect that os.py got frozen into the binary.
-
-Os.py is a wrapper for system specific built-in modules and tries
-to unify the interface. One problem is os.environ which looks
-very differently per os.
-Access to os.environ is not possible on Windows, due to caching
-problems. We solve that by passing the PATH envirnment setting
-in from a low-level interface.
-
-As an intermediate hack, the os.path functions are used until
-os.py can be imported. The module is then re-imported. This
-intermediate, since it will still leave os.environ unusable.
-(the last version solved that by hairy import tricks)
-
-The next version will avoid early import of os, alltogether.
-"""
+# 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():
- # this function does not exist on app-level.
- # Don't confuse it with
- # from pypy.rlib.objectmodel import we_are_translated
- # which I did.
+ # app-level, very different from pypy.rlib.objectmodel.we_are_translated
return hasattr(sys, 'pypy_translation_info')
-class reload_os:
- def __init__(self):
- self.pre_import = sys.modules.keys()
-
- def reload(self):
- # re-load modules instead of using the pre-compiled ones
- # note that this gives trouble if we are not translated,
- # since some exithandler in threading.py complains
- if we_are_translated():
- for mod in sys.modules.keys():
- if mod not in self.pre_import:
- del sys.modules[mod]
- global os
- import os
-
-reload_os = reload_os()
-import os
-
-AUTOSUBPATH = 'share' + os.sep + 'pypy-%d.%d'
-
if 'nt' in sys.builtin_module_names:
IS_WINDOWS = True
DRIVE_LETTER_SEP = ':'
else:
IS_WINDOWS = False
-def entry_point(executable, argv, path):
+def entry_point(executable, argv, nanos):
+ # a substituted os if we are translated
+ global os
+ os = nanos
+ AUTOSUBPATH = 'share' + os.sep + 'pypy-%d.%d'
# 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'):
@@ -209,8 +172,7 @@
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')
- # we avoid getenv
+ path = os.getenv('PATH')
if path:
for dir in path.split(os.pathsep):
fn = os.path.join(dir, executable)
@@ -238,8 +200,6 @@
sys.path = newpath # found!
break
- reload_os.reload() # from now on use a fresh import
-
go_interactive = False
run_command = False
import_site = True
@@ -441,6 +401,7 @@
if __name__ == '__main__':
+ import os
import autopath
# obscure! try removing the following line, see how it crashes, and
# guess why...
@@ -459,5 +420,5 @@
from pypy.module.sys.version import PYPY_VERSION
sys.pypy_version_info = PYPY_VERSION
sys.pypy_initial_path = pypy_initial_path
- sys.exit(entry_point(sys.argv[0], sys.argv[1:], os.getenv("PATH")))
+ sys.exit(entry_point(sys.argv[0], sys.argv[1:], os))
#sys.exit(entry_point('app_main.py', sys.argv[1:]))
Added: pypy/branch/windows48396/pypy/translator/goal/nanos.py
==============================================================================
--- (empty file)
+++ pypy/branch/windows48396/pypy/translator/goal/nanos.py Fri Nov 23 19:05:18 2007
@@ -0,0 +1,53 @@
+"""
+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, ObjSpace, W_Root, interp2app
+import os
+
+app_os_path = applevel(r'''
+ from os.path import dirname, join, abspath, isfile, islink
+''', filename=__file__)
+
+app_os = applevel(r'''
+ from os import sep, pathsep
+ try:
+ from os import readlink
+ except ImportError:
+ pass
+''', filename=__file__)
+
+def getenv(space, w_name):
+ name = space.str_w(w_name)
+ return space.wrap(os.environ.get(name))
+getenv_w = interp2app(getenv, unwrap_spec=[ObjSpace, W_Root])
+
+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
Modified: pypy/branch/windows48396/pypy/translator/goal/targetpypystandalone.py
==============================================================================
--- pypy/branch/windows48396/pypy/translator/goal/targetpypystandalone.py (original)
+++ pypy/branch/windows48396/pypy/translator/goal/targetpypystandalone.py Fri Nov 23 19:05:18 2007
@@ -8,6 +8,7 @@
from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy
from pypy.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE
from pypy.tool.option import make_objspace
+from pypy.translator.goal.nanos import setup_nanos
thisdir = py.magic.autopath().dirpath()
@@ -26,6 +27,7 @@
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)
def entry_point(argv):
#debug("entry point starting")
@@ -43,9 +45,7 @@
space.call_function(w_run_toplevel, w_call_startup_gateway)
w_executable = space.wrap(argv[0])
w_argv = space.newlist([space.wrap(s) for s in argv[1:]])
- # we avoid using app-level environ due to the weird initialization of os
- w_path = space.wrap(os.environ.get("PATH"))
- w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_path)
+ w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_os)
exitcode = space.int_w(w_exitcode)
# try to pull it all in
## from pypy.interpreter import main, interactive, error
Added: pypy/branch/windows48396/pypy/translator/goal/test2/test_nanos.py
==============================================================================
--- (empty file)
+++ pypy/branch/windows48396/pypy/translator/goal/test2/test_nanos.py Fri Nov 23 19:05:18 2007
@@ -0,0 +1,20 @@
+"""
+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
+
+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)
+ entry_point(['', '-c', 'print 42'])
More information about the Pypy-commit
mailing list