Lib.test.test_slots_jy.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
"""Slot tests
Made for Jython.
"""
from test import test_support
from java.util import HashMap
import unittest
# The strict tests fail on PyPy (but work on CPython and Jython).
# They're questionable
strict = True
class SlottedTestCase(unittest.TestCase):
def test_slotted(self):
class Foo(object):
__slots__ = 'bar'
self.assert_('__dict__' not in Foo.__dict__)
foo = Foo()
self.assert_(not hasattr(foo, '__dict__'))
foo.bar = 'hello bar'
self.assertEqual(foo.bar, 'hello bar')
self.assertRaises(AttributeError, setattr, foo, 'foo', 'hello foo')
class Baz(object):
__slots__ = ['python', 'jython']
self.assert_('__dict__' not in Baz.__dict__)
baz = Baz()
self.assert_(not hasattr(baz, '__dict__'))
baz.python = 'hello python'
baz.jython = 'hello jython'
self.assertEqual(baz.python, 'hello python')
self.assertEqual(baz.jython, 'hello jython')
self.assertRaises(AttributeError, setattr, baz, 'foo', 'hello')
class SlottedWithDictTestCase(unittest.TestCase):
def test_subclass(self):
class Base(object):
pass
class Foo(Base):
__slots__ = 'bar'
self.assert_('__dict__' not in Foo.__dict__)
foo = Foo()
self.assert_(hasattr(foo, '__dict__'))
foo.bar = 'hello bar'
foo.foo = 'hello foo'
self.assertEqual(foo.bar, 'hello bar')
self.assertEqual(foo.__dict__, {'foo': 'hello foo'})
def test_subclass_mro(self):
class Base(object):
pass
class Slotted(object):
__slots__ = 'baz'
class Foo(Slotted, Base):
__slots__ = 'bar'
if strict:
self.assert_('__dict__' in Foo.__dict__)
self.assertEqual(Foo.__dict__['__dict__'].__objclass__, Foo)
foo = Foo()
self.assert_(hasattr(foo, '__dict__'))
foo.bar = 'hello bar'
foo.baz = 'hello baz'
foo.foo = 'hello foo'
self.assertEqual(foo.bar, 'hello bar')
self.assertEqual(foo.baz, 'hello baz')
self.assertEqual(foo.__dict__, {'foo': 'hello foo'})
class Bar(Slotted, Base):
pass
if strict:
self.assert_('__dict__' in Bar.__dict__)
self.assertEqual(Bar.__dict__['__dict__'].__objclass__, Bar)
bar = Bar()
self.assert_(hasattr(bar, '__dict__'))
bar.bar = 'hello bar'
bar.baz = 'hello baz'
bar.foo = 'hello foo'
self.assertEqual(bar.bar, 'hello bar')
self.assertEqual(bar.baz, 'hello baz')
self.assertEqual(bar.__dict__, {'foo': 'hello foo', 'bar': 'hello bar'})
def test_subclass_oldstyle(self):
class OldBase:
pass
class Foo(OldBase, object):
__slots__ = 'bar'
if strict:
self.assert_('__dict__' in Foo.__dict__)
self.assertEqual(Foo.__dict__['__dict__'].__objclass__, Foo)
foo = Foo()
self.assert_(hasattr(foo, '__dict__'))
foo.bar = 'hello bar'
foo.foo = 'hello foo'
self.assertEqual(foo.bar, 'hello bar')
self.assertEqual(foo.__dict__, {'foo': 'hello foo'})
class Bar(OldBase, object):
__slots__ = '__dict__'
self.assert_('__dict__' in Bar.__dict__)
self.assertEqual(Bar.__dict__['__dict__'].__objclass__, Bar)
bar = Bar()
self.assert_(hasattr(bar, '__dict__'))
bar.bar = 'hello bar'
bar.foo = 'hello foo'
self.assertEqual(bar.bar, 'hello bar')
self.assertEqual(bar.__dict__, {'foo': 'hello foo', 'bar': 'hello bar'})
def test_mixin_oldstyle(self):
class OldBase:
pass
class NewBase(object):
pass
class Baz(NewBase, OldBase):
__slots__ = 'baz'
self.assert_('__dict__' not in Baz.__dict__)
baz = Baz()
self.assert_(hasattr(baz, '__dict__'))
baz.baz = 'hello baz'
baz.bar = 'hello bar'
self.assertEqual(baz.baz, 'hello baz')
self.assertEqual(baz.bar, 'hello bar')
self.assertEqual(baz.__dict__, {'bar': 'hello bar'})
class SlottedWithWeakrefTestCase(unittest.TestCase):
def test_subclass_oldstyle(self):
class OldBase:
pass
class Foo(OldBase, object):
__slots__ = '__dict__'
self.assert_(hasattr(Foo, '__weakref__'))
class SpecialSlotsBaseTestCase(unittest.TestCase):
# Tests for http://bugs.jython.org/issue2272, including support for
# werkzeug.local.LocalProxy
def make_class(self, base, slot):
class C(base):
__slots__ = (slot)
if slot == "__dict__":
@property
def __dict__(self):
return {"x": 42, "y": 47}
def __getattr__(self, name):
try:
return self.__dict__[name]
except KeyError:
raise AttributeError("%r object has no attribute %r" % (
self.__class__.__name__, name))
return C
def test_dict_slot(self):
C = self.make_class(object, "__dict__")
c = C()
self.assertIn("__dict__", dir(c))
self.assertIn("x", dir(c))
self.assertIn("y", dir(c))
self.assertEqual(c.__dict__.get("x"), 42)
self.assertEqual(c.x, 42)
self.assertEqual(c.y, 47)
with self.assertRaisesRegexp(AttributeError, r"'C' object has no attribute 'z'"):
c.z
def test_dict_slot_str(self):
# Unlike CPython, Jython does not arbitrarily limit adding
# __dict__ slot to str and other types that are not object
C = self.make_class(str, "__dict__")
c = C("abc123")
self.assertTrue(c.startswith("abc"))
self.assertIn("__dict__", dir(c))
self.assertIn("x", dir(c))
self.assertIn("y", dir(c))
self.assertEqual(c.__dict__.get("x"), 42)
self.assertEqual(c.x, 42)
self.assertEqual(c.y, 47)
with self.assertRaisesRegexp(AttributeError, r"'C' object has no attribute 'z'"):
c.z
def test_dict_slot_subclass(self):
# Unlike CPython, Jython does not arbitrarily limit adding __dict__ slot to subtypes
class B(object):
@property
def w(self):
return 23
C = self.make_class(B, "__dict__")
c = C()
self.assertIn("__dict__", dir(c))
self.assertIn("x", dir(c))
self.assertIn("y", dir(c))
self.assertEqual(c.__dict__.get("x"), 42)
self.assertEqual(c.x, 42)
self.assertEqual(c.y, 47)
with self.assertRaisesRegexp(AttributeError, r"'C' object has no attribute 'z'"):
c.z
self.assertEqual(c.w, 23)
def test_dict_slot_subclass_java_hashmap(self):
C = self.make_class(HashMap, "__dict__")
# has everything in a HashMap, including Python semantic equivalence
c = C({"a": 1, "b": 2})
self.assertTrue(c.containsKey("a"))
self.assertEqual(sorted(c.iteritems()), [("a", 1), ("b", 2)])
# but also has a __dict__ slot for further interesting ;) possibilities
self.assertIn("__dict__", dir(c))
self.assertIn("x", dir(c))
self.assertIn("y", dir(c))
self.assertEqual(c.__dict__.get("x"), 42)
self.assertEqual(c.x, 42)
self.assertEqual(c.y, 47)
with self.assertRaisesRegexp(AttributeError, r"'C' object has no attribute 'z'"):
c.z
def test_weakref_slot(self):
self.assertNotIn("__weakref__", dir(object()))
self.assertIn("__weakref__", dir(self.make_class(object, "__weakref__")()))
class B(object):
pass
self.assertIn("__weakref__", dir(B()))
self.assertIn("__weakref__", dir(self.make_class(B, "__weakref__")()))
self.assertNotIn("__weakref__", dir("abc"))
self.assertIn("__weakref__", dir(self.make_class(str, "__weakref__")()))
self.assertNotIn("__weakref__", dir(HashMap()))
self.assertIn("__weakref__", dir(self.make_class(HashMap, "__weakref__")()))
class MultiInheritanceSlotsTestCase(unittest.TestCase):
def test_diamond_multi_inheritance_second_branch(self):
# see issue bugs.jython.org/issue2101
# also related: bugs.jython.org/issue1996
result = []
class A(object):
def method(self):
pass
class B(A):
__slots__ = ('b')
def method(self):
result.append('B.method begin')
super(B, self).method()
self.b = 'b'
result.append('B.method end')
class C(A):
def method(self):
result.append('C.method begin')
super(C, self).method()
self.c = 'c'
result.append('C.method end')
class D1(B, C):
def method(self): super(D1, self).method()
class D2(C, B):
def method(self): super(D2, self).method()
D1().method()
self.assertEqual(result,
['B.method begin', 'C.method begin', 'C.method end', 'B.method end'])
result = []
D2().method()
self.assertEqual(result,
['C.method begin', 'B.method begin', 'B.method end', 'C.method end'])
def test_main():
test_support.run_unittest(SlottedTestCase,
SlottedWithDictTestCase,
SlottedWithWeakrefTestCase,
SpecialSlotsBaseTestCase,
MultiInheritanceSlotsTestCase)
if __name__ == '__main__':
test_main()