[pypy-svn] r28518 - in pypy/dist/pypy: interpreter objspace/std tool

mwh at codespeak.net mwh at codespeak.net
Thu Jun 8 15:34:15 CEST 2006


Author: mwh
Date: Thu Jun  8 15:34:13 2006
New Revision: 28518

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/objspace/std/objspace.py
   pypy/dist/pypy/objspace/std/stdtypedef.py
   pypy/dist/pypy/objspace/std/typeobject.py
   pypy/dist/pypy/objspace/std/typetype.py
   pypy/dist/pypy/tool/cache.py
Log:
(mwh, pedronis)
issue204 in-progress
implement __subclasses__().  required a small extension of tool/cache, and a
way of building a very simple weakref that has a chance of working "early".
W_TypeObjects now need to have their .ready() called "at some point" -- apart
from during space setup, just after __init__ will do.


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Thu Jun  8 15:34:13 2006
@@ -111,6 +111,15 @@
             return self.build(key)
         finally:
             self.space.leave_cache_building_mode(val)
+    def _ready(self, result):
+        val = self.space.enter_cache_building_mode()
+        try:
+            return self.ready(result)
+        finally:
+            self.space.leave_cache_building_mode(val)
+    def ready(self, result):
+        pass
+        
 
 class ObjSpaceOptions: 
     def _freeze_(self): 

Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Thu Jun  8 15:34:13 2006
@@ -211,6 +211,7 @@
             if not bases:
                 bases = [space.w_object]
             res = W_TypeObject(space, name, bases, dic)
+            res.ready()
             return res
         try:
             # note that we hide the real call method by an instance variable!

Modified: pypy/dist/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stdtypedef.py	(original)
+++ pypy/dist/pypy/objspace/std/stdtypedef.py	Thu Jun  8 15:34:13 2006
@@ -91,6 +91,9 @@
         w_type.lazyloaders = lazyloaders
         return w_type
 
+    def ready(self, w_type):
+        w_type.ready()
+
 def hack_out_multimethods(ns):
     "NOT_RPYTHON: initialization-time only."
     result = []

Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/typeobject.py	Thu Jun  8 15:34:13 2006
@@ -53,6 +53,7 @@
         w_self.nslots = 0
         w_self.needsdel = False
         w_self.w_bestbase = None
+        w_self.weak_subclasses_w = []
 
         # make sure there is a __doc__ in dict_w
         if '__doc__' not in dict_w:
@@ -207,6 +208,12 @@
                 return
         w_self.mro_w = w_self.compute_mro()
 
+    def ready(w_self):
+        for w_base in w_self.bases_w:
+            if not isinstance(w_base, W_TypeObject):
+                continue
+            w_base.add_subclass(w_self)
+
     # compute the most parent class with the same layout as us
     def get_layout(w_self):
         w_bestbase = w_self.w_bestbase
@@ -315,6 +322,20 @@
         else:
             return space.wrap('__builtin__')
 
+    def add_subclass(w_self, w_subclass):
+        space = w_self.space
+        from pypy.module._weakref.interp__weakref import basic_weakref
+        w_newref = basic_weakref(space, w_subclass)
+        
+        for i in range(len(w_self.weak_subclasses_w)):
+            w_ref = w_self.weak_subclasses_w[i]
+            ob = space.call_function(w_ref)
+            if space.is_w(ob, space.w_None):
+                w_self.weak_subclasses_w[i] = w_newref
+                return
+        else:
+            w_self.weak_subclasses_w.append(w_newref)
+
     # for now, weakref support for W_TypeObject is hard to get automatically
     _lifeline_ = None
     def getweakref(self):

Modified: pypy/dist/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typetype.py	(original)
+++ pypy/dist/pypy/objspace/std/typetype.py	Thu Jun  8 15:34:13 2006
@@ -44,6 +44,7 @@
     w_type = space.allocate_instance(W_TypeObject, w_typetype)
     W_TypeObject.__init__(w_type, space, name, bases_w or [space.w_object],
                           dict_w)
+    w_type.ready()
     return w_type
 
 def _precheck_for_new(space, w_type):
@@ -138,6 +139,15 @@
                                         w_type.name))
     w_type.dict_w['__module__'] = w_value
 
+def descr___subclasses__(space, w_type):
+    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)
+
 # ____________________________________________________________
 
 type_typedef = StdTypeDef("type",
@@ -151,5 +161,6 @@
     mro = gateway.interp2app(descr_mro),
     __flags__ = GetSetProperty(descr__flags),
     __module__ = GetSetProperty(descr_get__module, descr_set__module),
+    __subclasses__ = gateway.interp2app(descr___subclasses__),
     __weakref__ = weakref_descr,
     )

Modified: pypy/dist/pypy/tool/cache.py
==============================================================================
--- pypy/dist/pypy/tool/cache.py	(original)
+++ pypy/dist/pypy/tool/cache.py	Thu Jun  8 15:34:13 2006
@@ -36,9 +36,13 @@
         except KeyError:
             result = self._build(key)
             self.content[key] = result
+            self._ready(result)
             return result
     getorbuild._annspecialcase_ = "specialize:memo"
 
+    def _ready(self, result):
+        pass
+
     def _freeze_(self):
         # needs to be SomePBC, but otherwise we can't really freeze the
         # cache because more getorbuild() calls might be discovered later



More information about the Pypy-commit mailing list