[pypy-svn] r11876 - in pypy/dist/pypy: interpreter module/sys2

arigo at codespeak.net arigo at codespeak.net
Tue May 3 17:31:48 CEST 2005


Author: arigo
Date: Tue May  3 17:31:47 2005
New Revision: 11876

Modified:
   pypy/dist/pypy/interpreter/interactive.py
   pypy/dist/pypy/interpreter/main.py
   pypy/dist/pypy/interpreter/py.py
   pypy/dist/pypy/module/sys2/__init__.py
   pypy/dist/pypy/module/sys2/app.py
Log:
Cleaned up a bit py.py / main.py / interactive.py, implementing a more
complete exception behavior: normalization, calling sys.excepthook(), ...



Modified: pypy/dist/pypy/interpreter/interactive.py
==============================================================================
--- pypy/dist/pypy/interpreter/interactive.py	(original)
+++ pypy/dist/pypy/interpreter/interactive.py	Tue May  3 17:31:47 2005
@@ -159,52 +159,11 @@
 
     def runcode(self, code):
         # 'code' is a CPython code object
-        from pypy.interpreter.pycode import PyCode
-        pycode = PyCode(self.space)._from_code(code)
-        try:
-            self.settrace()
-            pycode.exec_code(self.space, self.w_globals, self.w_globals)
-            self.checktrace()
-            
-        except error.OperationError, operationerr:
-            space = self.space
-            try:
-                if operationerr.match(space, space.w_SystemExit):
-                    w_exitcode = space.getattr(operationerr.w_value,
-                                               space.wrap('code'))
-                    if space.is_w(w_exitcode, space.w_None):
-                        exitcode = 0
-                    else:
-                        try:
-                            exitcode = space.int_w(w_exitcode)
-                        except error.OperationError:
-                            # not an integer: print it to stderr
-                            msg = space.str_w(space.str(w_exitcode))
-                            print >> sys.stderr, msg
-                            exitcode = 1
-                    raise SystemExit(exitcode)
-                space.setitem(space.sys.w_dict, space.wrap('last_type'),
-                              operationerr.w_type)
-                space.setitem(space.sys.w_dict, space.wrap('last_value'),
-                              operationerr.w_value)
-                space.setitem(space.sys.w_dict, space.wrap('last_traceback'),
-                              space.wrap(operationerr.application_traceback))
-            except error.OperationError, operationerr:
-                pass   # let the code below print any error we get above
-            if self.verbose:
-                operationerr.print_detailed_traceback(space)
-            else:
-                operationerr.print_application_traceback(space)
-            # for debugging convenience we also insert the exception into
-            # the interpreter-level sys.last_xxx
-            sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
-        else:
-            try:
-                if sys.stdout.softspace:
-                    print
-            except AttributeError:
-                # Don't crash if user defined stdout doesn't have softspace
-                pass
+        self.settrace()
+        main.run_toplevel_program(self.space, code,
+                                  w_globals=self.w_globals,
+                                  verbose=self.verbose)
+        self.checktrace()
 
     def runsource(self, source, ignored_filename="<input>", symbol="single"):
         hacked_filename = '<inline>' + source

Modified: pypy/dist/pypy/interpreter/main.py
==============================================================================
--- pypy/dist/pypy/interpreter/main.py	(original)
+++ pypy/dist/pypy/interpreter/main.py	Tue May  3 17:31:47 2005
@@ -1,7 +1,8 @@
 import autopath
-from pypy.interpreter import executioncontext, module
+from pypy.interpreter import executioncontext, module, eval
 from pypy.interpreter.error import OperationError
-import sys
+from pypy.interpreter.pycode import PyCode
+import sys, types
 
 def ensure__main__(space):
     w_main = space.wrap('__main__')
@@ -15,6 +16,18 @@
     space.setitem(w_modules, w_main, mainmodule)
     return mainmodule
 
+def compilecode(space, source, filename, cmd='exec'):
+    if isinstance(source, types.CodeType):
+        pycode = PyCode(space)._from_code(source)
+    else:
+        w = space.wrap
+        w_code = space.builtin.call('compile', 
+                 w(source), w(filename), w(cmd), w(0), w(0))
+        pycode = space.interpclass_w(w_code)
+    assert isinstance(pycode, eval.Code)
+    return pycode
+
+
 def _run_eval_string(source, filename, space, eval):
     if eval:
         cmd = 'eval'
