[pypy-svn] pypy default: Support "pypy filename.pyc".

arigo commits-noreply at bitbucket.org
Mon Feb 14 11:48:10 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41893:723cc5563f33
Date: 2011-02-13 18:30 +0100
http://bitbucket.org/pypy/pypy/changeset/723cc5563f33/

Log:	Support "pypy filename.pyc".

diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -3,7 +3,7 @@
 from pypy.rlib import streamio
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.module import Module
-from pypy.interpreter.gateway import NoneNotWrapped
+from pypy.interpreter.gateway import NoneNotWrapped, W_Root, ObjSpace
 import struct
 
 def get_suffixes(space):
@@ -98,23 +98,26 @@
         stream.close()
     return w_mod
 
-def load_compiled(space, w_modulename, w_filename, w_file=None):
-    filename = space.str_w(w_filename)
-
+def _run_compiled_module(space, w_modulename, filename, w_file, w_module):
+    # the function 'imp._run_compiled_module' is a pypy-only extension
     stream = get_file(space, w_file, filename, 'rb')
 
-    w_mod = space.wrap(Module(space, w_modulename))
-    importing._prepare_module(space, w_mod, filename, None)
-
     magic = importing._r_long(stream)
     timestamp = importing._r_long(stream)
 
     importing.load_compiled_module(
-        space, w_modulename, w_mod, filename, magic, timestamp,
+        space, w_modulename, w_module, filename, magic, timestamp,
         stream.readall())
     if space.is_w(w_file, space.w_None):
         stream.close()
+_run_compiled_module.unwrap_spec = [ObjSpace, W_Root, str, W_Root, W_Root]
+
+def load_compiled(space, w_modulename, filename, w_file=None):
+    w_mod = space.wrap(Module(space, w_modulename))
+    importing._prepare_module(space, w_mod, filename, None)
+    _run_compiled_module(space, w_modulename, filename, w_file, w_mod)
     return w_mod
+load_compiled.unwrap_spec = [ObjSpace, W_Root, str, W_Root]
 
 def new_module(space, w_name):
     return space.wrap(Module(space, w_name))

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
@@ -550,10 +550,21 @@
         else:
             # handle the common case where a filename is specified
             # on the command-line.
-            mainmodule.__file__ = sys.argv[0]
-            scriptdir = resolvedirof(sys.argv[0])
-            sys.path.insert(0, scriptdir)
-            success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__)
+            filename = sys.argv[0]
+            mainmodule.__file__ = filename
+            sys.path.insert(0, 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.
+            if IS_WINDOWS:
+                filename = filename.lower()
+            if filename.endswith('.pyc') or filename.endswith('.pyo'):
+                import imp
+                success = run_toplevel(imp._run_compiled_module, '__main__',
+                                       sys.argv[0], None, mainmodule)
+            else:
+                success = run_toplevel(execfile, sys.argv[0],
+                                       mainmodule.__dict__)
 
     except SystemExit, e:
         status = e.code
@@ -623,6 +634,19 @@
         except OSError:
             return None
 
+    # add an emulator for this pypy-only function
+    # (for test_pyc_commandline_argument)
+    import imp
+    def _run_compiled_module(modulename, filename, file, module):
+        import os
+        assert modulename == '__main__'
+        assert os.path.isfile(filename)
+        assert filename.endswith('.pyc')
+        assert file is None
+        assert module.__name__ == '__main__'
+        print 'in _run_compiled_module'
+    imp._run_compiled_module = _run_compiled_module
+
     # stick the current sys.path into $PYTHONPATH, so that CPython still
     # finds its own extension modules :-/
     import os

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
@@ -14,14 +14,36 @@
 app_main = os.path.abspath(app_main)
 
 _counter = 0
-def getscript(source):
+def _get_next_path():
     global _counter
     p = udir.join('demo_test_app_main_%d.py' % (_counter,))
     _counter += 1
+    return p
+
+def getscript(source):
+    p = _get_next_path()
     p.write(str(py.code.Source(source)))
     # return relative path for testing purposes 
     return py.path.local().bestrelpath(p) 
 
+def getscriptpyc(space, source):
+    p = _get_next_path()
+    p.write(str(py.code.Source(source)))
+    w_dir = space.wrap(str(p.dirpath()))
+    w_modname = space.wrap(p.purebasename)
+    space.appexec([w_dir, w_modname], """(dir, modname):
+        import sys
+        d = sys.modules.copy()
+        sys.path.insert(0, dir)
+        __import__(modname)
+        sys.path.pop(0)
+        for key in sys.modules.keys():
+            if key not in d:
+                del sys.modules[key]
+    """)
+    p = str(p) + 'c'
+    assert os.path.isfile(p)   # the .pyc file should have been created above
+    return p
 
 demo_script = getscript("""
     print 'hello'
@@ -671,6 +693,12 @@
         data = self.run('-c "import sys; print sys.path"')
         assert data.startswith("[''")
 
+    def test_pyc_commandline_argument(self):
+        p = getscriptpyc(self.space, "print 6*7\n")
+        assert p.endswith('.pyc')
+        data = self.run(p)
+        assert data == 'in _run_compiled_module\n'
+
 
 class AppTestAppMain:
 

diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py
--- a/pypy/module/imp/__init__.py
+++ b/pypy/module/imp/__init__.py
@@ -19,6 +19,7 @@
         'load_module':     'interp_imp.load_module',
         'load_source':     'interp_imp.load_source',
         'load_compiled':   'interp_imp.load_compiled',
+        '_run_compiled_module': 'interp_imp._run_compiled_module',
         #'run_module':      'interp_imp.run_module',
         'new_module':      'interp_imp.new_module',
         'init_builtin':    'interp_imp.init_builtin',


More information about the Pypy-commit mailing list