[pypy-svn] rev 2402 - in pypy/trunk/src/pypy: interpreter interpreter/testmodule objspace objspace/std

hpk at codespeak.net hpk at codespeak.net
Tue Dec 16 18:12:49 CET 2003


Author: hpk
Date: Tue Dec 16 18:12:48 2003
New Revision: 2402

Modified:
   pypy/trunk/src/pypy/interpreter/baseobjspace.py
   pypy/trunk/src/pypy/interpreter/function.py
   pypy/trunk/src/pypy/interpreter/pycode.py
   pypy/trunk/src/pypy/interpreter/pyframe.py
   pypy/trunk/src/pypy/interpreter/pyopcode.py
   pypy/trunk/src/pypy/interpreter/test/test_code.py
   pypy/trunk/src/pypy/module/builtin.py
   pypy/trunk/src/pypy/objspace/std/cpythonobject.py
   pypy/trunk/src/pypy/objspace/std/objspace.py
   pypy/trunk/src/pypy/objspace/trivial.py
Log:
- fixed introspection and lots of pypy_* protocol places
  to allow full introspection of codeobjects and functions. 
  Frames are only inspectable for non-mutable attributes
  (due to a new ad-hoc Wrappable-mechanism) 

- fixed all failing tests 

(Samuele,Holger)



Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py	Tue Dec 16 18:12:48 2003
@@ -23,9 +23,9 @@
     def app_visible(self):
         """ returns [(name,w_value)...] for application-level visible attributes """ 
         raise NotImplementedError
-            
-    def pypy_getattr(self,w_name):
-        space = self.space
+
+    def pypy_getattr(self, w_name):
+        space = self.space 
         w_dict = self.get_wdict()
         try:
             return space.getitem(w_dict,w_name)

Modified: pypy/trunk/src/pypy/interpreter/function.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/function.py	(original)
+++ pypy/trunk/src/pypy/interpreter/function.py	Tue Dec 16 18:12:48 2003
@@ -30,6 +30,7 @@
                                             self.closure)
         frame.setfastscope(scope_w)
         return frame.run()
+
     pypy_call = call
 
     def parse_args(self, w_args, w_kwds=None):
@@ -166,13 +167,14 @@
             return Method(self.space, wrap(self), None, wrap(cls))
 
     def pypy_get(self, w_obj, w_cls):
-        wrap = self.space.wrap
-        if not self.space.is_true(self.space.is_(w_obj, self.space.w_None)):
-            if self.space.is_true(self.space.is_(w_cls, self.space.w_None)):
-                w_cls = self.space.type(w_obj)
-            return wrap(Method(self.space, wrap(self), w_obj, w_cls))
+        space = self.space
+        wrap = space.wrap
+        if not space.is_true(space.is_(w_obj, space.w_None)):
+            if space.is_true(space.is_(w_cls, space.w_None)):
+                w_cls = space.type(w_obj)
+            return wrap(Method(space, wrap(self), w_obj, w_cls))
         else:
-            return wrap(Method(self.space, wrap(self), None, w_cls))
+            return wrap(Method(space, wrap(self), None, w_cls))
 
     def __call__(self, *args_w, **kwds_w):
         wrap = self.space.wrap
@@ -183,10 +185,6 @@
         # (for FlowObjSpace)
         return self.space.call(wrap(self), w_args, w_kwds)
 
-    #def pypy_getattr(self, w_name):
-    #    space = self.space
-    #    raise OperationError(space.w_AttributeError, w_name)
-
     def app_visible(self):  
         space = self.space
         def makedict(**kw):
@@ -202,6 +200,7 @@
         it['__name__'] = it['func_name']
         it['__doc__'] = it['func_doc']
         it['__dict__'] = it['func_dict']
+        it['__call__'] = space.wrap(self)
         return it.items()
 
 class Method(object):
@@ -230,6 +229,7 @@
                 raise OperationError(self.space.w_TypeError,
                                      self.space.wrap(msg))
         return self.space.call(self.w_function, w_args, w_kwds)
+
     pypy_call = call
 
     def __call__(self, *args_w, **kwds_w):

Modified: pypy/trunk/src/pypy/interpreter/pycode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pycode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pycode.py	Tue Dec 16 18:12:48 2003
@@ -6,6 +6,8 @@
 
 import dis
 from pypy.interpreter import eval
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import Wrappable
 
 
 # code object contants, for co_flags below
@@ -16,6 +18,32 @@
 CO_NESTED       = 0x0010
 CO_GENERATOR    = 0x0020
 
