[pypy-svn] r36405 - in pypy/dist/pypy: config objspace/std objspace/std/test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Jan 10 15:23:57 CET 2007


Author: cfbolz
Date: Wed Jan 10 15:23:53 2007
New Revision: 36405

Added:
   pypy/dist/pypy/objspace/std/test/test_versionedtype.py
Modified:
   pypy/dist/pypy/config/pypyoption.py
   pypy/dist/pypy/objspace/std/typeobject.py
   pypy/dist/pypy/objspace/std/typetype.py
Log:
(pedronis, cfbolz): adding a version tag to types to check whether they
changed. used only when a new config option withversiontypes.


Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Wed Jan 10 15:23:53 2007
@@ -140,6 +140,11 @@
                    "list is mutaged",
                    default=False),
 
+        BoolOption("withtypeversion",
+                   "version type objects when changing them",
+                   cmdline=None,
+                   default=False),
+
         BoolOption("optimized_int_add",
                    "special case the addition of two integers in BINARY_ADD",
                    default=False),

Added: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py	Wed Jan 10 15:23:53 2007
@@ -0,0 +1,56 @@
+from pypy.objspace.std.test import test_typeobject
+from pypy.conftest import gettestobjspace
+
+class TestVersionedType(test_typeobject.TestTypeObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True})
+
+    def test_tag_changes(self):
+        space = self.space
+        w_types = space.appexec([], """():
+            class A(object):
+                def f(self): pass
+            class B(A):
+                pass
+            class metatype(type):
+                pass
+            class C(object):
+                __metaclass__ = metatype
+            return A, B, C
+        """)
+        w_A, w_B, w_C = space.unpackiterable(w_types)
+        atag = w_A.version_tag
+        btag = w_B.version_tag
+        assert atag is not None
+        assert btag is not None
+        assert w_C.version_tag is None
+        assert atag is not btag
+        w_types = space.appexec([w_A, w_B], """(A, B):
+            B.g = lambda self: None
+        """)
+        assert w_B.version_tag is not btag
+        assert w_A.version_tag is atag
+        btag = w_B.version_tag
+        w_types = space.appexec([w_A, w_B], """(A, B):
+            A.f = lambda self: None
+        """)
+        assert w_B.version_tag is not btag
+        assert w_A.version_tag is not atag
+        atag = w_A.version_tag
+        btag = w_B.version_tag
+        assert atag is not btag
+        w_types = space.appexec([w_A, w_B], """(A, B):
+            del A.f
+        """)
+        assert w_B.version_tag is not btag
+        assert w_A.version_tag is not atag
+        atag = w_A.version_tag
+        btag = w_B.version_tag
+        assert atag is not btag
+
+
+class AppTestVersionedType(test_typeobject.AppTestTypeObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True})
+
+

Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/typeobject.py	Wed Jan 10 15:23:53 2007
@@ -38,6 +38,9 @@
 
     return "_%s%s" % (klass, name)
 
+class VersionTag(object):
+    pass
+
 class W_TypeObject(W_Object):
     from pypy.objspace.std.typetype import type_typedef as typedef
 
@@ -200,6 +203,8 @@
                 w_self.weakrefable = True
             w_type = space.type(w_self)
             if not space.is_w(w_type, space.w_type):
+                if space.config.objspace.std.withtypeversion:
+                    w_self.version_tag = None
                 w_self.mro_w = []
                 mro_func = w_type.lookup('mro')
                 mro_func_args = Arguments(space, [w_self])
@@ -207,6 +212,17 @@
                 w_self.mro_w = space.unpackiterable(w_mro)
                 return
         w_self.mro_w = w_self.compute_mro()
+        if space.config.objspace.std.withtypeversion:
+            w_self.version_tag = VersionTag()
+
+    def mutated(w_self):
+        space = w_self.space
+        assert space.config.objspace.std.withtypeversion
+        if w_self.version_tag is not None:
+            w_self.version_tag = VersionTag()
+            subclasses_w = w_self.get_subclasses()
+            for w_subclass in subclasses_w:
+                w_subclass.mutated()
 
     def ready(w_self):
         for w_base in w_self.bases_w:
@@ -352,6 +368,16 @@
                 del w_self.weak_subclasses_w[i]
                 return
 
+    def get_subclasses(w_self):
+        space = w_self.space
+        subclasses_w = []
+        for w_ref in w_self.weak_subclasses_w:
+            w_ob = space.call_function(w_ref)
+            if not space.is_w(w_ob, space.w_None):
+                subclasses_w.append(w_ob)
+        return subclasses_w
+
+
     # for now, weakref support for W_TypeObject is hard to get automatically
     _lifeline_ = None
     def getweakref(self):
@@ -418,6 +444,8 @@
     # Note. This is exactly the same thing as descroperation.descr__setattr__,
     # but it is needed at bootstrap to avoid a call to w_type.getdict() which
     # would un-lazify the whole type.
+    if space.config.objspace.std.withtypeversion:
+        w_type.mutated()
     name = space.str_w(w_name)
     w_descr = space.lookup(w_type, name)
     if w_descr is not None:
@@ -427,6 +455,8 @@
     w_type.dict_w[name] = w_value
 
 def delattr__Type_ANY(space, w_type, w_name):
+    if space.config.objspace.std.withtypeversion:
+        w_type.mutated()
     if w_type.lazyloaders:
         w_type._freeze_()    # force un-lazification
     name = space.str_w(w_name)
@@ -441,6 +471,7 @@
     except KeyError:
         raise OperationError(space.w_AttributeError, w_name)
 
+
 # ____________________________________________________________
 
 

Modified: pypy/dist/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typetype.py	(original)
+++ pypy/dist/pypy/objspace/std/typetype.py	Wed Jan 10 15:23:53 2007
@@ -248,12 +248,7 @@
 def descr___subclasses__(space, w_type):
     """Return the list of immediate subclasses."""
     w_type = _check(space, w_type)
-    subclasses_w = []
-    for w_ref in w_type.weak_subclasses_w:
-        w_ob = space.call_function(w_ref)
-        if not space.is_w(w_ob, space.w_None):
-            subclasses_w.append(w_ob)
-    return space.newlist(subclasses_w)
+    return space.newlist(w_type.get_subclasses())
 
 # ____________________________________________________________
 



More information about the Pypy-commit mailing list