[pypy-svn] r11043 - in pypy/dist/pypy: interpreter objspace/std objspace/std/test

pedronis at codespeak.net pedronis at codespeak.net
Sat Apr 23 00:04:02 CEST 2005


Author: pedronis
Date: Sat Apr 23 00:04:02 2005
New Revision: 11043

Modified:
   pypy/dist/pypy/interpreter/typedef.py
   pypy/dist/pypy/objspace/std/test/test_typeobject.py
   pypy/dist/pypy/objspace/std/typeobject.py
Log:
type checks for slots descriptors



Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py	(original)
+++ pypy/dist/pypy/interpreter/typedef.py	Sat Apr 23 00:04:02 2005
@@ -213,15 +213,23 @@
 
 class Member(Wrappable):
     """For slots."""
-    def __init__(self, index, name):  # XXX ,cls later
+    def __init__(self, index, name, w_cls):
         self.index = index
         self.name = name
+        self.w_cls = w_cls
 
-    def descr_member_get(space, member, w_obj, w_cls=None):
+    def typecheck(self, space, w_obj):
+        if not space.is_true(space.isinstance(w_obj, self.w_cls)):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("descriptor '%s' for '%s' objects doesn't apply to '%s' object" %
+                                            (self.name, self.w_cls.name, space.type(w_obj).name)))
+
+    def descr_member_get(space, member, w_obj, w_w_cls=None):
         if space.is_w(w_obj, space.w_None):
             return space.wrap(member)
         else:
             self = member
+            self.typecheck(space, w_obj)
             w_result = w_obj.slots_w[self.index]
             if w_result is None:
                 raise OperationError(space.w_AttributeError,
@@ -230,11 +238,13 @@
 
     def descr_member_set(space, member, w_obj, w_value):
         self = member
-        w_obj.slots_w[self.index] = w_value # xxx typecheck
+        self.typecheck(space, w_obj)
+        w_obj.slots_w[self.index] = w_value
 
     def descr_member_del(space, member, w_obj):
         self = member
-        w_obj.slots_w[self.index] = None # xxx typecheck
+        self.typecheck(space, w_obj)
+        w_obj.slots_w[self.index] = None
 
 Member.typedef = TypeDef(
     "Member",

Modified: pypy/dist/pypy/objspace/std/test/test_typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_typeobject.py	Sat Apr 23 00:04:02 2005
@@ -237,6 +237,30 @@
         raises(TypeError,type.__dict__['__name__'].__get__,1)
         raises(TypeError,type.__dict__['__mro__'].__get__,1)
 
-
+    def test_slots_simple(self):
+        class A(object):
+            __slots__ = ('x',)
+        a = A()
+        raises(AttributeError, getattr, a, 'x')
+        a.x = 1
+        assert a.x == 1
+        assert A.__dict__['x'].__get__(a) == 1
+        del a.x
+        raises(AttributeError, getattr, a, 'x')
+        class B(A):
+            pass
+        b = B()
+        raises(AttributeError, getattr, b, 'x')
+        b.x = 1
+        assert b.x == 1
+        assert A.__dict__['x'].__get__(b) == 1
+        del b.x
+        raises(AttributeError, getattr, b, 'x')
+        class Z(object):
+            pass
+        z = Z()
+        raises(TypeError, A.__dict__['x'].__get__, z)
+        raises(TypeError, A.__dict__['x'].__set__, z, 1)
+        raises(TypeError, A.__dict__['x'].__delete__, z)
         
         

Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/typeobject.py	Sat Apr 23 00:04:02 2005
@@ -110,7 +110,7 @@
                         wantdict = True
                     else:
                         # create member
-                        w_self.dict_w[slot_name] = space.wrap(Member(nslots, slot_name))
+                        w_self.dict_w[slot_name] = space.wrap(Member(nslots, slot_name, w_self))
                         nslots += 1
 
             w_self.nslots = nslots



More information about the Pypy-commit mailing list