[pypy-svn] rev 1042 - pypy/trunk/src/pypy/objspace/ann

gvanrossum at codespeak.net gvanrossum at codespeak.net
Tue Jun 24 13:58:25 CEST 2003


Author: gvanrossum
Date: Tue Jun 24 13:58:25 2003
New Revision: 1042

Modified:
   pypy/trunk/src/pypy/objspace/ann/cloningcontext.py
   pypy/trunk/src/pypy/objspace/ann/objspace.py
   pypy/trunk/src/pypy/objspace/ann/wrapper.py
Log:
Mure functionality in annotation space.

M      cloningcontext.py
        support for w_globals being a W_KnownKeysContainer
M      objspace.py
        the base clsas make_builtins() now works
        move most of unwrap implementation into wrapper objects
        support for modules and builtin functions
        support calling builtin functions
        support getting/setting module attributes
M      wrapper.py
        __repr__ places a limit on argsrepr() return value
        add unwrap() as a method of W_Object
        make W_KnownKeysContainer unwrappable if all values are
        add W_Module type, with getattr and setattr support
        add W_BuiltinFunction type (incomplete?)


Modified: pypy/trunk/src/pypy/objspace/ann/cloningcontext.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/cloningcontext.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/cloningcontext.py	Tue Jun 24 13:58:25 2003
@@ -1,7 +1,8 @@
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.pyframe import ControlFlowException, ExitFrame
 from pypy.objspace.ann.wrapper \
-     import union, compatible_frames, unify_frames, W_Anything, W_Constant
+     import union, compatible_frames, unify_frames, W_Anything, W_Constant, \
+            W_KnownKeysContainer
 
 class FunctionInfo(object):
 
@@ -58,8 +59,7 @@
         # {(bytecode, w_globals): FunctionInfo(), ...}
 
     def getfunctioninfo(self, frame, new=False):
-        assert isinstance(frame.w_globals, W_Constant)
-        key = (frame.bytecode, id(frame.w_globals.value))
+        key = self.makekey(frame)
         info = self.functioninfos.get(key)
         if info is None:
             if not new:
@@ -67,6 +67,12 @@
             self.functioninfos[key] = info = FunctionInfo()
         return info
 
+    def makekey(self, frame):
+        if isinstance(frame.w_globals, W_Constant):
+            return (frame.bytecode, id(frame.w_globals.value))
+        if isinstance(frame.w_globals, W_KnownKeysContainer):
+            return (frame.bytecode, id(frame.w_globals.args_w))
+
     def bytecode_trace(self, frame):
         if frame.restarting is not None:
             w_obj, flag = frame.restarting

Modified: pypy/trunk/src/pypy/objspace/ann/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/objspace.py	Tue Jun 24 13:58:25 2003
@@ -5,6 +5,7 @@
 from pypy.interpreter.baseobjspace \
      import ObjSpace, OperationError, NoValue, PyPyError
 from pypy.interpreter.pycode import PyByteCode
+from pypy.interpreter.extmodule import PyBuiltinCode
 from pypy.objspace.ann.cloningcontext import CloningExecutionContext
 from pypy.objspace.ann.cloningcontext import IndeterminateCondition
 
@@ -33,13 +34,9 @@
         for n, c in __builtin__.__dict__.iteritems():
             if isinstance(c, types.TypeType) or isinstance(c, types.ClassType):
                 setattr(self, 'w_'+n, self.wrap(c))
-        self.w_builtins = self.wrap(__builtin__)
         self.make_builtins()
         self.make_sys()
 
-    def make_builtins(self):
-        self.builtin = pypy.module.builtin.Builtin(self)
-
     # Service methods whose interface is in the abstract base class
 
     def wrapboot(self, obj):
@@ -58,10 +55,8 @@
         return W_Constant(obj)
 
     def unwrap(self, w_obj):
-        if isinstance(w_obj, W_Constant):
-            return w_obj.value
-        elif isinstance(w_obj, W_Object):
-            raise UnwrapException("Cannot unwrap: " +repr(w_obj))
+        if isinstance(w_obj, W_Object):
+            return w_obj.unwrap()
         else:
             raise TypeError("not wrapped: " + repr(w_obj))
 
@@ -130,9 +125,11 @@
         return W_Anything()
 
     def newmodule(self, w_name):
-        return W_Anything()
+        return W_Module(w_name, self.w_None)
 
-    def newfunction(self, *stuff):
+    def newfunction(self, code, w_globals, w_defaults, w_closure=None):
+        if isinstance(code, PyBuiltinCode):
+            return W_BuiltinFunction(code, w_defaults)
         return W_Anything()
 
     def newlist(self, list_w):
@@ -240,27 +237,42 @@
         raise IndeterminateCondition(w_iterator)
 
     def call(self, w_func, w_args, w_kwds):