+class AppPyCode(Wrappable):
+    """ applevel representation of a PyCode object. """
+    def __init__(self, pycode, space):
+        self.space = space
+        self.pycode = pycode
+
+    def __unwrap__(self):
+        return self.pycode
+        
+    def pypy_id(self):
+        # XXX we need a type system for internal objects!
+        return id(self.pycode)
+
+    def pypy_type(self):
+        # XXX we need a type system for internal objects!
+        return self.space.wrap(self.__class__)
+       
+    def app_visible(self):
+
+        # XXX change that if we have type objects ...
+        l = []
+        for name,value in self.pycode.__dict__.items():
+            if name.startswith('co_'):
+                l.append( (name, self.space.wrap(value)))
+        l.append(('__class__', self.pypy_type()))
+        return l
 
 class PyCode(eval.Code):
     "CPython-style code objects."
@@ -38,6 +66,9 @@
         self.co_firstlineno = 0      # first source line number
         self.co_lnotab = ""          # string: encoding addr<->lineno mapping
 
+    def __wrap__(self, space):
+        return space.wrap(AppPyCode(self, space))
+
     def _from_code(self, code):
         """ Initialize the code object from a real (CPython) one.
             This is just a hack, until we have our own compile.

Modified: pypy/trunk/src/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyframe.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyframe.py	Tue Dec 16 18:12:48 2003
@@ -6,7 +6,7 @@
 from pypy.interpreter.error import OperationError
 
 
-class PyFrame(eval.Frame):
+class PyFrame(eval.Frame, baseobjspace.Wrappable):
     """Represents a frame for a regular Python function
     that needs to be interpreted.
 
@@ -82,17 +82,19 @@
             if valuestackdepth <= self.valuestack.depth():
                 break
             self.exceptionstack.pop()
-
-    ### public attributes ###
-
-    def pypy_getattr(self, w_attr):
-        # XXX surely not the Right Way to do this
-        attr = self.space.unwrap(w_attr)
-        if attr == 'f_locals':   return self.w_locals
-        if attr == 'f_globals':  return self.w_globals
-        if attr == 'f_builtins': return self.w_builtins
-        if attr == 'f_code':     return self.space.wrap(self.code)
-        raise OperationError(self.space.w_AttributeError, w_attr)
+    
+    ### application level visible attributes ###
+    def app_visible(self):
+        def makedict(**kw): return kw
+        space = self.space
+        d = makedict(
+            f_code = space.wrap(self.code),
+            f_locals = self.getdictscope(),
+            f_globals = self.w_globals,
+            f_builtins = self.w_builtins,
+            # XXX f_lasti, f_back, f_exc*, f_restricted need to do pypy_getattr directly
+            )
+        return d.items() 
 
 ### Frame Blocks ###
 

Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyopcode.py	Tue Dec 16 18:12:48 2003
@@ -70,6 +70,7 @@
     def getname(self, index):
         return self.code.co_names[index]
 
+
     ################################################################
     ##  Implementation of the "operational" opcodes
     ##  See also pyfastscope.py and pynestedscope.py for the rest.
@@ -701,7 +702,7 @@
 
     def MAKE_FUNCTION(f, numdefaults):
         w_codeobj = f.valuestack.pop()
-        codeobj = f.space.unwrap(w_codeobj)
+        codeobj = f.space.unwrap(w_codeobj)   
         defaultarguments = [f.valuestack.pop() for i in range(numdefaults)]
         defaultarguments.reverse()
         fn = function.Function(f.space, codeobj, f.w_globals, defaultarguments)

Modified: pypy/trunk/src/pypy/interpreter/test/test_code.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/test/test_code.py	(original)
+++ pypy/trunk/src/pypy/interpreter/test/test_code.py	Tue Dec 16 18:12:48 2003
@@ -9,6 +9,7 @@
         def f(): pass
         code = f.func_code    
         self.assert_(hasattr(code, 'co_code'))
+        self.assert_(hasattr(code, '__class__'))
         self.assert_(not hasattr(code,'__dict__'))
         self.assertEquals(code.co_name,'f')
         self.assertEquals(code.co_names,())

Modified: pypy/trunk/src/pypy/module/builtin.py
==============================================================================
--- pypy/trunk/src/pypy/module/builtin.py	(original)
+++ pypy/trunk/src/pypy/module/builtin.py	Tue Dec 16 18:12:48 2003
@@ -35,6 +35,10 @@
 ##        self.w_imp_path = space.sys.w_path
 ##        ExtModule.__init__(self, space)
 
+    def __init__(self, space):
+        self.w___debug__ = space.newbool(1)
+        ExtModule.__init__(self, space)
+
     def _initcompiledbuiltins(self):
         """ add 'compiled' builtins to app-level dict and interp-level """
         self._eval_app_source(xrange_appsource)

Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/cpythonobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py	Tue Dec 16 18:12:48 2003
@@ -29,7 +29,10 @@
 
 
 def cpython_unwrap(space, w_obj):
