[pypy-svn] r9308 - pypy/branch/dist-interpapp/pypy/objspace/std

arigo at codespeak.net arigo at codespeak.net
Fri Feb 18 14:56:54 CET 2005


Author: arigo
Date: Fri Feb 18 14:56:53 2005
New Revision: 9308

Modified:
   pypy/branch/dist-interpapp/pypy/objspace/std/stdtypedef.py
   pypy/branch/dist-interpapp/pypy/objspace/std/typeobject.py
   pypy/branch/dist-interpapp/pypy/objspace/std/typetype.py
Log:
Make W_TypeObject.dict_w lazy-loading, following the model of 
LazyModule.  This allows the multimethods to be installed only when 
needed.



Modified: pypy/branch/dist-interpapp/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/stdtypedef.py	(original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/stdtypedef.py	Fri Feb 18 14:56:53 2005
@@ -73,15 +73,19 @@
     from pypy.objspace.std.objecttype import object_typedef
 
     w = space.wrap
-    rawdict = typedef.rawdict.copy()
+    rawdict = typedef.rawdict
+    lazyloaders = {}
 
     if isinstance(typedef, StdTypeDef):
         # get all the sliced multimethods
         multimethods = slicemultimethods(space, typedef)
-        for name, gateway in multimethods.items():
-            assert name not in rawdict, 'name clash: %s in %s_typedef' % (
-                name, typedef.name)
-            rawdict[name] = gateway
+        for name, loader in multimethods.items():
+            if name in rawdict:
+                # the name specified in the rawdict has priority
+                continue
+            assert name not in lazyloaders, (
+                'name clash: %s in %s.lazyloaders' % (name, typedef.name))
+            lazyloaders[name] = loader
 
     # compute the bases
     if typedef is object_typedef:
@@ -95,8 +99,10 @@
     for descrname, descrvalue in rawdict.items():
         dict_w[descrname] = w(descrvalue)
 
-    return W_TypeObject(space, typedef.name, bases_w, dict_w,
-                        overridetypedef=typedef)
+    w_type = W_TypeObject(space, typedef.name, bases_w, dict_w,
+                          overridetypedef=typedef)
+    w_type.lazyloaders = lazyloaders
+    return w_type
 
 def hack_out_multimethods(ns):
     "NOT_RPYTHON: initialization-time only."
@@ -261,29 +267,30 @@
     return gateway.interp2app(func, app_name=methname, unwrap_spec=unwrap_spec)
 
 def slicemultimethod(space, multimethod, typedef, result, local=False):
-    from pypy.objspace.std.objecttype import object_typedef
     for i in range(len(multimethod.specialnames)):
-        # each MultimethodCode embeds a multimethod
         methname = multimethod.specialnames[i]
         if methname in result:
             # conflict between e.g. __lt__ and
             # __lt__-as-reversed-version-of-__gt__
-            gw = result[methname]
-            if gw.bound_position < i:
+            loader = result[methname]
+            if loader.bound_position < i:
                 continue
 
-        prefix, list_of_typeorders = sliced_typeorders(
-            space.model.typeorder, multimethod, typedef, i, local=local)
-        exprargs, expr, miniglobals, fallback = multimethod.install(prefix, list_of_typeorders,
-                                                                    baked_perform_call=False)
-        if fallback:
-            continue   # skip empty multimethods
-        trampoline = make_perform_trampoline(prefix, exprargs, expr, miniglobals,
-                                             multimethod, i,
-                                             allow_NotImplemented_results=True)
-        gw = wrap_trampoline_in_gateway(trampoline, methname, multimethod)
-        gw.bound_position = i   # for the check above
-        result[methname] = gw
+        def multimethod_loader(i=i, methname=methname):
+            prefix, list_of_typeorders = sliced_typeorders(
+                space.model.typeorder, multimethod, typedef, i, local=local)
+            exprargs, expr, miniglobals, fallback = multimethod.install(prefix, list_of_typeorders,
+                                                                        baked_perform_call=False)
+            if fallback:
+                return None   # skip empty multimethods
+            trampoline = make_perform_trampoline(prefix, exprargs, expr, miniglobals,
+                                                 multimethod, i,
+                                                 allow_NotImplemented_results=True)
+            gw = wrap_trampoline_in_gateway(trampoline, methname, multimethod)
+            return space.wrap(gw)
+
+        multimethod_loader.bound_position = i   # for the check above
+        result[methname] = multimethod_loader
 
 def slicemultimethods(space, typedef):
     result = {}

Modified: pypy/branch/dist-interpapp/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/typeobject.py	(original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/typeobject.py	Fri Feb 18 14:56:53 2005
@@ -8,6 +8,8 @@
 class W_TypeObject(W_Object):
     from pypy.objspace.std.typetype import type_typedef as typedef
 
+    lazyloaders = None   # can be overridden by specific instances
+
     def __init__(w_self, space, name, bases_w, dict_w,
                  overridetypedef=None):
         W_Object.__init__(w_self, space)
@@ -110,6 +112,13 @@
         try:
             return w_self.dict_w[attr]
         except KeyError:
+            if w_self.lazyloaders and attr in w_self.lazyloaders:
+                loader = w_self.lazyloaders[attr]
+                del w_self.lazyloaders[attr]
+                w_value = loader()
+                if w_value is not None:   # None means no such attribute
+                    w_self.dict_w[attr] = w_value
+                return w_value
             return None
 
     def lookup(w_self, key):
@@ -148,6 +157,10 @@
 
     def getdict(w_self):
         # XXX should return a <dictproxy object>
+        if w_self.lazyloaders:
+            for attr in w_self.lazyloaders.keys():
+                w_self.getdictvalue(w_self.space, attr)
+            del w_self.lazyloaders
         space = w_self.space
         dictspec = []
         for key, w_value in w_self.dict_w.items():
@@ -215,6 +228,8 @@
     w_type.dict_w[name] = w_value
 
 def delattr__Type_ANY(space, w_type, w_name):
+    if w_type.lazyloaders:
+        w_type.getdict()    # force un-lazification
     name = space.str_w(w_name)
     w_descr = space.lookup(w_type, name)
     if w_descr is not None:

Modified: pypy/branch/dist-interpapp/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/objspace/std/typetype.py	(original)
+++ pypy/branch/dist-interpapp/pypy/objspace/std/typetype.py	Fri Feb 18 14:56:53 2005
@@ -62,7 +62,11 @@
         return space.w_object
 
 def descr__doc(space, w_type):
-    return w_type.dict_w.get('__doc__')
+    w_result = w_type.getdictvalue(space, '__doc__')
+    if w_result is None:
+        return space.w_None
+    else:
+        return w_result
 
 # ____________________________________________________________
 



More information about the Pypy-commit mailing list