[pypy-svn] r4871 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace

arigo at codespeak.net arigo at codespeak.net
Thu Jun 3 16:29:50 CEST 2004


Author: arigo
Date: Thu Jun  3 16:29:49 2004
New Revision: 4871

Modified:
   pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py
   pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py
   pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py
   pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py
   pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py
Log:
Added the CPyWrappers for the trivial object space.


Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py	Thu Jun  3 16:29:49 2004
@@ -9,6 +9,8 @@
 class Wrappable(object):
     """A subclass of Wrappable is an internal, interpreter-level class
     that can nevertheless be exposed at application-level by space.wrap()."""
+    def __spacebind__(self, space):
+        return self
 
 class NoValue(Exception):
     """Raised to signal absence of value, e.g. in the iterator accessing

Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py	Thu Jun  3 16:29:49 2004
@@ -113,7 +113,7 @@
     return function(*argarray, **keywords)
 
 
-class Gateway(object):
+class Gateway(Wrappable):
     """General-purpose utility for the interpreter-level to create callables
     that transparently invoke code objects (and thus possibly interpreted
     app-level code)."""
@@ -132,10 +132,10 @@
         #   staticglobals 
         #   staticdefs 
 
-    def __wrap__(self, space):
+    def __spacebind__(self, space):
         # to wrap a Gateway, we first make a real Function object out of it
         # and the result is a wrapped version of this Function.
-        return space.wrap(self.get_function(space))
+        return self.get_function(space)
 
     def get_function(self, space):
         try:

Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py
==============================================================================
--- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py	(original)
+++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py	Thu Jun  3 16:29:49 2004
@@ -11,7 +11,10 @@
         self.rawdict = rawdict
 
     def mro(self, space):
-        return [self, space.object_typedef]
+        if self is space.object_typedef:
+            return [self]
+        else:
+            return [self, space.object_typedef]
 
 class GetSetProperty(Wrappable):
     def __init__(self, fget, fset=None, fdel=None, doc=None):

Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py	(original)
+++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py	Thu Jun  3 16:29:49 2004
@@ -62,24 +62,26 @@
         return space.lookup(w_obj, '__set__') is not None
 
     def get_and_call(space, w_descr, w_obj, w_args, w_kwargs):
-        if isinstance(w_descr, Function):  # wrapped Function actually
+        descr = space.unwrap_builtin(w_descr)
+        if isinstance(descr, Function):
             # special-case Functions to avoid infinite recursion
             args_w = space.unpacktuple(w_args)
             args_w = [w_obj] + args_w
             w_args = space.newtuple(args_w)
-            return w_descr.call(w_args, w_kwargs)
+            return descr.call(w_args, w_kwargs)
         else:
             w_impl = space.get(w_descr, w_obj, space.type(w_obj))
             return space.call(w_impl, w_args, w_kwargs)
 
     def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w):
-        if isinstance(w_descr, Function):  # wrapped Function actually
+        descr = space.unwrap_builtin(w_descr)
+        if isinstance(descr, Function):
             # special-case Functions to avoid infinite recursion
             args_w = [w_obj] + list(args_w)
             w_args = space.newtuple(args_w)
             w_kwargs = space.newdict([(space.wrap(key), w_item)
                                       for key, w_item in kwargs_w])
-            return w_descr.call(w_args, w_kwargs)
+            return descr.call(w_args, w_kwargs)
         else:
             w_impl = space.get(w_descr, w_obj, space.type(w_obj))
             return space.call_function(w_impl, *args_w, **kwargs_w)

Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py
==============================================================================
--- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py	(original)
+++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py	Thu Jun  3 16:29:49 2004
@@ -10,6 +10,9 @@
 import operator, types, new, sys
 import __builtin__ as cpy_builtin
 
+class CPyWrapper(object):
+    pass
+
 class TrivialObjSpace(ObjSpace, DescrOperation):
 
     def clone_exception_hierarchy(self):
@@ -110,15 +113,56 @@
 
     # general stuff
     def wrap(self, x):
-        if hasattr(type(x), '__wrap__'):
-            return x.__wrap__(self)
+        if isinstance(x, Wrappable):
+            x = x.__spacebind__(self)
+            wrapperclass = self.hackwrapperclass(x.typedef)
+            instance = CPyWrapper.__new__(wrapperclass)
+            instancedict = CPyWrapper.__dict__['__dict__'].__get__(instance)
+            instancedict['__internalpypyobject__'] = x
+            return instance
         else:
+            # optional check for double-wrapping
+            if isinstance(x, CPyWrapper):
+                raise TypeError, "wrapping an already-wrapped object"
             return x
 
     def unwrap(self, w):
-        #if hasattr(type(w), '__unwrap__'):
-        #    w = w.__unwrap__()
-        return w
+        if isinstance(w, CPyWrapper):
+            instancedict = CPyWrapper.__dict__['__dict__'].__get__(w)
+            return instancedict['__internalpypyobject__']
+        else:
+            return w
+
+    def hackwrapperclass(self, typedef):
+        try:
+            return typedef.trivialwrapperclass
+        except AttributeError:
+            # make the base first (assuming single inheritance)
+            mro = typedef.mro(self)
+            if len(mro) > 1:
+                bases = (self.hackwrapperclass(mro[1]),)
+            else:
+                bases = (CPyWrapper,)
+            # make the class dict with descriptors redirecting to the ones
+            # in rawdict
+            descrdict = {}
+            for descrname, descr in typedef.rawdict.items():
+                def fget(w_obj, w_descr=descr, space=self):
+                    return space.get(w_descr, w_obj, space.type(w_obj))
+                def fset(w_obj, w_value, w_descr=descr, space=self):
+                    return space.set(w_descr, w_obj, w_value)
+                def fdel(w_obj, w_descr=descr, space=self):
+                    return space.set(w_descr, w_obj)
+                descrdict[descrname] = property(fget, fset, fdel)
+            cls = type(typedef.name, bases, descrdict)
+            typedef.trivialwrapperclass = cls
+            return cls
+
+    def unwrap_builtin(self, w_obj):
+        if isinstance(w_obj, CPyWrapper):
+            return self.unwrap(w_obj)
+        else:
+            return None
 
     def is_(self, w_obj1, w_obj2):
         return self.unwrap(w_obj1) is self.unwrap(w_obj2)
@@ -356,8 +400,10 @@
     #    return round(*args)
 
     def lookup(space, w_obj, name):
-        if isinstance(w_obj, Wrappable):
-            for basedef in w_obj.typedef.mro(space):
+        assert not isinstance(w_obj, Wrappable)
+        if isinstance(w_obj, CPyWrapper):
+            obj = space.unwrap(w_obj)
+            for basedef in obj.typedef.mro(space):
                 if name in basedef.rawdict:
                     return space.wrap(basedef.rawdict[name])
             return None 
@@ -372,7 +418,7 @@
             return None
 
     def get_and_call(self, w_descr, w_obj, w_args, w_kwargs):
-        if isinstance(w_descr, Wrappable):
+        if isinstance(w_descr, CPyWrapper):
             return DescrOperation.get_and_call(self, w_descr, w_obj,
                                                w_args, w_kwargs)
         else:
@@ -383,7 +429,7 @@
                 self.reraise()
 
     def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w):
-        if isinstance(w_descr, Wrappable):
+        if isinstance(w_descr, CPyWrapper):
             return DescrOperation.get_and_call_function(self, w_descr, w_obj,
                                                         *args_w, **kwargs_w)
         else:



More information about the Pypy-commit mailing list