-    return w_obj.cpyobj
+    cpyobj = w_obj.cpyobj
+    if hasattr(cpyobj, '__unwrap__'):
+        cpyobj = cpyobj.__unwrap__()
+    return cpyobj
 
 StdObjSpace.unwrap.register(cpython_unwrap, W_CPythonObject)
 
@@ -159,19 +162,23 @@
     if f:
         if _arity == 1:
             def cpython_f(space, w_1, f=f, pypymethod='pypy_'+_name):
-                x = space.unwrap(w_1)
-                if hasattr(x, pypymethod):
-                    return getattr(x, pypymethod)()
+                x1 = space.unwrap(w_1)
+                type_x1 = type(x1)
+                if hasattr(type_x1, pypymethod):
+                    return getattr(type_x1, pypymethod)(x1)
                 try:
-                    y = f(x)
+                    y = f(x1)
                 except:
                     wrap_exception(space)
                 return space.wrap(y)
         elif _arity == 2:
             def cpython_f(space, w_1, w_2, f=f, pypymethod='pypy_'+_name):
                 x1 = space.unwrap(w_1)
-                if hasattr(x1, pypymethod):
-                    return getattr(x1, pypymethod)(w_2)
+                type_x1 = type(x1)
+                if hasattr(type_x1, pypymethod):
+                    return getattr(type_x1, pypymethod)(x1, w_2)
+
+                # XXX do we really want to unwrap unknown objects here? 
                 x2 = space.unwrap(w_2)
                 try:
                     y = f(x1, x2)
@@ -181,8 +188,10 @@
         elif _arity == 3:
             def cpython_f(space, w_1, w_2, w_3, f=f, pypymethod='pypy_'+_name):
                 x1 = space.unwrap(w_1)
-                if hasattr(x1, pypymethod):
-                    return getattr(x1, pypymethod)(w_2, w_3)
+                type_x1 = type(x1)
+                if hasattr(type_x1, pypymethod):
+                    return getattr(type_x1, pypymethod)(x1, w_2, w_3)
+
                 x2 = space.unwrap(w_2)
                 x3 = space.unwrap(w_3)
                 try:

Modified: pypy/trunk/src/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/objspace.py	Tue Dec 16 18:12:48 2003
@@ -200,7 +200,7 @@
             wrappeditems = [self.wrap(item) for item in x]
             import listobject
             return listobject.W_ListObject(self, wrappeditems)
-        if hasattr(x, '__wrap__'):
+        if hasattr(type(x), '__wrap__'):
             return x.__wrap__(self)
         # print "wrapping %r (%s)" % (x, type(x))
         import cpythonobject
@@ -254,17 +254,17 @@
     call    = MultiMethod('call', 3, [], varargs=True, keywords=True)
 
     def is_(self, w_one, w_two):
-        # XXX this is a hopefully temporary speed hack:
+        # XXX a bit of hacking to gain more speed 
+        #
+        if w_one is w_two:
+            return self.newbool(1)
         from cpythonobject import W_CPythonObject
         if isinstance(w_one, W_CPythonObject):
             if isinstance(w_two, W_CPythonObject):
-                return self.newbool(w_one.cpyobj is w_two.cpyobj)
-            else:
-                return self.newbool(0)
-        else:
-            return self.newbool(w_one is w_two)
-
-
+                if w_one.cpyobj is w_two.cpyobj:
+                    return self.newbool(1)
+                return self.newbool(self.unwrap(w_one) is self.unwrap(w_two))
+        return self.newbool(0)
 
 # add all regular multimethods to StdObjSpace
 for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:

Modified: pypy/trunk/src/pypy/objspace/trivial.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/trivial.py	(original)
+++ pypy/trunk/src/pypy/objspace/trivial.py	Tue Dec 16 18:12:48 2003
@@ -143,12 +143,14 @@
 
     # general stuff
     def wrap(self, x):
-        if hasattr(x, '__wrap__'):
+        if hasattr(type(x), '__wrap__'):
             return x.__wrap__(self)
         else:
             return x
 
     def unwrap(self, w):
+        if hasattr(type(w), '__unwrap__'):
+            w = w.__unwrap__()
         return w
 
     def reraise(self):
@@ -178,7 +180,7 @@
     def _auto(name, sourcefn, classlocals):
         s = """
 def %(name)s(self, x, *args):
-    if hasattr(x, 'pypy_%(name)s'):
+    if hasattr(type(x), 'pypy_%(name)s'):
         return x.pypy_%(name)s(*args)
     try:
         value = %(sourcefn)s(x, *args)


More information about the Pypy-commit mailing list