-        func = self.unwrap(w_func) # XXX What if this fails?
-        try:
-            code = func.func_code
-        except AttributeError:
-            return W_Anything()
-        bytecode = self.bytecodecache.get(code)
-        if bytecode is None:
-            bytecode = PyByteCode()
-            bytecode._from_code(code)
-            self.bytecodecache[code] = bytecode
+        if isinstance(w_func, W_BuiltinFunction):
+            bytecode = w_func.code
+            w_defaults = w_func.w_defaults
+            w_globals = self.w_None
+        else:
+            try:
+                func = self.unwrap(w_func)
+            except UnwrapException:
+                return W_Anything()
+            try:
+                code = func.func_code
+            except AttributeError:
+                return W_Anything()
+            bytecode = self.bytecodecache.get(code)
+            if bytecode is None:
+                bytecode = PyByteCode()
+                bytecode._from_code(code)
+                self.bytecodecache[code] = bytecode
+            w_defaults = self.wrap(func.func_defaults)
+            w_globals = self.wrap(func.func_globals)
         w_locals = bytecode.build_arguments(self,
                                             w_args,
                                             w_kwds,
-                                            self.wrap(func.func_defaults),
+                                            w_defaults,
                                             self.wrap(()))
-        w_result = bytecode.eval_code(self,
-                                      self.wrap(func.func_globals),
-                                      w_locals)
+        w_result = bytecode.eval_code(self, w_globals, w_locals)
         return w_result
 
     def getattr(self, w_obj, w_name):
+        if isinstance(w_obj, W_Module) and isinstance(w_name, W_Constant):
+            name = self.unwrap(w_name)
+            try:
+                return w_obj.getattr(name)
+            except KeyError:
+                raise OperationError(self.wrap(AttributeError),
+                                     self.wrap(AttributeError(name)))
         try:
             obj = self.unwrap(w_obj)
             name = self.unwrap(w_name)
@@ -273,8 +285,10 @@
                 return self.reraise()
 
     def setattr(self, w_obj, w_name, w_value):
-        # XXX What about the side effect?
-        return self.w_None
+        if isinstance(w_obj, W_Module) and isinstance(w_name, W_Constant):
+            name = self.unwrap(w_name)
+            w_obj.setattr(name, w_value)
+        # Space setattr shouldn't return anything, so no w_None here
 
     def len(self, w_obj):
         if isinstance(w_obj, W_KnownKeysContainer):

Modified: pypy/trunk/src/pypy/objspace/ann/wrapper.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/wrapper.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/wrapper.py	Tue Jun 24 13:58:25 2003
@@ -21,11 +21,19 @@
         pass
 
     def __repr__(self):
-        return "%s(%s)" % (self.__class__.__name__, self.argsrepr())
+        s = self.argsrepr()
+        if len(s) > 100:
+            s = s[:25] + "..." + s[-25:]
+        return "%s(%s)" % (self.__class__.__name__, s)
 
     def argsrepr(self):
         return ""
 
+    def unwrap(self):
+        # XXX Somehow importing this at module level doesn't work
+        from pypy.objspace.ann.objspace import UnwrapException
+        raise UnwrapException(self)
+
     def __eq__(self, other):
         return type(other) is type(self)
 
@@ -51,7 +59,10 @@
         self.value = value
 
     def argsrepr(self):
-        return repr(self.value)[:50]
+        return repr(self.value)
+
+    def unwrap(self):
+        return self.value
 
     def __eq__(self, other):
         return type(other) is type(self) and self.value == other.value
@@ -60,9 +71,9 @@
         return self
 
 class W_KnownKeysContainer(W_Object):
-    """A dict with constant set of keys or a tuple with known length.
+    """A dict with a known set of keys or a list with known length.
 
-    XXX This may be mutable!  Is that a good idea?
+    XXX This is mutable!  Is that a good idea?
     """
 
     def __init__(self, args_w):
@@ -71,6 +82,18 @@
     def argsrepr(self):
         return repr(self.args_w)
 
+    def unwrap(self):
+        if hasattr(self.args_w, "keys"):
+            d = {}
+            for k, w_v in self.args_w.iteritems():
+                d[k] = w_v.unwrap()
+            return d
+        assert isinstance(self.args_w, list), self.args_w
+        l = []
+        for w_obj in self.args_w:
+            l.append(w_obj.unwrap())
+        return l
+
     def __eq__(self, other):
         return type(other) is type(self) and self.args_w == other.args_w
 
@@ -87,6 +110,39 @@
         # XXX Recurse down the values?
         return W_KnownKeysContainer(args_w)
 
+class W_Module(W_Object):
+    """A module object.  It supports getattr and setattr (yikes!)."""
+
+    def __init__(self, w_name, w_doc):
+        # The wrapped module name and wrapped docstring must be known
+        self.w_name = w_name
+        self.w_doc = w_doc
+        self.contents = W_KnownKeysContainer({"__name__": w_name,
+                                              "__doc__": w_doc})
+
+    def argsrepr(self):
+        return repr(self.w_name) + ", " + repr(self.w_doc)
+
+    def getattr(self, name):
+        # Returned a wrapped object or raise an unwrapped KeyError exception
+        if name == "__dict__":
+            return self.contents
+        return self.contents[name]
+
+    def setattr(self, name, w_obj):
+        self.contents.args_w[name] = w_obj
+
+class W_BuiltinFunction(W_Object):
+    """A function that executes in interpreter space."""
+
+    def __init__(self, code, w_defaults):
+        self.code = code
+        self.w_defaults = w_defaults
+
+    def argsrepr(self):
+        return repr(self.code) + ", " + repr(self.w_defaults)
+
+
 def unify_frames(f1, f2):
     """Given two compatible frames, make them the same.
 


More information about the Pypy-commit mailing list