@@ -27,15 +40,14 @@
             space = StdObjSpace()
 
         w = space.wrap
-        w_code = space.builtin.call('compile', 
-                 w(source), w(filename), w(cmd), w(0), w(0))
+
+        pycode = compilecode(space, source, filename, cmd)
 
         mainmodule = ensure__main__(space)
         w_globals = mainmodule.w_dict
 
         space.setitem(w_globals, w('__builtins__'), space.builtin)
 
-        pycode = space.interpclass_w(w_code)
         retval = pycode.exec_code(space, w_globals, w_globals)
         if eval:
             return retval
@@ -57,3 +69,96 @@
         print "Running %r with %r" % (filename, space)
     istring = open(filename).read()
     run_string(istring, filename, space)
+
+# ____________________________________________________________
+
+def run_toplevel_program(space, source, filename='<program>',
+                         w_globals=None, verbose=False):
+    """Run the given source code in the given globals (or __main__ by default).
+    Intended use is to run the main program or one interactive statement.
+    It handles details like forwarding exceptions to sys.excepthook(),
+    catching SystemExit, printing a newline after sys.stdout if needed, etc.
+    """
+    try:
+        # build a valid w_globals
+        if w_globals is None:
+            w_globals = ensure__main__(space).w_dict
+        w1 = space.wrap('__builtins__')
+        if not space.is_true(space.contains(w_globals, w1)):
+            space.setitem(w_globals, w1, space.builtin)
+
+        # compile and execute the code
+        pycode = compilecode(space, source, filename)
+        pycode.exec_code(space, w_globals, w_globals)
+
+        # we arrive here if no exception is raised.  stdout cosmetics...
+        try:
+            w_stdout = space.sys.get('stdout')
+            w_softspace = space.getattr(w_stdout, space.wrap('softspace'))
+        except OperationError, e:
+            if not e.match(space, space.w_AttributeError):
+                raise
+            # Don't crash if user defined stdout doesn't have softspace
+        else:
+            if space.is_true(w_softspace):
+                space.call_method(w_stdout, 'write', space.wrap('\n'))
+
+    except OperationError, operationerr:
+        operationerr.normalize_exception(space)
+        w_type = operationerr.w_type
+        w_value = operationerr.w_value
+        w_traceback = space.wrap(operationerr.application_traceback)
+
+        # for debugging convenience we also insert the exception into
+        # the interpreter-level sys.last_xxx
+        operationerr.record_interpreter_traceback()
+        sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
+
+        try:
+            # exit if we catch a w_SystemExit
+            if operationerr.match(space, space.w_SystemExit):
+                w_exitcode = space.getattr(operationerr.w_value,
+                                           space.wrap('code'))
+                if space.is_w(w_exitcode, space.w_None):
+                    exitcode = 0
+                else:
+                    try:
+                        exitcode = space.int_w(w_exitcode)
+                    except OperationError:
+                        # not an integer: print it to stderr
+                        msg = space.str_w(space.str(w_exitcode))
+                        print >> sys.stderr, msg
+                        exitcode = 1
+                raise SystemExit(exitcode)
+
+            # set the sys.last_xxx attributes
+            space.setitem(space.sys.w_dict, space.wrap('last_type'), w_type)
+            space.setitem(space.sys.w_dict, space.wrap('last_value'), w_value)
+            space.setitem(space.sys.w_dict, space.wrap('last_traceback'),
+                          w_traceback)
+
+            # call sys.excepthook if present
+            w_hook = space.sys.getdictvalue(space, 'excepthook')
+            if w_hook is not None:
+                # hack: skip it if it wasn't modified by the user,
+                #       to do instead the faster verbose/nonverbose thing below
+                w_original = space.sys.getdictvalue(space, '__excepthook__')
+                if w_original is None or not space.is_w(w_hook, w_original):
+                    space.call_function(w_hook, w_type, w_value, w_traceback)
+                    return 1   # done
+
+        except OperationError, err2:
+            # XXX should we go through sys.get('stderr') ?
+            print >> sys.stderr, 'Error calling sys.excepthook:'
+            err2.print_application_traceback(space)
+            print >> sys.stderr
+            print >> sys.stderr, 'Original exception was:'
+
+        # we only get here if sys.excepthook didn't do its job
+        if verbose:
+            operationerr.print_detailed_traceback(space)
+        else:
+            operationerr.print_application_traceback(space)
+        return 1
+
+    return 0   # success

