Commits

Armin Rigo committed 03da2db

Wohoo! 'python interactive.py std' will successfully run a (very) limited set
of operations on top of the standard object space! It can now be used to
test, say, integer operations (for example, 'import sys; sys.maxint+1' which
raises an OverflowError).
--This line, and those below, will be ignored--

M /home/arigo/python/pypy/pypy/trunk/src/pypy/interpreter/test/test_pyframe_app.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/interpreter/opcode.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/interpreter/opcode_app.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/interpreter/pyframe_app.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/interpreter/pyframe.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/trivial.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/multimethod.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/dictobject.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/cpythonobject.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/tupleobject.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/funcobject.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/noneobject.py
M /home/arigo/python/pypy/pypy/trunk/src/pypy/objspace/std/objspace.py

Comments (0)

Files changed (13)

pypy/interpreter/opcode.py

     # but not to actually raise it, because we cannot use the 'raise'
     # statement to implement RAISE_VARARGS
     if nbargs == 0:
-        w_resulttuple = f.space.gethelper(appfile).call("prepare_raise0")
+        w_resulttuple = f.space.gethelper(appfile).call("prepare_raise0", [])
     elif nbargs == 1:
         w_type = f.valuestack.pop()
         w_resulttuple = f.space.gethelper(appfile).call(
 
 def GET_ITER(f):
     w_iterable = f.valuestack.pop()
-    w_iterator = f.space.op.iter(w_iterable)
+    w_iterator = f.space.iter(w_iterable)
     f.valuestack.push(w_iterator)
 
 def FOR_ITER(f, jumpby):
     w_iterator = f.valuestack.top()
     try:
-        w_nextitem = f.space.op.next(w_iterator)
+        w_nextitem = f.space.next(w_iterator)
     except NoValue:
         # iterator exhausted
         f.valuestack.pop()

pypy/interpreter/opcode_app.py

     
 def prepare_raise(etype, value, traceback):
     import types
+    # XXX we get an infinite loop if this import fails:
+    #    import types -> IMPORT_NAME -> import_name -> raise ImportError
+    #    -> RAISE_VARARGS -> prepare_raise -> import types ...
     if  not isinstance(traceback, (types.NoneType, types.TracebackType)):
             raise TypeError, "raise: arg 3 must be traceback or None"
     while isinstance(etype, tuple):

pypy/interpreter/pyframe.py

         for i in range(len(arguments)):
             varname = self.getlocalvarname(i)
             w_varname = self.space.wrap(varname)
-            w_arg = self.space.wrap(arguments[i])
+            w_arg = arguments[i]
             self.space.setitem(self.w_locals, w_varname, w_arg)
 
     def decode_arguments(self, w_arguments, w_kwargs, w_defaults, w_closure):

pypy/interpreter/pyframe_app.py

                 
     # Fill in with defaults, starting at argcount - defcount
     if defs:
-        argcount = len(codeobject.co_varnames)
+        argcount = codeobject.co_argcount
         defcount = len(defs)
         for i in range(argcount - defcount, argcount):
             if argdict.has_key(parameter_names[i]):

pypy/interpreter/test/test_pyframe_app.py

     """ A code object class for test purposes. """
     def __init__(self, count=3, vflag = 0, kflag = 0):
         self.co_argcount = count
-        self.co_varnames = ('a', 'b', 'c', 'd', 'e')[:count]
+        self.co_varnames = ('a', 'b', 'c', 'd', 'e')
         self.co_flags = 4 * vflag + 8 * kflag
 
 

pypy/objspace/std/cpythonobject.py

 from pypy.objspace.std.objspace import *
+from stringobject import W_StringObject
 
 
 class W_CPythonObject:
     return space.wrap(id(w_obj.cpyobj))
 
 StdObjSpace.id.register(cpython_id, W_CPythonObject)
+
+def cpython_getattr(space, w_obj, w_attrname):
+    attributevalue = getattr(w_obj.cpyobj, w_attrname.value)
+    return space.wrap(attributevalue)
+
+StdObjSpace.getattr.register(cpython_getattr, W_CPythonObject, W_StringObject)
+
+def cpython_call(space, w_obj, w_arguments, w_keywords):
+    # XXX temporary hack similar to objspace.trivial.call()
+    # XXX keywords are ignored
+    callable = space.unwrap(w_obj)
+    args = space.unwrap(w_arguments)
+    try:
+        result = apply(callable, args)
+    except:
+        raise OperationError(*sys.exc_info()[:2])
+    return space.wrap(result)
+
+StdObjSpace.call.register(cpython_call, W_CPythonObject, W_ANY, W_ANY)

pypy/objspace/std/dictobject.py

 
 StdObjSpace.is_true.register(dict_is_true, W_DictObject)
 
+def dict_unwrap(space, w_dict):
+    result = {}
+    for w_key, w_value in w_dict.data:
+        result[space.unwrap(w_key)] = space.unwrap(w_value)
+    return result
+
+StdObjSpace.unwrap.register(dict_unwrap, W_DictObject)
+
 def getitem_dict_any(space, w_dict, w_lookup):
     data = w_dict.data
     for w_key, w_value in data:

pypy/objspace/std/funcobject.py

+from __future__ import nested_scopes
 from pypy.objspace.std.objspace import *
 import pypy.interpreter.pyframe
 
         w_self.w_closure = w_closure
 
 
+def function_unwrap(space, w_function):
+    # XXX this is probably a temporary hack
+    def proxy_function(*args, **kw):
+        w_arguments = space.wrap(args)
+        w_keywords  = space.wrap(kw)
+        w_result = func_call(space, w_function, w_arguments, w_keywords)
+        return space.unwrap(w_result)
+    # XXX no closure implemented
+    return proxy_function
+
+StdObjSpace.unwrap.register(function_unwrap, W_FuncObject)
+
+
 def func_call(space, w_function, w_arguments, w_keywords):
     ec = space.getexecutioncontext()
     bytecode = space.unwrap(w_function.w_code)

pypy/objspace/std/multimethod.py

             w_value = self.space.wrap(message)
             raise OperationError(self.space.w_TypeError, w_value)
         else:
-            raise e
+            raise OperationError(*e.args)
 
 
 class error(Exception):

pypy/objspace/std/noneobject.py

+from pypy.objspace.std.objspace import *
+
 
 class W_NoneObject:
     delegate_once = {}
         "Implements 'is'."
         # all w_None wrapped values are equal ('is'-identical)
         return isinstance(w_other, W_NoneObject)
+
+
+def none_unwrap(space, w_none):
+    return None
+
+StdObjSpace.unwrap.register(none_unwrap, W_NoneObject)

pypy/objspace/std/objspace.py

 from pypy.interpreter.baseobjspace import *
 from multimethod import *
 
+if not isinstance(bool, type):
+    booltype = ()
+else:
+    booltype = bool
+
 
 ##################################################################
 
                 w_c = W_CPythonObject(c)
                 setattr(self, 'w_' + c.__name__, w_c)
                 self.setitem(self.w_builtins, self.wrap(c.__name__), w_c)
+        # add a dummy __import__  XXX fixme
+        w_import = self.wrap(__import__)
+        self.setitem(self.w_builtins, self.wrap("__import__"), w_import)
 
     def wrap(self, x):
         "Wraps the Python value 'x' into one of the wrapper classes."
+        if x is None:
+            return self.w_None
         if isinstance(x, int):
+            if isinstance(x, booltype):
+                return self.newbool(x)
             import intobject
             return intobject.W_IntObject(x)
         if isinstance(x, str):

pypy/objspace/std/tupleobject.py

 
 
 class W_TupleObject(object):
+
     def __init__(self, wrappeditems):
         self.wrappeditems = wrappeditems   # a list of wrapped values
 
+    def __repr__(w_self):
+        """ representation for debugging purposes """
+        reprlist = [repr(w_item) for w_item in w_self.wrappeditems]
+        return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
+
 
 def tuple_unwrap(space, w_tuple):
     items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems]

