[pypy-svn] rev 844 - in pypy/trunk/src/pypy/objspace/std: . test

arigo at codespeak.net arigo at codespeak.net
Sat Jun 21 14:36:59 CEST 2003


Author: arigo
Date: Sat Jun 21 14:36:58 2003
New Revision: 844

Modified:
   pypy/trunk/src/pypy/objspace/std/default.py
   pypy/trunk/src/pypy/objspace/std/multimethod.py
   pypy/trunk/src/pypy/objspace/std/objspace.py
   pypy/trunk/src/pypy/objspace/std/test/test_multimethod.py
Log:
saner delegation-to-parent-classes

Modified: pypy/trunk/src/pypy/objspace/std/default.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/default.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/default.py	Sat Jun 21 14:36:58 2003
@@ -3,24 +3,6 @@
 from pypy.objspace.std.objspace import *
 
 
-# The default delegation mecanism is to allow any W_XxxObject class
-# to be regarded as an instance of any of its parent classes.
-
-def class_to_parent_classes(space, w_obj):
-    converted = []
-    W_Cls = w_obj.__class__
-    while W_Cls is not W_Object:
-        assert len(W_Cls.__bases__) == 1, (
-            "multimethod call with non wrapped argument: %r" % w_obj)
-        W_Cls, = W_Cls.__bases__
-        converted.append((W_Cls, w_obj))
-    return converted
-
-class_to_parent_classes.priority = PRIORITY_PARENT_IMPL
-StdObjSpace.delegate.register(class_to_parent_classes, Ellipsis)
-# 'Ellipsis' should not be used in other calls to register()
-
-
 # These are operations that must fall back to some default behavior,
 # but that should not appear explicitly at application-level.
 # There is no default object.__xxx__() method for these.

Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/multimethod.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/multimethod.py	Sat Jun 21 14:36:58 2003
@@ -126,15 +126,23 @@
         MultiMethod.__init__(self, 'delegate', 1, [])
     
     def postprocessresult(self, allowedtypes, result):
-        # add the Ellipsis catch-all delegator(s)
-        for function in self.dispatch_table[Ellipsis,]:
-            for t in allowedtypes[0]:
-                result.append(((t,), function))
+        by_priority = {} # classify delegators by priority
         
+        # add delegation from a class to its parent classes
+        arg1types, = allowedtypes
+        parenttypes = []
+        for t in arg1types:
+            parenttypes += list(t.__bases__)
+        if parenttypes:
+            def delegate_to_parent_classes(space, a, parenttypes=parenttypes):
+                return [(t, a) for t in parenttypes]
+            # hard-wire it at priority 0
+            by_priority[0] = [((t,), delegate_to_parent_classes)
+                              for t in arg1types]
+
         # sort the results in priority order, and insert None marks
         # between jumps in the priority values. Higher priority values
         # first.
-        by_priority = {} # classify delegators by priority
         for signature, function in result:
             assert hasattr(function, 'priority'), (
                 "delegator function must have a priority")
@@ -189,6 +197,7 @@
 
 
 class BoundMultiMethod:
+    ASSERT_BASE_TYPE = None
 
     def __init__(self, space, multimethod):
         self.space = space
@@ -221,6 +230,12 @@
         arity = self.multimethod.arity
         extraargs = args[arity:]
 
+        if self.ASSERT_BASE_TYPE:
+            for a in args[:arity]:
+                assert isinstance(a, self.ASSERT_BASE_TYPE), (
+                    "multimethod '%s' call with non wrapped argument: %r" %
+                    (self.multimethod.operatorsymbol, a))
+
         # look for an exact match first
         firstfailure = None
         types = tuple([(a.__class__,) for a in args])

Modified: pypy/trunk/src/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/objspace.py	Sat Jun 21 14:36:58 2003
@@ -16,14 +16,14 @@
 
 
 W_ANY = W_Object  # synonyms for use in .register()
-MultiMethod.ASSERT_BASE_TYPE = W_Object
+BoundMultiMethod.ASSERT_BASE_TYPE = W_Object
 MultiMethod.BASE_TYPE_OBJECT = W_AbstractTypeObject
 
 # delegation priorities
-PRIORITY_SAME_TYPE    = 4  # converting between several impls of the same type
-PRIORITY_PARENT_TYPE  = 3  # converting to a base type (e.g. bool -> int)
-PRIORITY_PARENT_IMPL  = 2  # this one is always done implicitely in default.py
-PRIORITY_CHANGE_TYPE  = 1  # changing type altogether (e.g. int -> float)
+PRIORITY_SAME_TYPE    = 2  # converting between several impls of the same type
+PRIORITY_PARENT_TYPE  = 1  # converting to a base type (e.g. bool -> int)
+PRIORITY_PARENT_IMPL  = 0  # hard-wired in multimethod.py
+PRIORITY_CHANGE_TYPE  = -1 # changing type altogether (e.g. int -> float)
 
 def registerimplementation(implcls):
     # this function should ultimately register the implementation class somewhere

Modified: pypy/trunk/src/pypy/objspace/std/test/test_multimethod.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_multimethod.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_multimethod.py	Sat Jun 21 14:36:58 2003
@@ -3,17 +3,7 @@
 from pypy.objspace.std.multimethod import *
 from pypy.tool import test
 
-# default delegator
-
-def class_to_parent_classes(space, w_obj):
-    converted = []
-    W_Cls = w_obj.__class__
-    while len(W_Cls.__bases__) == 1:
-        W_Cls, = W_Cls.__bases__
-        converted.append((W_Cls, w_obj))
-    return converted
-
-class_to_parent_classes.priority = 1
+BoundMultiMethod.ASSERT_BASE_TYPE = None
 
 
 class X:
@@ -77,7 +67,6 @@
     delegate = DelegateMultiMethod()
     delegate.register(from_y_to_x,              Y)
     delegate.register(from_x_to_str_sometimes,  X)
-    delegate.register(class_to_parent_classes,  Ellipsis)
     
     def wrap(self, x):
         return '<wrapped %r>' % (x,)


More information about the Pypy-commit mailing list