[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