pypy/objspace/trivial.py

     str       = str
     len       = len
     pow       = pow
+    divmod    = divmod
     hash      = hash
     setattr   = setattr
     delattr   = delattr
         except:
             raise OperationError(*sys.exc_info()[:2])
 
-    for _name in ('pos', 'neg', 'not_', 'pos', 'neg', 'not_', 'invert',
+    for _name in ('pos', 'neg', 'not_', 'abs', 'invert',
                  'mul', 'truediv', 'floordiv', 'div', 'mod',
                  'add', 'sub', 'lshift', 'rshift', 'and_', 'xor', 'or_',
                  'getitem', 'setitem', 'delitem', 'contains',
 
 
     # misc
-    def iternext(self, w):
+    def next(self, w):
         try:
             return w.next()
         except StopIteration:
             raise NoValue
 
     def newfunction(self, code, globals, defaultarguments, closure=None):
-        if closure is None:   # temp hack
+        if closure is None:   # temp hack for Python 2.2
             return new.function(code, globals, None, defaultarguments)
         return new.function(code, globals, None, defaultarguments, closure)
 
             bytecode = callable.func_code
             ec = self.getexecutioncontext()
             w_globals = self.wrap(callable.func_globals)
+            w_defaults = self.wrap(callable.func_defaults)
             w_locals = self.newdict([])
             frame = pyframe.PyFrame(self, bytecode, w_globals, w_locals)
             # perform call
-            frame.setargs(args, kwds)
+            frame.setargs(args, kwds, w_defaults)
             return ec.eval_frame(frame)
         else:
-            return apply(callable, args, kwds)
+            try:
+                return apply(callable, args, kwds)
+            except:
+                raise OperationError(*sys.exc_info()[:2])