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

arigo at codespeak.net arigo at codespeak.net
Tue Jun 24 11:23:01 CEST 2003


Author: arigo
Date: Tue Jun 24 11:23:00 2003
New Revision: 1022

Modified:
   pypy/trunk/src/pypy/objspace/std/multimethod.py
   pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
Log:
Method calls now raise TypeErrors in preference of returning NotImplemented
(unless they are binary __xxx__ methods).


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	Tue Jun 24 11:23:00 2003
@@ -224,6 +224,7 @@
             if e.args:
                 raise OperationError(*e.args)
             else:
+                # raise a TypeError for a FailedToImplement
                 initialtypes = [dispatchtype(a)
                                 for a in args[:self.multimethod.arity]]
                 if len(initialtypes) <= 1:

Modified: pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py	Tue Jun 24 11:23:00 2003
@@ -1,8 +1,8 @@
 import autopath
 from pypy.tool import test
-from pypy.objspace.std.typeobject import PyMultimethodCode
+from pypy.objspace.std.typeobject import SpecialMultimethodCode
 
-class TestPyMultimethodCode(test.TestCase):
+class TestSpecialMultimethodCode(test.TestCase):
 
     def setUp(self):
         self.space = test.objspace('std')
@@ -13,8 +13,8 @@
     def test_int_sub(self):
         w = self.space.wrap
         for i in range(2):
-            meth = PyMultimethodCode(self.space.sub.multimethod, 
-                                     self.space.w_int.__class__, i)
+            meth = SpecialMultimethodCode(self.space.sub.multimethod, 
+                                          self.space.w_int.__class__, i)
             self.assertEqual(meth.slice().is_empty(), False)
             # test int.__sub__ and int.__rsub__
             self.assertEqual_w(meth.eval_code(self.space, None,
@@ -29,16 +29,16 @@
 
     def test_empty_inplace_add(self):
         for i in range(2):
-            meth = PyMultimethodCode(self.space.inplace_add.multimethod,
-                                     self.space.w_int.__class__, i)
+            meth = SpecialMultimethodCode(self.space.inplace_add.multimethod,
+                                          self.space.w_int.__class__, i)
             self.assertEqual(meth.slice().is_empty(), True)
 
     def test_float_sub(self):
         w = self.space.wrap
         w(1.5)   # force floatobject imported
         for i in range(2):
-            meth = PyMultimethodCode(self.space.sub.multimethod,
-                                     self.space.w_float.__class__, i)
+            meth = SpecialMultimethodCode(self.space.sub.multimethod,
+                                          self.space.w_float.__class__, i)
             self.assertEqual(meth.slice().is_empty(), False)
             # test float.__sub__ and float.__rsub__
 

Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py	Tue Jun 24 11:23:00 2003
@@ -94,7 +94,11 @@
                     code = multimethods[name]
                     if code.bound_position < i:
                         continue
-                code = PyMultimethodCode(multimethod, typeclass, i)
+                if len(multimethod.specialnames) > 1:
+                    mmcls = SpecialMultimethodCode
+                else:
+                    mmcls = PyMultimethodCode
+                code = mmcls(multimethod, typeclass, i)
                 multimethods[name] = code
         # add some more multimethods with a special interface
         code = NextMultimethodCode(spaceclass.next, typeclass)
@@ -123,30 +127,40 @@
     def slice(self):
         return self.basemultimethod.slice(self.typeclass, self.bound_position)
 
-    def do_call(self, space, w_globals, w_locals):
-        """Call the multimethod, ignoring all implementations that do not
-        have exactly the expected type at the bound_position."""
+    def prepare_args(self, space, w_globals, w_locals):
         multimethod = self.slice()
         dispatchargs = []
         for i in range(multimethod.arity):
             w_arg = space.getitem(w_locals, space.wrap('x%d'%(i+1)))
             dispatchargs.append(w_arg)
         dispatchargs = tuple(dispatchargs)
-        return multimethod.get(space).perform_call(dispatchargs)
+        return multimethod.get(space), dispatchargs
+
+    def do_call(self, space, w_globals, w_locals):
+        "Call the multimethod, raising a TypeError if not implemented."
+        mm, args = self.prepare_args(space, w_globals, w_locals)
+        return mm(*args)
 
     def eval_code(self, space, w_globals, w_locals):
-        "Call the multimethods, translating back information to Python."
+        "Call the multimethods, or raise a TypeError."
+        w_result = self.do_call(space, w_globals, w_locals)
+        # we accept a real None from operations with no return value
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
+class SpecialMultimethodCode(PyMultimethodCode):
+
+    def do_call(self, space, w_globals, w_locals):
+        "Call the multimethods, possibly returning a NotImplemented."
+        mm, args = self.prepare_args(space, w_globals, w_locals)
         try:
-            w_result = self.do_call(space, w_globals, w_locals)
+            return mm.perform_call(args)
         except FailedToImplement, e:
             if e.args:
                 raise OperationError(*e.args)
             else:
                 return space.w_NotImplemented
-        # we accept a real None from operations with no return value
-        if w_result is None:
-            w_result = space.w_None
-        return w_result
 
 class NextMultimethodCode(PyMultimethodCode):
 


More information about the Pypy-commit mailing list