RandomSec/lib/jython-2.5.1/test/test_descr_jy.py
Vishal Talwar d0df704d8a added python code part of jython distribution in lib/jython-2.5.1
added python.path vm arg to startup script
fixed infinite loop in unwrap() when displaying sequences of sequences



git-svn-id: http://google-refine.googlecode.com/svn/trunk@509 7d457c2a-affb-35e4-300a-418c747d4874
2010-04-20 18:50:24 +00:00

549 lines
15 KiB
Python

"""Test descriptors, binary ops, etc.
Made for Jython.
"""
import types
import unittest
from test import test_support
class Old:
pass
class New(object):
pass
old = Old()
new = New()
class TestDescrTestCase(unittest.TestCase):
def test_class_dict_is_copy(self):
class FooMeta(type):
def __new__(meta, name, bases, class_dict):
cls = type.__new__(meta, name, bases, class_dict)
self.assert_('foo' not in class_dict)
cls.foo = 'bar'
self.assert_('foo' not in class_dict)
return cls
class Foo(object):
__metaclass__ = FooMeta
def test_descr___get__(self):
class Foo(object):
__slots__ = 'bar'
def hello(self):
pass
def hi(self):
pass
hi = staticmethod(hi)
foo = Foo()
foo.bar = 'baz'
self.assertEqual(Foo.bar.__get__(foo), 'baz')
self.assertEqual(Foo.bar.__get__(None, Foo), Foo.bar)
bound = Foo.hello.__get__(foo)
self.assert_(isinstance(bound, types.MethodType))
self.assert_(bound.im_self is foo)
self.assertEqual(Foo.hello.__get__(None, Foo), Foo.hello)
bound = Foo.hi.__get__(foo)
self.assert_(isinstance(bound, types.MethodType))
self.assert_(bound.im_self is foo)
unbound = Foo.hi.__get__(None, foo)
self.assert_(isinstance(unbound, types.MethodType))
self.assert_(unbound.im_self is None)
def test_ints(self):
class C(int):
pass
try:
foo = int(None)
except TypeError:
pass
else:
self.assert_(False, "should have raised TypeError")
try:
foo = C(None)
except TypeError:
pass
else:
self.assert_(False, "should have raised TypeError")
def test_raising_custom_attribute_error(self):
class RaisesCustomMsg(object):
def __get__(self, instance, type):
raise AttributeError("Custom message")
class CustomAttributeError(AttributeError): pass
class RaisesCustomErr(object):
def __get__(self, instance, type):
raise CustomAttributeError
class Foo(object):
custom_msg = RaisesCustomMsg()
custom_err = RaisesCustomErr()
self.assertRaises(CustomAttributeError, lambda: Foo().custom_err)
try:
Foo().custom_msg
self.assert_(False) # Previous line should raise AttributteError
except AttributeError, e:
self.assertEquals("Custom message", str(e))
class SubclassDescrTestCase(unittest.TestCase):
def test_subclass_cmp_right_op(self):
# Case 1: subclass of int
class B(int):
def __ge__(self, other):
return "B.__ge__"
def __le__(self, other):
return "B.__le__"
self.assertEqual(B(1) >= 1, "B.__ge__")
self.assertEqual(1 >= B(1), "B.__le__")
# Case 2: subclass of object
class C(object):
def __ge__(self, other):
return "C.__ge__"
def __le__(self, other):
return "C.__le__"
self.assertEqual(C() >= 1, "C.__ge__")
self.assertEqual(1 >= C(), "C.__le__")
# Case 3: subclass of new-style class; here it gets interesting
class D(C):
def __ge__(self, other):
return "D.__ge__"
def __le__(self, other):
return "D.__le__"
self.assertEqual(D() >= C(), "D.__ge__")
self.assertEqual(C() >= D(), "D.__le__")
# Case 4: comparison is different than other binops
class E(C):
pass
self.assertEqual(E.__le__, C.__le__)
self.assertEqual(E() >= 1, "C.__ge__")
self.assertEqual(1 >= E(), "C.__le__")
self.assertEqual(E() >= C(), "C.__ge__")
self.assertEqual(C() >= E(), "C.__le__") # different
def test_subclass_binop(self):
def raises(exc, expected, callable, *args):
try:
callable(*args)
except exc, msg:
if str(msg) != expected:
self.assert_(False, "Message %r, expected %r" % (str(msg),
expected))
else:
self.assert_(False, "Expected %s" % exc)
class B(object):
pass
class C(object):
def __radd__(self, o):
return '%r + C()' % (o,)
def __rmul__(self, o):
return '%r * C()' % (o,)
# Test strs, unicode, lists and tuples
mapping = []
# + binop
mapping.append((lambda o: 'foo' + o,
TypeError, "cannot concatenate 'str' and 'B' objects",
"'foo' + C()"))
# XXX: There's probably work to be done here besides just emulating this
# message
if test_support.is_jython:
mapping.append((lambda o: u'foo' + o,
TypeError, "cannot concatenate 'unicode' and 'B' objects",
"u'foo' + C()"))
else:
mapping.append((lambda o: u'foo' + o,
TypeError,
'coercing to Unicode: need string or buffer, B found',
"u'foo' + C()"))
mapping.append((lambda o: [1, 2] + o,
TypeError, 'can only concatenate list (not "B") to list',
'[1, 2] + C()'))
mapping.append((lambda o: ('foo', 'bar') + o,
TypeError, 'can only concatenate tuple (not "B") to tuple',
"('foo', 'bar') + C()"))
# * binop
mapping.append((lambda o: 'foo' * o,
TypeError, "can't multiply sequence by non-int of type 'B'",
"'foo' * C()"))
mapping.append((lambda o: u'foo' * o,
TypeError, "can't multiply sequence by non-int of type 'B'",
"u'foo' * C()"))
mapping.append((lambda o: [1, 2] * o,
TypeError, "can't multiply sequence by non-int of type 'B'",
'[1, 2] * C()'))
mapping.append((lambda o: ('foo', 'bar') * o,
TypeError, "can't multiply sequence by non-int of type 'B'",
"('foo', 'bar') * C()"))
for func, bexc, bexc_msg, cresult in mapping:
raises(bexc, bexc_msg, lambda : func(B()))
self.assertEqual(func(C()), cresult)
def test_overriding_base_binop(self):
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
self.assertEquals(DoublerBase(2) * AnotherDoubler(3), 12)
def test_oldstyle_binop_notimplemented(self):
class Foo:
pass
class Bar(object):
def __radd__(self, other):
return 3
self.assertEqual(Foo() + Bar(), 3)
def test_int_mul(self):
# http://bugs.jython.org/issue1332
class Foo(tuple):
def __rmul__(self, other):
return 'foo'
foo = Foo()
self.assertEqual(3.0 * foo, 'foo')
self.assertEqual(4 * foo, 'foo')
class InPlaceTestCase(unittest.TestCase):
def test_iadd(self):
class Foo(object):
def __add__(self, other):
return 1
def __radd__(self, other):
return 2
class Bar(object):
pass
class Baz(object):
def __iadd__(self, other):
return NotImplemented
foo = Foo()
foo += Bar()
self.assertEqual(foo, 1)
bar = Bar()
bar += Foo()
self.assertEqual(bar, 2)
baz = Baz()
baz += Foo()
self.assertEqual(baz, 2)
def test_imul(self):
class FooInplace(list):
def __imul__(self, other):
return [1]
class Bar(FooInplace):
def __mul__(self, other):
return [2]
foo = FooInplace()
foo *= 3
self.assertEqual(foo, [1])
foo = Bar([3])
foo *= 3
self.assertEqual(foo, [1])
class Baz(FooInplace):
def __mul__(self, other):
return [3]
baz = Baz()
baz *= 3
self.assertEqual(baz, [1])
def test_list(self):
class Foo(list):
def __mul__(self, other):
return [1]
foo = Foo([2])
foo *= 3
if test_support.is_jython:
self.assertEqual(foo, [2, 2, 2])
else:
# CPython ignores list.__imul__ on a subclass with __mul__
# (unlike Jython and PyPy)
self.assertEqual(foo, [1])
class Bar(object):
def __radd__(self, other):
return 1
def __rmul__(self, other):
return 2
l = []
l += Bar()
self.assertEqual(l, 1)
l = []
l *= Bar()
self.assertEqual(l, 2)
def test_iand(self):
# Jython's set __iand__ (as well as isub, ixor, etc) was
# previously broken
class Foo(set):
def __and__(self, other):
return set([1])
foo = Foo()
foo &= 3
self.assertEqual(foo, set([1]))
class DescrExceptionsTestCase(unittest.TestCase):
def test_hex(self):
self._test(hex)
def test_oct(self):
self._test(oct)
def test_other(self):
for op in '-', '+', '~':
try:
eval('%s(old)' % op)
except AttributeError:
pass
else:
self._assert(False, 'Expected an AttributeError, op: %s' % op)
try:
eval('%s(new)' % op)
except TypeError:
pass
else:
self._assert(False, 'Expected a TypeError, op: %s' % op)
def _test(self, func):
self.assertRaises(AttributeError, func, old)
self.assertRaises(TypeError, func, new)
def test_eq(self):
class A(object):
def __eq__(self, other):
return self.value == other.value
self.assertRaises(AttributeError, lambda: A() == A())
class GetAttrTestCase(unittest.TestCase):
def test_raising_custom_attribute_error(self):
# Very similar to
# test_descr_jy.TestDescrTestCase.test_raising_custom_attribute_error
class BarAttributeError(AttributeError): pass
class Bar(object):
def __getattr__(self, name):
raise BarAttributeError
class BarClassic:
def __getattr__(self, name):
raise BarAttributeError
class Foo(object):
def __getattr__(self, name):
raise AttributeError("Custom message")
class FooClassic:
def __getattr__(self, name):
raise AttributeError("Custom message")
self.assertRaises(BarAttributeError, lambda: Bar().x)
self.assertRaises(BarAttributeError, lambda: BarClassic().x)
try:
Foo().x
self.assert_(False) # Previous line should raise AttributteError
except AttributeError, e:
self.assertEquals("Custom message", str(e))
try:
FooClassic().x
self.assert_(False) # Previous line should raise AttributteError
except AttributeError, e:
self.assertEquals("Custom message", str(e))
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
class BinopCombinationsTestCase(unittest.TestCase):
"""Try to test more exhaustively binop overriding combination
cases"""
def test_binop_combinations_mul(self):
class X(Base):
pass
class Y(X):
pass
fail = do_test(X, Y, 'mul', lambda x, y: x*y)
#print len(fail)
self.assert_(not fail)
def test_binop_combinations_sub(self):
class X(Base):
pass
class Y(X):
pass
fail = do_test(X, Y, 'sub', lambda x, y: x-y)
#print len(fail)
self.assert_(not fail)
def test_binop_combinations_pow(self):
class X(Base):
pass
class Y(X):
pass
fail = do_test(X, Y, 'pow', lambda x, y: x**y)
#print len(fail)
self.assert_(not fail)
def test_binop_combinations_more_exhaustive(self):
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)
self.assert_(not fail)
def test_main():
test_support.run_unittest(TestDescrTestCase,
SubclassDescrTestCase,
InPlaceTestCase,
DescrExceptionsTestCase,
GetAttrTestCase,
BinopCombinationsTestCase)
if __name__ == '__main__':
test_main()