[pypy-svn] r49671 - in pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Dec 12 13:06:09 CET 2007


Author: cfbolz
Date: Wed Dec 12 13:06:09 2007
New Revision: 49671

Modified:
   pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py
   pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py
Log:
implement get/set/delattr


Modified: pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py
==============================================================================
--- pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py	(original)
+++ pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py	Wed Dec 12 13:06:09 2007
@@ -200,26 +200,18 @@
         return self.w_dict
 
     def setdict(self, space, w_dict):
-        if not space.is_true(space.isinstance(w_dict, space.w_dict)):
+        if (w_dict is None or
+            not space.is_true(space.isinstance(w_dict, space.w_dict))):
             raise OperationError(
                 space.w_TypeError,
                 space.wrap("__dict__ must be a dictionary object"))
         self.w_dict = w_dict
 
-    def fget_dict(space, self):
-        return self.w_dict
-
-    def fset_dict(space, self, w_dict):
-        self.setdict(space, w_dict)
-
-    def fget_class(space, self):
-        return self.w_class
-
-    def fset_class(space, self, w_class):
-        if not isinstance(w_class, W_ClassObject):
+    def setclass(self, space, w_class):
+        if w_class is None or not isinstance(w_class, W_ClassObject):
             raise OperationError(
                 space.w_TypeError,
-                space.wrap("instance() first arg must be class"))
+                space.wrap("__class__ must be set to a class"))
         self.w_class = w_class
 
     def descr_new(space, w_type, w_class, w_dict=None):
@@ -268,7 +260,43 @@
 
     def descr_getattribute(self, space, w_attr):
         #import pdb; pdb.set_trace()
-        return self.getattr(space, w_attr)
+        try:
+            return self.getattr(space, w_attr)
+        except OperationError, e:
+            if not e.match(space, space.w_AttributeError):
+                raise
+            w_meth = self.getattr(space, space.wrap('__getattr__'), False)
+            if w_meth is not None:
+                return space.call_function(w_meth, w_attr)
+            raise
+
+    def descr_setattr(self, space, w_name, w_value):
+        name = space.str_w(w_name)
+        if name == '__dict__':
+            self.setdict(space, w_value)
+        elif name == '__class__':
+            self.setclass(space, w_value)
+        else:
+            w_meth = self.getattr(space, space.wrap('__setattr__'), False)
+            if w_meth is not None:
+                space.call_function(w_meth, w_name, w_value)
+            else:
+                self.setdictvalue(space, w_name, w_value)
+
+    def descr_delattr(self, space, w_name):
+        name = space.str_w(w_name)
+        if name == '__dict__':
+            # use setdict to raise the error
+            self.setdict(space, None)
+        elif name == '__class__':
+            # use setclass to raise the error
+            self.setclass(space, None)
+        else:
+            w_meth = self.getattr(space, space.wrap('__delattr__'), False)
+            if w_meth is not None:
+                space.call_function(w_meth, w_name)
+            else:
+                self.deldictvalue(space, w_name)
 
     def descr_repr(self, space):
         w_meth = self.getattr(space, space.wrap('__repr__'), False)
@@ -345,12 +373,12 @@
 
 W_InstanceObject.typedef = TypeDef("instance",
     __new__ = interp2app(W_InstanceObject.descr_new),
-    __dict__ = GetSetProperty(W_InstanceObject.fget_dict,
-                              W_InstanceObject.fset_dict),
-    __class__ = GetSetProperty(W_InstanceObject.fget_class,
-                               W_InstanceObject.fset_class),
     __getattribute__ = interp2app(W_InstanceObject.descr_getattribute,
                                   unwrap_spec=['self', ObjSpace, W_Root]),
+    __setattr__ = interp2app(W_InstanceObject.descr_setattr,
+                             unwrap_spec=['self', ObjSpace, W_Root, W_Root]),
+    __delattr__ = interp2app(W_InstanceObject.descr_delattr,
+                             unwrap_spec=['self', ObjSpace, W_Root]),
     __repr__ = interp2app(W_InstanceObject.descr_repr,
                           unwrap_spec=['self', ObjSpace]),
     __str__ = interp2app(W_InstanceObject.descr_str,

Modified: pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py
==============================================================================
--- pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py	(original)
+++ pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py	Wed Dec 12 13:06:09 2007
@@ -326,3 +326,36 @@
                 return self.list[i]
         for i, element in enumerate(A()):
             assert i + 1 == element
+
+    def test_getsetdelattr(self):
+        class A:
+            __metaclass__ = nclassobj
+            a = 1
+            def __getattr__(self, attr):
+                return attr.upper()
+        a = A()
+        assert a.a == 1
+        a.__dict__['b'] = 4
+        assert a.b == 4
+        assert a.c == "C"
+        class A:
+            __metaclass__ = nclassobj
+            a = 1
+            def __setattr__(self, attr, value):
+                self.__dict__[attr.lower()] = value
+        a = A()
+        assert a.a == 1
+        a.A = 2
+        assert a.a == 2
+        class A:
+            __metaclass__ = nclassobj
+            a = 1
+            def __delattr__(self, attr):
+                del self.__dict__[attr.lower()]
+        a = A()
+        assert a.a == 1
+        a.a = 2
+        assert a.a == 2
+        del a.A
+        assert a.a == 1
+



More information about the Pypy-commit mailing list