Modified: pypy/dist/pypy/interpreter/py.py
==============================================================================
--- pypy/dist/pypy/interpreter/py.py	(original)
+++ pypy/dist/pypy/interpreter/py.py	Tue May  3 17:31:47 2005
@@ -52,65 +52,117 @@
 
 def main_(argv=None):
     starttime = time.time() 
-    from pypy.tool import tb_server
     args = option.process_options(get_main_options(), Options, argv[1:])
-    space = None
-    exit_status = 1   # until proven otherwise
-                      # XXX should review what CPython's policy is for
-                      # the exit status code
-    try:
-        space = option.objspace()
-        space._starttime = starttime
-        assert 'pypy.tool.udir' not in sys.modules, (
-            "running py.py should not import pypy.tool.udir, which is\n"
-            "only for testing or translating purposes.")
-        go_interactive = Options.interactive
-        if Options.verbose:
-            error.RECORD_INTERPLEVEL_TRACEBACK = True
-        banner = ''
-        space.setitem(space.sys.w_dict,space.wrap('executable'),space.wrap(argv[0]))
-        if Options.command:
-            args = ['-c'] + Options.command[1:]
-        for arg in args:
-            space.call_method(space.sys.get('argv'), 'append', space.wrap(arg))
-        try:
-            if Options.command:
-                main.run_string(Options.command[0], '<string>', space)
-            elif args:
-                main.run_file(args[0], space)
-            else:
-                space.call_method(space.sys.get('argv'), 'append', space.wrap(''))
-                go_interactive = 1
-                banner = None
-            exit_status = 0
-        except error.OperationError, operationerr:
-            if Options.verbose:
-                operationerr.print_detailed_traceback(space)
-            else:
-                operationerr.print_application_traceback(space)
-        if go_interactive:
-            con = interactive.PyPyConsole(space, verbose=Options.verbose, completer=Options.completer)
-            if banner == '':
-                banner = '%s / %s'%(con.__class__.__name__,
-                                    repr(space))
-            con.interact(banner)
-    except:
-        exc_type, value, tb = sys.exc_info()
-        sys.last_type = exc_type
-        sys.last_value = value
-        sys.last_traceback = tb
-        if issubclass(exc_type, SystemExit):
-            pass   # don't print tracebacks for SystemExit
-        elif isinstance(value, error.OperationError):
-            value.print_detailed_traceback(space=space)
-        else:
-            sys.excepthook(exc_type, value, tb)
-        tb_server.wait_until_interrupt()
-        exit_status = 1
-            
-    tb_server.stop()
+    if Options.verbose:
+        error.RECORD_INTERPLEVEL_TRACEBACK = True
+
+    # create the object space
+    space = option.objspace()
+    space._starttime = starttime
+    assert 'pypy.tool.udir' not in sys.modules, (
+        "running py.py should not import pypy.tool.udir, which is\n"
+        "only for testing or translating purposes.")
+    space.setitem(space.sys.w_dict,space.wrap('executable'),space.wrap(argv[0]))
+
+    # store the command-line arguments into sys.argv
+    go_interactive = Options.interactive
+    banner = ''
+    exit_status = 0
+    if Options.command:
+        args = ['-c'] + Options.command[1:]
+    for arg in args:
+        space.call_method(space.sys.get('argv'), 'append', space.wrap(arg))
+
+    # compile the program given as command-line argument
+    if Options.command:
+        filename = '<string>'
+        fullsource = Options.command[0]
+    elif args:
+        filename = args[0]
+        fullsource = open(filename).read()
+    else:
+        filename = fullsource = None
+        space.call_method(space.sys.get('argv'), 'append', space.wrap(''))
+        go_interactive = 1
+        banner = None
+
+    # run it
+    if fullsource is not None:
+        exit_status = main.run_toplevel_program(space, fullsource, filename,
+                                                verbose=Options.verbose)
+
+    # start the interactive console
+    if go_interactive:
+        con = interactive.PyPyConsole(space, verbose=Options.verbose,
+                                             completer=Options.completer)
+        if banner == '':
+            banner = '%s / %s'%(con.__class__.__name__,
+                                repr(space))
+        con.interact(banner)
+        exit_status = 0
     return exit_status
 
