[pypy-svn] r60867 - pypy/trunk/pypy/objspace/test
pedronis at codespeak.net
pedronis at codespeak.net
Sat Jan 10 13:37:19 CET 2009
Author: pedronis
Date: Sat Jan 10 13:37:17 2009
New Revision: 60867
Added:
pypy/trunk/pypy/objspace/test/test_binop_overriding.py (contents, props changed)
Log:
issue412 in-progress
tests about issue412, they pass on cpython but fails on PyPy, made most of them run only with py.test -A because they are quite exhaistive but slow
Added: pypy/trunk/pypy/objspace/test/test_binop_overriding.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/objspace/test/test_binop_overriding.py Sat Jan 10 13:37:17 2009
@@ -0,0 +1,175 @@
+# test about the binop operation rule, see issue 412
+from pypy.conftest import option
+
+class AppTestBinopCombinations:
+
+ def setup_class(cls):
+ w_helpers = cls.space.appexec([], """():
+ class Base(object):
+ def __init__(self, name):
+ self.name = name
+
+ def lookup_where(obj, name):
+ mro = type(obj).__mro__
+ for t in mro:
+ if name in t.__dict__:
+ return t.__dict__[name], t
+ return None, None
+
+ def refop(x, y, opname, ropname):
+ # this has been validated by running the tests on top of cpython
+ # so for the space of possibilities that the tests touch it is known
+ # to behave like cpython as long as the latter doesn't change its own
+ # algorithm
+ t1 = type(x)
+ t2 = type(y)
+ op, where1 = lookup_where(x, opname)
+ rop, where2 = lookup_where(y, ropname)
+ if op is None and rop is not None:
+ return rop(y, x)
+ if rop and where1 is not where2:
+ if (issubclass(t2, t1) and not issubclass(where1, where2)
+ and not issubclass(t1, where2)
+ ):
+ return rop(y, x)
+ if op is None:
+ return "TypeError"
+ return op(x,y)
+
+ def do_test(X, Y, name, impl):
+ x = X('x')
+ y = Y('y')
+ opname = '__%s__' % name
+ ropname = '__r%s__' % name
+
+ count = [0]
+ fail = []
+
+ def check(z1, z2):
+ ref = refop(z1, z2, opname, ropname)
+ try:
+ v = impl(z1, z2)
+ except TypeError:
+ v = "TypeError"
+ if v != ref:
+ fail.append(count[0])
+
+ def override_in_hier(n=6):
+ if n == 0:
+ count[0] += 1
+ check(x, y)
+ check(y, x)
+ return
+
+ f = lambda self, other: (n, self.name, other.name)
+ if n%2 == 0:
+ name = opname
+ else:
+ name = ropname
+
+ for C in Y.__mro__:
+ if name in C.__dict__:
+ continue
+ if C is not object:
+ setattr(C, name, f)
+ override_in_hier(n-1)
+ if C is not object:
+ delattr(C, name)
+
+ override_in_hier()
+ #print count[0]
+ return fail
+
+ return Base, do_test
+""")
+ cls.w_helpers = w_helpers
+ cls.w_appdirect = cls.space.wrap(option.runappdirect)
+
+ def test_overriding_base_binop_explict(self):
+ if not self.appdirect:
+ skip("fails, issue412")
+ class MulBase(object):
+ def __init__(self, value):
+ self.value = value
+ def __mul__(self, other):
+ return self.value * other.value
+ def __rmul__(self, other):
+ return other.value * self.value
+ class DoublerBase(MulBase):
+ def __mul__(self, other):
+ return 2 * (self.value * other.value)
+ class AnotherDoubler(DoublerBase):
+ pass
+ res = DoublerBase(2) * AnotherDoubler(3)
+ assert res == 12
+
+ def test_binop_combinations_mul(self):
+ if not self.appdirect:
+ skip("slow test, should be run as appdirect test")
+ Base, do_test = self.helpers
+
+ class X(Base):
+ pass
+ class Y(X):
+ pass
+
+ fail = do_test(X, Y, 'mul', lambda x,y: x*y)
+ #print len(fail)
+ assert not fail
+
+ def test_binop_combinations_sub(self):
+ if not self.appdirect:
+ skip("fails, issue412")
+ Base, do_test = self.helpers
+ class X(Base):
+ pass
+ class Y(X):
+ pass
+
+ fail = do_test(X, Y, 'sub', lambda x,y: x-y)
+ #print len(fail)
+ assert not fail
+
+ def test_binop_combinations_pow(self):
+ if not self.appdirect:
+ skip("slow test, should be run as appdirect test")
+ Base, do_test = self.helpers
+
+ class X(Base):
+ pass
+ class Y(X):
+ pass
+
+ fail = do_test(X, Y, 'pow', lambda x,y: x**y)
+ #print len(fail)
+ assert not fail
+
+ def test_binop_combinations_more_exhaustive(self):
+ if not self.appdirect:
+ skip("very slow test, should be run as appdirect test")
+ Base, do_test = self.helpers
+
+ class X(Base):
+ pass
+
+ class B1(object):
+ pass
+
+ class B2(object):
+ pass
+
+ class X1(B1, X, B2):
+ pass
+
+ class C1(object):
+ pass
+
+ class C2(object):
+ pass
+
+ class Y(C1, X1, C2):
+ pass
+
+ fail = do_test(X, Y, 'sub', lambda x,y: x-y)
+ #print len(fail)
+ assert not fail
More information about the Pypy-commit
mailing list