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

pedronis at codespeak.net pedronis at codespeak.net
Fri Sep 23 18:20:06 CEST 2005


Author: pedronis
Date: Fri Sep 23 18:20:04 2005
New Revision: 17798

Modified:
   pypy/dist/pypy/interpreter/typedef.py
   pypy/dist/pypy/objspace/std/test/test_typeobject.py
Log:
avoid duplicated methods in the User* classes hierarchy



Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py	(original)
+++ pypy/dist/pypy/interpreter/typedef.py	Fri Sep 23 18:20:04 2005
@@ -63,6 +63,10 @@
 def _buildusercls(cls, hasdict, wants_slots):
     "NOT_RPYTHON: initialization-time only"
     typedef = cls.typedef
+
+    if hasdict and typedef.hasdict:
+        return get_unique_interplevel_subclass(cls, False, wants_slots)
+
     name = ['User']
     if not hasdict:
         name.append('NoDict')
@@ -72,27 +76,10 @@
 
     name = ''.join(name)
 
-    body = {}
-
-    no_extra_dict = typedef.hasdict or not hasdict
-
-    class User_InsertNameHere(object):
-
-        def getclass(self, space):
-            return self.w__class__
-
-        def setclass(self, space, w_subtype):
-            # only used by descr_set___class__
-            self.w__class__ = w_subtype
-
-        def __del__(self):
-            try:
-                self.space.userdel(self)
-            except OperationError, e:
-                e.write_unraisable(self.space, 'method __del__ of ', self)
-                e.clear(self.space)   # break up reference cycles
+    if wants_slots:
+        supercls = get_unique_interplevel_subclass(cls, hasdict, False)
 
-        if wants_slots:
+        class Proto(object):
             def user_setup_slots(self, nslots):
                 self.slots_w = [None] * nslots 
 
@@ -101,17 +88,10 @@
 
             def getslotvalue(self, index):
                 return self.slots_w[index]
-        else:
-            def user_setup_slots(self, nslots):
-                assert nslots == 0
-
-        if no_extra_dict:
-            def user_setup(self, space, w_subtype, nslots):
-                self.space = space
-                self.w__class__ = w_subtype
-                self.user_setup_slots(nslots)
+    elif hasdict:
+        supercls = get_unique_interplevel_subclass(cls, False, False)
 
-        else:
+        class Proto(object):
             def getdict(self):
                 return self.w__dict__
 
@@ -126,15 +106,38 @@
                 self.w__class__ = w_subtype
                 self.w__dict__ = space.newdict([])
                 self.user_setup_slots(nslots)
+    else:
+        supercls = cls
+        
+        class Proto(object):
+
+            def getclass(self, space):
+                return self.w__class__
+        
+            def setclass(self, space, w_subtype):
+                # only used by descr_set___class__
+                self.w__class__ = w_subtype
+
+            def __del__(self):
+                try:
+                    self.space.userdel(self)
+                except OperationError, e:
+                    e.write_unraisable(self.space, 'method __del__ of ', self)
+                    e.clear(self.space)   # break up reference cycles
+
+            def user_setup(self, space, w_subtype, nslots):
+                self.space = space
+                self.w__class__ = w_subtype
+                self.user_setup_slots(nslots)
+
+            def user_setup_slots(self, nslots):
+                assert nslots == 0
 
     body = dict([(key, value)
-                 for key, value in User_InsertNameHere.__dict__.items()
+                 for key, value in Proto.__dict__.items()
                  if not key.startswith('_') or key == '__del__'])
-    if not hasdict and not wants_slots:
-        subcls = type(name, (cls,), body)
-    else:
-        basesubcls = get_unique_interplevel_subclass(cls, False, False)
-        subcls = type(name, (basesubcls,), body)
+    
+    subcls = type(name, (supercls,), body)
 
     return subcls
 

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	Fri Sep 23 18:20:04 2005
@@ -440,3 +440,46 @@
         Abc.__name__ = 'Def'
         assert Abc.__name__ == 'Def'
         raises(TypeError, "Abc.__name__ = 42")
+
+    def test_class_variations(self):
+        class A(object):
+            pass
+        assert '__dict__' in A.__dict__
+        a = A()
+        a.x = 3
+        assert a.x == 3
+
+        class A(object):
+            __slots__ = ()
+        assert '__dict__' not in A.__dict__
+        a = A()
+        raises(AttributeError, setattr, a, 'x', 3)
+
+        class B(A):
+            pass
+        assert '__dict__' in B.__dict__
+        b = B()
+        b.x = 3
+        assert b.x == 3
+
+        import sys
+        class A(type(sys)):
+            pass
+        assert '__dict__' not in A.__dict__
+        a = A("a")
+        a.x = 3
+        assert a.x == 3
+
+        class A(type(sys)):
+            __slots__ = ()
+        assert '__dict__' not in A.__dict__
+        a = A("a")
+        a.x = 3
+        assert a.x == 3
+
+        class B(A):
+            pass
+        assert '__dict__' not in B.__dict__
+        b = B("b")
+        b.x = 3
+        assert b.x == 3



More information about the Pypy-commit mailing list