+##def main_(argv=None):
+##    starttime = time.time() 
+##    from pypy.tool import tb_server
+##    args = option.process_options(get_main_options(), Options, argv[1:])
+##    space = None
+##    exit_status = 1   # until proven otherwise
+##                      # XXX should review what CPython's policy is for
+##                      # the exit status code
+##    try:
+##        space = option.objspace()
+##        space._starttime = starttime
+##        assert 'pypy.tool.udir' not in sys.modules, (
+##            "running py.py should not import pypy.tool.udir, which is\n"
+##            "only for testing or translating purposes.")
+##        go_interactive = Options.interactive
+##        if Options.verbose:
+##            error.RECORD_INTERPLEVEL_TRACEBACK = True
+##        banner = ''
+##        space.setitem(space.sys.w_dict,space.wrap('executable'),space.wrap(argv[0]))
+##        if Options.command:
+##            args = ['-c'] + Options.command[1:]
+##        for arg in args:
+##            space.call_method(space.sys.get('argv'), 'append', space.wrap(arg))
+##        try:
+##            if Options.command:
+##                main.run_string(Options.command[0], '<string>', space)
+##            elif args:
+##                main.run_file(args[0], space)
+##            else:
+##                space.call_method(space.sys.get('argv'), 'append', space.wrap(''))
+##                go_interactive = 1
+##                banner = None
+##            exit_status = 0
+##        except error.OperationError, operationerr:
+##            if Options.verbose:
+##                operationerr.print_detailed_traceback(space)
+##            else:
+##                operationerr.print_application_traceback(space)
+##        if go_interactive:
+##            con = interactive.PyPyConsole(space, verbose=Options.verbose, completer=Options.completer)
+##            if banner == '':
+##                banner = '%s / %s'%(con.__class__.__name__,
+##                                    repr(space))
+##            con.interact(banner)
+##    except:
+##        exc_type, value, tb = sys.exc_info()
+##        sys.last_type = exc_type
+##        sys.last_value = value
+##        sys.last_traceback = tb
+##        if issubclass(exc_type, SystemExit):
+##            pass   # don't print tracebacks for SystemExit
+##        elif isinstance(value, error.OperationError):
+##            value.print_detailed_traceback(space=space)
+##        else:
+##            sys.excepthook(exc_type, value, tb)
+##        tb_server.wait_until_interrupt()
+##        exit_status = 1
+            
+##    tb_server.stop()
+##    return exit_status
+
 if __name__ == '__main__':
     try:
         import readline

Modified: pypy/dist/pypy/module/sys2/__init__.py
==============================================================================
--- pypy/dist/pypy/module/sys2/__init__.py	(original)
+++ pypy/dist/pypy/module/sys2/__init__.py	Tue May  3 17:31:47 2005
@@ -64,7 +64,7 @@
         #'displayhook'           : 'app.displayhook', 
         #'__displayhook__'       : 'app.__displayhook__', 
         'excepthook'            : 'app.excepthook', 
-        '__excepthook__'        : 'app.__excepthook__', 
+        '__excepthook__'        : 'app.excepthook', 
         'exit'                  : 'app.exit', 
         'getfilesystemencoding' : 'app.getfilesystemencoding', 
         'callstats'             : 'app.callstats',

Modified: pypy/dist/pypy/module/sys2/app.py
==============================================================================
--- pypy/dist/pypy/module/sys2/app.py	(original)
+++ pypy/dist/pypy/module/sys2/app.py	Tue May  3 17:31:47 2005
@@ -7,13 +7,10 @@
 
 import sys 
 
-# XXX not called by the core yet
 def excepthook(exctype, value, traceback):
     from traceback import print_exception
     print_exception(exctype, value, traceback)
 
-__excepthook__ = excepthook  # this is exactly like in CPython
-
 def exit(exitcode=0):
     # note that we cannot use SystemExit(exitcode) here.
     # The comma version leads to an extra de-tupelizing



More information about the Pypy-commit mailing list