/Languages/IronPython/Tests/test_class.py
Python | 3764 lines | 3631 code | 82 blank | 51 comment | 36 complexity | 781581b3b4743bfe061622f3b4ddff9a MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- #####################################################################################
- #
- # Copyright (c) Microsoft Corporation. All rights reserved.
- #
- # This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- # copy of the license can be found in the License.html file at the root of this distribution. If
- # you cannot locate the Apache License, Version 2.0, please send an email to
- # ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- # by the terms of the Apache License, Version 2.0.
- #
- # You must not remove this notice, or any other, from this software.
- #
- #
- #####################################################################################
- #--IMPORTS---------------------------------------------------------------------
- from iptest.assert_util import *
- from iptest.type_util import *
- import sys
- #--HELPERS---------------------------------------------------------------------
- ############################################################
- def test_common_attributes():
- builtin_type_instances = [None, object(), 1, "Hello", [0,1], {"a":0}]
- builtin_hashable_type_instances = [None, object(), 1, "Hello"]
- builtin_types = [type(None), object, int, str, list, dict]
- for i in builtin_type_instances:
- # Read-only attribute
- AssertError(AttributeError, i.__delattr__, "__doc__")
- # Non-existent attribute
- AssertError(AttributeError, i.__delattr__, "foo")
- # Modifying __class__ causes a TypeError
- AssertError(TypeError, i.__delattr__, "__class__")
-
- # Read-only attribute
- AssertError(TypeError, i.__setattr__, "__doc__")
- # Non-existent attribute
- AssertError(AttributeError, i.__setattr__, "foo", "foovalue")
- # Modifying __class__ causes a TypeError
- AssertError(TypeError, i.__setattr__, "__class__")
-
- AreEqual(type(i), i.__getattribute__("__class__"))
- # Non-existent attribute
- AssertError(AttributeError, i.__getattribute__, "foo")
-
- if (is_cli or is_silverlight) and i == None: # !!! Need to expose __reduce__ on all types
- AssertError(TypeError, i.__reduce__)
- AssertError(TypeError, i.__reduce_ex__)
-
- for i in builtin_hashable_type_instances:
- AreEqual(hash(i), i.__hash__())
-
- for i in builtin_types:
- if (is_cli or is_silverlight) and i == type(None):
- continue
- # __init__ and __new__ are implemented by IronPython.Runtime.Operations.InstanceOps
- # We do repr to ensure that we can map back the functions properly
- repr(getattr(i, "__init__"))
- repr(getattr(i, "__new__"))
-
- ############################################################
- def test_set_dict():
- class C: pass
- setdict = C.__dict__
- C.__dict__ = setdict
-
- o1 = C()
- class C:
- def m(self):
- return 42
-
- o2 = C()
- Assert(42 == o2.m())
-
- Assert(o2.__class__ is C)
- Assert(o2.__class__ is not o1.__class__)
- ############################################################
- def test_attrs():
- class C:pass
-
- C.v = 10
-
- Assert(C.v == 10)
-
- success = 0
- try:
- x = C.x
- except AttributeError:
- success = 1
- Assert(success == 1)
- ############################################################
- def test_type_in():
- AreEqual(type in (None, True, False, 1, {}, [], (), 1.0, 1L, (1+0j)), False)
- ############################################################
- def test_init_defaults():
- class A:
- def __init__(self, height=20, width=30):
- self.area = height * width
-
- a = A()
- Assert(a.area == 600)
- a = A(2,3)
- Assert(a.area == 6)
- a = A(2)
- Assert(a.area == 60)
- a = A(width = 2)
- Assert(a.area == 40)
- ############################################################
- def test_getattr():
- class C:
- def __init__(self, name, flag):
- self.f = file(name, flag)
- def __getattr__(self, name):
- return getattr(self.f, name)
-
- tmpfile = "tmpfile.txt"
-
- if not is_silverlight:
- c=C(tmpfile, "w")
- c.write("Hello\n")
- c.close()
- c=C(tmpfile, "r")
- Assert(c.readline() == "Hello\n")
- c.close()
- try:
- import os
- os.unlink(tmpfile)
- except:
- pass
-
- # new-style
- class C(object):
- def __getattr__(self, name):
- raise AttributeError(name)
-
- # old-style
- class D:
- def __getattr__(self, name):
- raise AttributeError(name)
- # new-style __getattribute__
- class E(object):
- def __getattribute__(self, name):
- if name == 'xyz':
- raise AttributeError(name)
- if name == 'x':
- return 42
- return object.__getattribute__(self, name)
- # derived new-style type
- class F(E):
- pass
- # verify that base class' __getattribute__ is called.
- AreEqual(F().x, 42)
-
- # exception shouldn't propagate out
- for cls in [C, D, E, F]:
- AreEqual(getattr(cls(), 'xyz', 'DNE'), 'DNE')
- AreEqual(hasattr(cls(), 'xyz'), False)
-
-
- # removing & adding back on __getattribute__ should work
- class foo(object):
- def __getattribute__(self, name): return 42
- x = foo.__getattribute__
- del foo.__getattribute__
- AssertError(AttributeError, getattr, foo(), 'x')
- foo.__getattribute__ = x
- AreEqual(foo().x, 42)
- del foo.__getattribute__
- AssertError(AttributeError, getattr, foo(), 'x')
- # check getattr when the property raises
- class C(object):
- def throw(self):
- raise AttributeError
- foo = property(throw)
- AreEqual(getattr(C(), 'foo', 'abc'), 'abc')
- def count_elem(d,n):
- count = 0
- for e in d:
- if e == n:
- count += 1
- return count
- ############################################################
- def test_newstyle_oldstyle_dict():
- """Dictionary and new style classes"""
-
- class class_n(object):
- val1 = "Value"
- def __init__(self):
- self.val2 = self.val1
-
- inst_n = class_n()
- Assert(inst_n.val2 == "Value")
- Assert(not 'val2' in dir(class_n))
- Assert('val1' in dir(class_n))
- Assert('val2' in dir(inst_n))
- Assert('val1' in dir(inst_n))
- Assert('val2' in inst_n.__dict__)
- Assert(inst_n.__dict__['val2'] == "Value")
- Assert(count_elem(dir(inst_n), "val1") == 1)
- inst_n.val1 = 20
- Assert(count_elem(dir(inst_n), "val1") == 1)
- # old style classes:
-
- class class_o:
- val1 = "Value"
- def __init__(self):
- self.val2 = self.val1
-
- inst_o = class_o()
- Assert('val1' in dir(class_o))
- Assert(not 'val2' in dir(class_o))
- Assert('val1' in dir(inst_o))
- Assert('val2' in dir(inst_o))
- Assert('val2' in inst_o.__dict__)
- Assert(inst_o.__dict__['val2'] == "Value")
- Assert(count_elem(dir(inst_o), "val1") == 1)
- inst_n.val1 = 20
- Assert(count_elem(dir(inst_o), "val1") == 1)
- Assert(isinstance(class_o, object))
- Assert(isinstance(inst_o, object))
- Assert(isinstance(None, object))
- ############################################################
- def test_misc():
- class C:
- def x(self):
- return 'C.x'
- def y(self):
- return 'C.y'
-
- class D:
- def z(self):
- return 'D.z'
-
- c = C()
- AreEqual(c.x(), "C.x")
- AreEqual(c.y(), "C.y")
-
- # verify repr and str on old-style class objects have the right format:
-
- # bug# 795
- AreEqual(str(C), __name__+'.C')
- AreEqual(repr(C).index('<class '+__name__+'.C at 0x'), 0)
-
- success=0
- try:
- c.z()
- except AttributeError:
- success=1
- Assert(success==1)
-
- C.__bases__+=(D,)
-
- AreEqual(c.z(), "D.z")
- class C:
- def m(self):
- return "IronPython"
- def n(self, parm):
- return parm
-
- c = C()
-
- y = c.m
- y = c.n
- y = C.m
- y = C.n
- Assert('__dict__' not in str.__dict__)
- ############################################################
- def test_dir_in_init():
- # both of these shouldn't throw
-
- class DirInInit(object):
- def __init__(self):
- dir(self)
-
- a = DirInInit()
- ############################################################
- def test_priv_class():
- class _PrivClass(object):
- def __Mangled(self):
- pass
- def __init__(self):
- a = self.__Mangled
-
- a = _PrivClass()
- ############################################################
- def test_inheritance_attrs_dir():
- class foo:
- def foofunc(self):
- return "foofunc"
-
- class bar(foo):
- def barfunc(self):
- return "barfunc"
-
- class baz(foo, bar):
- def bazfunc(self):
- return "bazfunc"
-
- Assert('foofunc' in dir(foo))
- Assert(dir(foo).count('__doc__') == 1)
- Assert(dir(foo).count('__module__') == 1)
- Assert(len(dir(foo)) == 3)
- Assert('foofunc' in dir(bar))
- Assert('barfunc' in dir(bar))
- Assert(dir(bar).count('__doc__') == 1)
- Assert(dir(bar).count('__module__') == 1)
- Assert(len(dir(bar)) == 4)
- Assert('foofunc' in dir(baz))
- Assert('barfunc' in dir(baz))
- Assert('bazfunc' in dir(baz))
- Assert(dir(baz).count('__doc__') == 1)
- Assert(dir(baz).count('__module__') == 1)
- Assert(len(dir(baz)) == 5)
-
- bz = baz()
- Assert('foofunc' in dir(bz))
- Assert('barfunc' in dir(bz))
- Assert('bazfunc' in dir(bz))
- Assert(dir(bz).count('__doc__') == 1)
- Assert(dir(bz).count('__module__') == 1)
- Assert(len(dir(bz)) == 5)
-
- bz.__module__ = "MODULE"
- Assert(bz.__module__ == "MODULE")
- bz.__module__ = "SOMEOTHERMODULE"
- Assert(bz.__module__ == "SOMEOTHERMODULE")
- bz.__module__ = 33
- Assert(bz.__module__ == 33)
- bz.__module__ = [2, 3, 4]
- Assert(bz.__module__ == [2, 3 , 4])
- ############################################################
- def test_oldstyle_setattr():
- global called
- class C:
- def __setattr__(self, name, value):
- global called
- called = (self, name, value)
-
- a = C()
- a.abc = 'def'
- AreEqual(called, (a, 'abc', 'def'))
-
- del C.__setattr__
-
- a.qrt = 'abc'
-
- AreEqual(called, (a, 'abc', 'def'))
-
- def setattr(self, name, value):
- global called
- called = (self, name, value)
-
- C.__setattr__ = setattr
-
- a.qrt = 'abc'
-
- AreEqual(called, (a, 'qrt', 'abc'))
-
- ############################################################
- def test_oldstyle_getattr():
- """verify we don't access __getattr__ while creating an old
- style class."""
-
- class C:
- def __getattr__(self,name):
- return globals()[name]
-
- a = C()
- def test_oldstyle_eq():
- """old style __eq__ shouldn't call __cmp__"""
- class x: pass
-
- inst = type(x())
-
- global cmpCalled
- cmpCalled = False
- class C:
- def __init__(self, value):
- self.value = value
- def __cmp__(self, other):
- global cmpCalled
- cmpCalled = True
- return self.value - other.value
-
- class D:
- def __init__(self, value):
- self.value = value
- def __cmp__(self, other):
- global cmpCalled
- cmpCalled = True
- return self.value - other.value
-
-
- class C2(C): pass
-
- class D2(D): pass
-
-
- AreEqual(inst.__eq__(C(3.0), C(4.5)), NotImplemented)
- AreEqual(inst.__eq__(C(3.0), C2(4.5)), NotImplemented)
- AreEqual(inst.__eq__(C(3.0), D(4.5)), NotImplemented)
- AreEqual(cmpCalled, False)
- ############################################################
- def test_raise_attrerror():
- """raising AttributeError from __getattr__ should be ok,
- and shouldn't be seen by the user"""
-
- class A:
- def __getattr__(self, name):
- raise AttributeError, 'get outta here'
- def __repr__(self):
- return 'foo'
-
- class B:
- def __getattr__(self, name):
- raise AttributeError, 'get outta here'
- def __str__(self):
- return 'foo'
-
- AreEqual(str(A()), 'foo')
- AreEqual(repr(A()), 'foo')
- AreEqual(str(B()), 'foo')
- Assert(repr(B()).find('B instance') != -1)
- ############################################################
- # use exec to define methods on classes:
- def test_exec_namespace():
- class oldclasswithexec:
- exec "def oldexecmethod(self): return 'result of oldexecmethod'"
-
- Assert('oldexecmethod' in dir(oldclasswithexec))
- AreEqual(oldclasswithexec().oldexecmethod(), 'result of oldexecmethod')
-
- class newclasswithexec(object):
- exec "def newexecmethod(self): return 'result of newexecmethod'"
-
- Assert('newexecmethod' in dir(newclasswithexec))
- AreEqual(newclasswithexec().newexecmethod(), 'result of newexecmethod')
- ############################################################
- def test_module_name():
- global __name__
-
- mod = sys.modules[__name__]
- name = __name__
-
- mod.__name__ = None
-
- class C: pass
-
- AreEqual(C.__module__, None)
-
- def func1():
- __name__ = "wrong"
- class C: pass
- return C()
-
- def func2():
- class C: pass
- return C()
-
- def func3():
- global __name__
- __name__ = "right"
- class C: pass
- return C()
-
-
- AreEqual(func1().__module__, func2().__module__)
-
- __name__ = "fake"
- AreEqual(func1().__module__, "fake")
-
- AreEqual(func3().__module__, "right")
- mod.__name__ = name
-
- def f(x): x.__module__
- def g(x): getattr(x, '__module__')
- import errno
- for thing in "", 1, errno, 1L, 1+2j, (), [], {}:
- AreEqual(getattr(thing, '__module__', 'does_not_exist'), 'does_not_exist')
- AreEqual(hasattr(thing, '__module__'), False)
- AssertError(AttributeError, f, thing)
- AssertError(AttributeError, g, thing)
-
- AssertErrorWithMessage(TypeError, "can't set function.__module__", type(type(f)).__dict__['__module__'].__set__, type(f), 42)
-
- class x(object): pass
- type(type(x())).__dict__['__module__'].__set__(x, 'fooz')
- AreEqual(x.__module__, 'fooz')
-
- AssertErrorWithMessage(TypeError, "can't delete x.__module__", type(type(x())).__dict__['__module__'].__delete__, x)
- ############################################################
- def test_check_dictionary():
- """tests to verify that Symbol dictionaries do the right thing in dynamic scenarios"""
- def CheckDictionary(C):
- # add a new attribute to the type...
- C.newClassAttr = 'xyz'
- AreEqual(C.newClassAttr, 'xyz')
-
- # add non-string index into the class and instance dictionary
- a = C()
- a.__dict__[1] = '1'
- if object in C.__bases__:
- try:
- C.__dict__[2] = '2'
- AssertUnreachable()
- except TypeError: pass
- AreEqual(C.__dict__.has_key(2), False)
- AreEqual(a.__dict__.has_key(1), True)
- AreEqual(dir(a).__contains__(1), True)
- AreEqual(repr(a.__dict__), "{1: '1'}")
-
- # replace a class dictionary (containing non-string keys) w/ a normal dictionary
- C.newTypeAttr = 1
- AreEqual(hasattr(C, 'newTypeAttr'), True)
-
- class OldClass: pass
-
- if isinstance(C, type(OldClass)):
- C.__dict__ = dict(C.__dict__)
- AreEqual(hasattr(C, 'newTypeAttr'), True)
- else:
- try:
- C.__dict__ = {}
- AssertUnreachable()
- except AttributeError:
- pass
-
- # replace an instance dictionary (containing non-string keys) w/ a new one.
- a.newInstanceAttr = 1
- AreEqual(hasattr(a, 'newInstanceAttr'), True)
- a.__dict__ = dict(a.__dict__)
- AreEqual(hasattr(a, 'newInstanceAttr'), True)
-
- a.abc = 'xyz'
- AreEqual(hasattr(a, 'abc'), True)
- AreEqual(getattr(a, 'abc'), 'xyz')
-
-
- class OldClass:
- def __init__(self): pass
-
- class NewClass(object):
- def __init__(self): pass
-
- CheckDictionary(OldClass)
- CheckDictionary(NewClass)
- ############################################################
- def test_call_type_call():
- for stuff in [object, int, str, bool, float]:
- AreEqual(type(type.__call__(stuff)), stuff)
-
- AreEqual(type.__call__(int, 5), 5)
- AreEqual(type.__call__(int), 0)
-
- AreEqual(type.__call__(bool, True), True)
- AreEqual(type.__call__(bool), False)
-
- #User-defined old/new style classes
- call_mapper = {}
-
- class KOld0:
- def __call__(self):
- return 2
- call_mapper[KOld0] = lambda: [type(KOld0()).__call__(KOld0())]
-
- class KOld1:
- def __call__(self, p):
- return 2
- call_mapper[KOld1] = lambda: [type(KOld1()).__call__(KOld1(), 3.14),
- type(KOld1()).__call__(KOld1(), p=3.14),
- type(KOld1()).__call__(KOld1(), **{"p":3.14}),
- type(KOld1()).__call__(KOld1(), (1, 2, 3)) ]
-
- class KOldArgs:
- def __call__(self, *args):
- return 2
- call_mapper[KOldArgs] = lambda: [type(KOldArgs()).__call__(KOldArgs())]
-
- class KOldKwargs:
- def __call__(self, **kwargs):
- return 2
- call_mapper[KOldKwargs] = lambda: [type(KOldKwargs()).__call__(KOldKwargs())]
-
- class KOldArgsKwargs:
- def __call__(self, *args, **kwargs):
- return 2
- call_mapper[KOldArgsKwargs] = lambda: [type(KOldArgsKwargs()).__call__(KOldArgsKwargs())]
-
-
-
- class KNew0(object):
- def __call__(self):
- return 2
- call_mapper[KNew0] = lambda: [type(KNew0()).__call__(KNew0())]
-
- class KNew1(object):
- def __call__(self, p):
- return 2
- call_mapper[KNew1] = lambda: [type(KNew1()).__call__(KNew1(), 3.14),
- type(KNew1()).__call__(KNew1(), p=3.14),
- type(KNew1()).__call__(KNew1(), **{"p":3.14}),
- type(KNew1()).__call__(KNew1(), []),
- ]
-
- class KNewArgs(object):
- def __call__(self, *args):
- return 2
- call_mapper[KNewArgs] = lambda: [type(KNewArgs()).__call__(KNewArgs()) ]
-
- class KNewKwargs(object):
- def __call__(self, **kwargs):
- return 2
- call_mapper[KNewKwargs] = lambda: [type(KNewKwargs()).__call__(KNewKwargs())]
-
- class KNewArgsKwargs(object):
- def __call__(self, *args, **kwargs):
- return 2
- call_mapper[KNewArgsKwargs] = lambda: [type(KNewArgsKwargs()).__call__(KNewArgsKwargs())]
-
- for K in call_mapper.keys():
- for ret_val in call_mapper[K]():
- AreEqual(ret_val, 2)
- def test_cp8246():
-
- #...
- class K(object):
- def __call__(self):
- return ((), {})
- AreEqual(K()(), ((), {}))
-
- #...
- class K(object):
- def __call__(self, **kwargs):
- return ((), kwargs)
- AreEqual(K()(), ((), {}))
- AreEqual(K()(**{}), ((), {}))
- AreEqual(K()(**{'a':None}), ((), {'a':None}))
-
- #...
- class K(object):
- def __call__(self, *args):
- return (args, {})
- AreEqual(K()(), ((), {}))
- AreEqual(K()(*()), ((), {}))
- AreEqual(K()(*(None,)), ((None,), {}))
-
- #...
- class K(object):
- def __call__(self, *args, **kwargs):
- return (args, kwargs)
- AreEqual(K()(), ((), {}))
- AreEqual(K()(*()), ((), {}))
- AreEqual(K()(**{}), ((), {}))
- AreEqual(K()(*(), **{}), ((), {}))
- AreEqual(K()(*(None,)), ((None,), {}))
- AreEqual(K()(**{'a':None}), ((), {'a':None}))
- AreEqual(K()(*(None,), **{'a':None}), ((None,), {'a':None}))
-
-
- ############################################################
- def test_mixed_inheritance():
- """inheritance from both old & new style classes..."""
- class foo: pass
-
- class bar(object): pass
-
- class baz1(foo, bar): pass
-
- class baz2(bar, foo): pass
-
- AreEqual(baz1.__bases__, (foo, bar))
- AreEqual(baz2.__bases__, (bar, foo))
-
- class foo:
- abc = 3
-
- class bar(object):
- def get_abc():
- return 42
- def set_abc():
- pass
-
- abc = property(fget=get_abc, fset=set_abc)
-
- class baz(foo, bar): pass
-
- AreEqual(baz().abc, 3)
- ############################################################
- def test_newstyle_unbound_inheritance():
- """verify calling unbound method w/ new-style class on subclass which
- new-style also inherits from works."""
- class foo:
- def func(self): return self
-
- class bar(object, foo):
- def barfunc(self):
- return foo.func(self)
-
- a = bar()
- AreEqual(a.barfunc(), a)
- ############################################################
- def test_mro():
- """mro (method resolution order) support"""
- class A(object): pass
-
- AreEqual(A.__mro__, (A, object))
-
- class B(object): pass
-
- AreEqual(B.__mro__, (B, object))
-
- class C(B): pass
-
- AreEqual(C.__mro__, (C, B, object))
-
- class N(C,B,A): pass
-
- AreEqual(N.__mro__, (N, C, B, A, object))
-
- try:
- class N(A, B,C): pass
- AssertUnreachable("impossible MRO created")
- except TypeError:
- pass
-
- try:
- class N(A, A): pass
- AssertUnreachable("can't dervie from the same base type twice")
- except TypeError:
- pass
- ############################################################
- def test_mro_bases():
- """verify replacing base classes also updates MRO"""
- class C(object):
- def __getattribute__(self, name):
- if(name == 'xyz'): return 'C'
- return super(C, self).__getattribute__(name)
-
- class C1(C):
- def __getattribute__(self, name):
- if(name == 'xyz'): return 'C1'
- return super(C1, self).__getattribute__(name)
-
- class A(object): pass
-
- class B(object):
- def __getattribute__(self, name):
- if(name == 'xyz'): return 'B'
- return super(B, self).__getattribute__(name)
-
- a = C1()
- AreEqual(a.xyz, 'C1')
-
- C1.__bases__ = (A,B)
- AreEqual(a.xyz, 'C1')
-
- del(C1.__getattribute__)
- AreEqual(a.xyz, 'B')
- ############################################################
- def test_dynamic_mro_bases():
- class C(object):
- pass
-
- def __getattribute__(self, name):
- if (name == 'xyz'):
- return 'C'
- return super(C, self).__getattribute__(name)
-
- C.__getattribute__ = __getattribute__
-
- class C1(C):
- pass
-
- def __getattribute__(self, name):
- if (name == 'xyz'):
- return 'C1'
- return super(C1, self).__getattribute__(name)
-
-
- C1.__getattribute__ = __getattribute__
-
-
- class B(object):
- pass
-
- def __getattribute__(self, name):
- if (name == 'xyz'):
- return 'B'
- return super(B, self).__getattribute__(name)
-
- B.__getattribute__ = __getattribute__
-
- C1.__bases__ = (B, )
- AreEqual(C1().xyz, 'C1')
-
- ############################################################
- def test_builtin_mro():
- """int mro shouldn't include ValueType"""
- AreEqual(int.__mro__, (int, object))
- ############################################################
- def test_mixed_inheritance_mro():
- """mixed inheritance from old-style & new-style classes"""
-
- # we should use old-style MRO when inheriting w/ a single old-style class
- class A: pass
-
- class B(A): pass
-
- class C(A): pass
-
- class D(B, C):pass
-
- class E(D, object): pass
-
- # old-style MRO of D is D, B, A, C, which should
- # be present in E's mro
- AreEqual(E.__mro__, (E, D, B, A, C, object))
-
- class F(B, C, object): pass
-
- # but when inheriting from multiple old-style classes we switch
- # to new-style MRO, and respect local ordering of classes in the MRO
- AreEqual(F.__mro__, (F, B, C, A, object))
-
- class G(B, object, C): pass
-
- AreEqual(G.__mro__, (G, B, object, C, A))
-
- class H(E): pass
-
- AreEqual(H.__mro__, (H, E, D, B, A, C, object))
-
- try:
- class H(A,B,E): pass
- AssertUnreachable()
- except TypeError:
- pass
-
-
- class H(E,B,A): pass
-
- AreEqual(H.__mro__, (H, E, D, B, A, C, object))
- ############################################################
- def test_depth_first_mro_mixed():
- """Verify given two large, independent class hierarchies
- that we favor them in the order listed.
-
- w/ old-style
- """
-
- class A: pass
-
- class B(A): pass
-
- class C(A): pass
-
- class D(B,C): pass
-
- class E(D, object): pass
-
- class G: pass
-
- class H(G): pass
-
- class I(G): pass
-
- class K(H,I, object): pass
-
- class L(K,E): pass
-
- AreEqual(L.__mro__, (L, K, H, I, G, E, D, B, A, C, object))
- ############################################################
- def test_depth_first_mro():
- """w/o old-style"""
-
- class A(object): pass
-
- class B(A): pass
-
- class C(A): pass
-
- class D(B,C): pass
-
- class E(D, object): pass
-
- class G(object): pass
-
- class H(G): pass
-
- class I(G): pass
-
- class K(H,I, object): pass
-
- class L(K,E): pass
-
- AreEqual(L.__mro__, (L, K, H, I, G, E, D, B, C, A, object))
-
- ############################################################
- def test_newstyle_lookup():
- """new-style classes should only lookup methods from the class, not from the instance"""
- class Strange(object):
- def uselessMethod(self): pass
-
- global obj
- obj = Strange()
- obj.__nonzero__ = lambda: False
- AreEqual(bool(obj), True)
-
- def twoargs(self, other):
- global twoArgsCalled
- twoArgsCalled = True
- return self
-
- def onearg(self):
- return self
-
- def onearg_str(self):
- return 'abc'
-
- # create methods that we can then stick into Strange
- twoargs = type(Strange.uselessMethod)(twoargs, None, Strange)
- onearg = type(Strange.uselessMethod)(onearg, None, Strange)
- class ForwardAndReverseTests:
- testCases = [
- #forward versions
- ('__add__', 'obj + obj'),
- ('__sub__', 'obj - obj'),
- ('__mul__', 'obj * obj'),
- ('__floordiv__', 'obj // obj'),
- ('__mod__', 'obj % obj'),
- ('__divmod__', 'divmod(obj,obj)'),
- ('__pow__', 'pow(obj, obj)'),
- ('__lshift__', 'obj << obj'),
- ('__rshift__', 'obj >> obj'),
- ('__and__', 'obj & obj'),
- ('__xor__', 'obj ^ obj'),
- ('__or__', 'obj | obj'),
-
- # reverse versions
- ('__radd__', '1 + obj'),
- ('__rsub__', '1 - obj'),
- ('__rmul__', '1 * obj'),
- ('__rfloordiv__', '1 // obj'),
- ('__rmod__', '1 % obj'),
- #('__rdivmod__', '1 % obj'), #bug 975
- ('__rpow__', 'pow(1, obj)'),
- ('__rlshift__', '1 << obj'),
- ('__rrshift__', '1 >> obj'),
- ('__rand__', '1 & obj'),
- ('__rxor__', '1 ^ obj'),
- ('__ror__', '1 | obj'),
- ]
-
- @staticmethod
- def NegativeTest(method, testCase):
- setattr(obj, method, twoargs)
-
- try:
- eval(testCase)
- AssertUnreachable()
- except TypeError, e:
- pass
-
- delattr(obj, method)
-
- @staticmethod
- def PositiveTest(method, testCase):
- setattr(Strange, method, twoargs)
-
- AreEqual(eval(testCase), obj)
-
- delattr(Strange, method)
-
-
- class InPlaceTests:
- # in-place versions require exec instead of eval
- testCases = [
- # inplace versions
- ('__iadd__', 'obj += obj'),
- ('__isub__', 'obj -= obj'),
- ('__imul__', 'obj *= obj'),
- ('__ifloordiv__', 'obj //= obj'),
- ('__imod__', 'obj %= obj'),
- ('__ipow__', 'obj **= obj'),
- ('__ilshift__', 'obj <<= obj'),
- ('__irshift__', 'obj >>= obj'),
- ('__iand__', 'obj &= obj'),
- ('__ixor__', 'obj ^= obj'),
- ('__ior__', 'obj |= obj'),
- ]
-
- @staticmethod
- def NegativeTest(method, testCase):
- setattr(obj, method, twoargs)
-
- try:
- exec testCase in globals(), locals()
- AssertUnreachable()
- except TypeError:
- pass
-
- delattr(obj, method)
-
- @staticmethod
- def PositiveTest(method, testCase):
- setattr(Strange, method, twoargs)
-
- global twoArgsCalled
- twoArgsCalled = False
- exec testCase in globals(), locals()
- AreEqual(twoArgsCalled, True)
-
- delattr(Strange, method)
-
-
- class SingleArgTests:
- testCases = [
- # one-argument versions
- ('__neg__', '-obj'),
- ('__pos__', '+obj'),
- ('__abs__', 'abs(obj)'),
- ('__invert__', '~obj'),
- ]
-
- @staticmethod
- def NegativeTest(method, testCase):
- setattr(obj, method, onearg)
-
- try:
- eval(testCase)
- AssertUnreachable()
- except TypeError:
- pass
-
- delattr(obj, method)
-
- @staticmethod
- def PositiveTest(method, testCase):
- setattr(Strange, method, onearg)
- try:
- AreEqual(eval(testCase), obj)
- except TypeError:
- Assert(method == '__oct__' or method == '__hex__')
-
- delattr(Strange, method)
-
- class HexOctTests:
- testCases = [
- ('__oct__', 'oct(obj)'),
- ('__hex__', 'hex(obj)'),
- ]
- @staticmethod
- def NegativeTest(method, testCase):
- setattr(obj, method, onearg)
-
- try:
- eval(testCase)
- AssertUnreachable()
- except TypeError:
- pass
-
- delattr(obj, method)
-
- @staticmethod
- def PositiveTest(method, testCase):
- setattr(Strange, method, onearg_str)
- AreEqual(eval(testCase), 'abc')
-
- delattr(Strange, method)
- class ConversionTests:
- testCases = [
- (('__complex__', 2+0j), 'complex(obj)'),
- (('__int__', 1), 'int(obj)'),
- (('__long__', 1L), 'long(obj)'),
- (('__float__', 1.0), 'float(obj)'),
- ]
-
- @staticmethod
- def NegativeTest(method, testCase):
- setattr(obj, method[0], onearg)
-
- try:
- eval(testCase)
- AssertUnreachable()
- except (TypeError, ValueError), e:
- AreEqual(e.args[0].find('returned') == -1, True) # shouldn't have returned '__complex__ returned ...'
- delattr(obj, method[0])
-
- @staticmethod
- def PositiveTest(method, testCase):
- def testMethod(self):
- return method[1]
-
- testMethod = type(Strange.uselessMethod)(testMethod, None, Strange)
- setattr(Strange, method[0], testMethod)
-
- AreEqual(eval(testCase), method[1])
-
- delattr(Strange, method[0])
-
- allTests = [ForwardAndReverseTests, InPlaceTests, SingleArgTests, ConversionTests, HexOctTests]
-
- for test in allTests:
- for method,testCase in test.testCases:
- test.NegativeTest(method, testCase)
- for method,testCase in test.testCases:
- test.PositiveTest(method, testCase)
-
- #Verify that the base type's defined special operators get picked up.
- class DerivedStrange(Strange): pass
-
- obj = DerivedStrange()
- for test in allTests:
- for method,testCase in test.testCases:
- test.NegativeTest(method, testCase)
- for method,testCase in test.testCases:
- test.PositiveTest(method, testCase)
-
-
- def test_bad_repr():
- # overriding a classes __repr__ and returning a
- # non-string should throw
-
- class C:
- def __repr__(self):
- return None
-
- AssertError(TypeError, repr, C())
-
- class C(object):
- def __repr__(self):
- return None
-
- AssertError(TypeError, repr, C())
- ############################################################
- def test_name():
- """setting __name__ on a class should work"""
-
- class C(object): pass
-
- C.__name__ = 'abc'
- AreEqual(C.__name__, 'abc')
- ############################################################
- def test_mro_super():
- """super for multiple inheritance we should follow the MRO as we go up the super chain"""
- class F:
- def meth(self):
- return 'F'
-
- class G: pass
-
- def gmeth(self): return 'G'
-
-
- class A(object):
- def meth(self):
- if hasattr(super(A, self), 'meth'):
- return 'A' + super(A, self).meth()
- else:
- return "A"
-
- class B(A):
- def __init__(self):
- self.__super = super(B, self)
- super(B, self).__init__()
- def meth(self):
- return "B" + self.__super.meth()
-
- class C(A):
- def __init__(self):
- self.__super = super(C, self)
- super(C, self).__init__()
- def meth(self):
- return "C" + self.__super.meth()
-
- class D(C, B):
- def meth(self):
- return "D" + super(D, self).meth()
-
- AreEqual(D().meth(), 'DCBA')
-
- class D(C, F, B):
- def meth(self):
- return "D" + super(D, self).meth()
-
- AreEqual(D.__mro__, (D,C,F,B,A,object))
- AreEqual(D().meth(), 'DCF')
-
- class D(C, B, F):
- def meth(self):
- return "D" + super(D, self).meth()
-
- AreEqual(D.__mro__, (D,C,B,A,object,F))
- AreEqual(D().meth(), 'DCBAF')
-
-
- class D(C, B, G):
- def meth(self):
- return "D" + super(D, self).meth()
-
- d = D()
- d.meth = type(F.meth)(gmeth, d, G)
- AreEqual(d.meth(), 'G')
- ############################################################
- def test_slots():
- """slots tests"""
-
- # simple slots, assign, delete, etc...
-
- class foo(object):
- __slots__ = ['abc']
-
- class bar(object):
- __slots__ = 'abc'
-
- class baz(object):
- __slots__ = ('abc', )
-
- for slotType in [foo, bar, baz]:
- a = slotType()
- AssertError(AttributeError, lambda: a.abc)
- AreEqual(hasattr(a, 'abc'), False)
-
- a.abc = 'xyz'
- AreEqual(a.abc, 'xyz')
- AreEqual(hasattr(a, 'abc'), True)
- del(a.abc)
- AreEqual(hasattr(a, 'abc'), False)
- AssertError(AttributeError, lambda: a.abc)
-
- # slot classes don't have __dict__
- AreEqual(hasattr(a, '__dict__'), False)
- AssertError(AttributeError, lambda: a.__dict__)
-
- # sub-class of slots class, has no slots, has a __dict__
- class foo(object):
- __slots__ = 'abc'
- def __init__(self):
- self.abc = 23
-
- class bar(foo):
- def __init__(self):
- super(bar, self).__init__()
-
- a = bar()
- AreEqual(a.abc, 23)
-
- del(a.abc)
- AreEqual(hasattr(a, 'abc'), False)
- a.abc = 42
- AreEqual(a.abc, 42)
-
- x = a.__dict__
- AreEqual(x.has_key('abc'), False)
- a.xyz = 'abc'
- AreEqual(a.xyz, 'abc')
-
- # subclass of not-slots class defining slots:
-
- class A(object): pass
- class B(A): __slots__ = 'c'
-
- AreEqual(hasattr(B(), '__dict__'), True)
- AreEqual(hasattr(B, 'c'), True)
-
- # slots & metaclass
- if is_cli or is_silverlight: # INCOMPATBILE: __slots__ not supported for subtype of type
- class foo(type):
- __slots__ = ['abc']
-
- class bar(object):
- __metaclass__ = foo
-
- # complex slots
-
- class foo(object):
- __slots__ = ['abc']
- def __new__(cls, *args, **kw):
- self = object.__new__(cls)
- dict = object.__getattribute__(self, '__dict__')
- return self
-
- class bar(foo): pass
-
-
- a = bar()
-
- AssertError(AttributeError, foo)
-
- # slots & name-mangling
-
- class foo(object):
- __slots__ = '__bar'
-
- AreEqual(hasattr(foo, '_foo__bar'), True)
-
- # invalid __slots__ values
- for x in ['', None, '3.5']:
- try:
- class C(object):
- __slots__ = x
- AssertUnreachable()
- except TypeError:
- pass
-
- # including __dict__ in slots allows accessing __dict__
- class A(object): __slots__ = '__dict__'
-
- AreEqual(hasattr(A(),"__dict__"), True)
- a = A()
- a.abc = 'xyz'
- AreEqual(a.abc, 'xyz')
-
- class B(A): pass
- AreEqual(hasattr(B(),"__dict__"), True)
- b = A()
- b.abc = 'xyz'
- AreEqual(b.abc, 'xyz')
-
- # including __weakref__ explicitly
- class A(object):
- __slots__ = ["__weakref__"]
-
- hasattr(A(), "__weakref__")
-
- class B(A): pass
-
- hasattr(B(), "__weakref__")
-
- # weird case, including __weakref__ and __dict__ and we allow
- # a subtype to inherit from both
- if is_cli or is_silverlight: types = [object, dict, tuple] # INCOMPATBILE: __slots__ not supported for tuple
- else: types = [object,dict]
-
- for x in types:
- class A(x):
- __slots__ = ["__dict__"]
-
- class B(x):
- __slots__ = ["__weakref__"]
-
- class C(A,B):
- __slots__ = []
-
- a = C()
- AreEqual(hasattr(a, '__dict__'), True)
- AreEqual(hasattr(a, '__weakref__'), True)
-
- class C(A,B):
- __slots__ = ['xyz']
-
- a = C()
- AreEqual(hasattr(a, '__dict__'), True)
- AreEqual(hasattr(a, '__weakref__'), True)
- AreEqual(hasattr(C, 'xyz'), True)
-
- # calling w/ keyword args
-
- class foo(object):
- __slots__ = ['a', 'b']
- def __new__(cls, one='a', two='b'):
- self = object.__new__(cls)
- self.a = one
- self.b = two
- return self
-
- a = foo('x', two='y')
- AreEqual(a.a, 'x')
- AreEqual(a.b, 'y')
-
- # assign to __dict__
-
- class C(object): pass
-
- a = C()
- a.__dict__ = {'b':1}
- AreEqual(a.b, 1)
-
-
- # base, child define slots, grand-child doesn't
-
- class foo(object): __slots__ = ['fooSlot']
-
- class bar(foo): __slots__ = ['barSlot']
-
- class baz(bar): pass # shouldn't throw
-
- a = baz()
- a.barSlot = 'xyz'
- a.fooSlot = 'bar'
- a.dictEntry = 'foo'
-
- AreEqual(a.barSlot, 'xyz')
- AreEqual(a.fooSlot, 'bar')
- AreEqual(a.dictEntry, 'foo')
-
- # large number of slots works (nested tuple slots)
- class foo(object):
- __slots__ = [ 'a' + str(x) for x in range(256) ]
-
- a = foo()
-
- for x in range(256):
- setattr(a, 'a' + str(x), x)
-
- for x in range(256):
- AreEqual(x, getattr(a, 'a' + str(x)))
- # new-style / old-style mixed with slots, slots take precedence
- class foo:
- abc = 3
- class bar(object):
- __slots__ = ['abc']
- def __init__(self): self.abc = 5
- class bar2(object):
- abc = 5
- class baz(foo, bar): pass
-
- class baz2(foo, bar2): pass
- AreEqual(baz().abc, 5)
-
- # but if it's just a class member we respect MRO
- AreEqual(baz2().abc, 3)
-
- # getattr and __slots__ should mix well
- class Foo(object):
- __slots__ = ['bar']
- def __getattr__(self, name):
- return name.upper()
-
- AreEqual(Foo().bar, 'BAR')
-
- # slot takes precedence over dictionary member
- class Foo(object):
- __slots__ = ['bar', '__dict__']
- a = Foo()
- a.__dict__['bar'] = 'abc'
- AssertError(AttributeError, lambda : a.bar)
- # members defined the class take precedence over slots
- global initCalled
- class Foo(object):
- __slots__ = ["__init__"]
- def __init__(self):
- global initCalled
- initCalled = True
-
- initCalled = False
- a = Foo()
- AreEqual(initCalled, True)
-
- # the member is readonly because the member slot is gone.
- def f(): a.__init__ = 'abc'
- AssertError(AttributeError, f)
-
- # make sure __init__ isn't special
- class Foo(object):
- __slots__ = ["abc"]
- abc = 3
-
- a = Foo()
- AreEqual(a.abc, 3)
-
- def f(): a.abc = 'abc'
- AssertError(AttributeError, f)
- class Foo(object): __slots__ = 'abc'
-
- AreEqual(repr(Foo.abc), "<member 'abc' of 'Foo' objects>")
- AreEqual(str(Foo.abc), "<member 'abc' of 'Foo' objects>")
- AssertErrorWithPartialMessage(AttributeError, 'abc', lambda: Foo().abc)
-
- # again w/ empty __slots__ in C1 (409720)
- class C1(object):
- __slots__ = []
- class C2(object):
- __slots__ = ['a']
-
- class D1(C1, C2): pass
-
- # name mangling, slots, and classes which start with __
- class __NameStartsWithUnderscore(object):
- __slots__ = [ '__a' ]
- def __init__(self): self.__a = 'a'
- def geta(self): return self.__a
-
- s = __NameStartsWithUnderscore()
- AreEqual(s.geta(), 'a')
-
- def test_slots11457():
- class COld:
- __slots__ = ['a']
- class CNew(object):
- __slots__ = ['a']
-
- for C in [COld, CNew]:
- for i in xrange(2):
- setattr(C, 'a', 5)
- AreEqual(C().a, 5)
-
- setattr(C, 'a', 7)
- AreEqual(C().a, 7)
-
- ############################################################
- def test_inheritance_cycle():
- """test for inheritance cycle"""
- class CycleA: pass
- class CycleB: pass
-
- try:
- CycleA.__bases__ = (CycleA,)
- AssertUnreachable()
- except TypeError: pass
-
- try:
- CycleA.__bases__ = (CycleB,)
- CycleB.__bases__ = (CycleA,)
- AssertUnreachable()
- except TypeError: pass
- ############################################################
- def test_hexoct():
- """returning non-string from hex & oct should throw"""
-
- class foo(object):
- def __hex__(self): return self
- def __oct__(self): return self
-
- class bar:
- def __hex__(self): return self
- def __oct__(self): return self
-
- AssertError(TypeError, hex, foo())
- AssertError(TypeError, oct, foo())
- AssertError(TypeError, hex, bar())
- AssertError(TypeError, oct, bar())
- @skip("multiple_execute")
- def test_no_clr_attributes():
- """verify types have no CLR attributes"""
- # list,
- class x: pass
-
- for stuff in [object, int, float, bool, str, long, complex, dict, set,
- None, NotImplemented, Ellipsis, type(test_no_clr_attributes),
- classmethod, staticmethod, frozenset, property, sys,
- BaseException, type(zip), slice, buffer, enumerate, file,
- range, xrange, type(x), type(x())]:
- for dir_stuff in dir(stuff):
- if dir_stuff[:1].isalpha():
- Assert(dir_stuff[:1].islower(),
- "%s should not be an attribute of %s" % (dir_stuff, str(stuff)))
- def test_method_correct_name():
- # __str__ is an InstanceOps method (ToStringMethod), but we should
- # report the proper name in __str__
- Assert(repr(BaseException.__str__).find('__str__') != -1)
- @skip("multiple_execute")
- def test_no_clr_attributes_sanity():
- AreEqual(hasattr(int, 'MaxValue'), False)
- AreEqual(hasattr(int, 'MinValue'), False)
- AreEqual(hasattr(int, 'Abs'), False)
- AreEqual(hasattr(int, 'BitwiseOr'), False)
- AreEqual(hasattr(int, 'Equals'), False)
-
- AreEqual(hasattr(str, 'Empty'), False)
- AreEqual(hasattr(str, 'Compare'), False)
- AreEqual(hasattr(str, 'Equals'), False)
- AreEqual(hasattr(str, 'IndexOf'), False)
- ############################################################
- def test_outer_scope():
- """do not automatically include outer scopes in closure scenarios"""
- def outer_scope_test():
- class Referenced:
- pass
- class C:
- if Referenced: pass
- Assert("Referenced" not in C.__dict__.keys())
-
- outer_scope_test()
-
-
- for x in [None, 'abc', 3]:
- class foo(object): pass
- a = foo()
- try:
- a.__dict__ = x
- AssertUnreachable()
- except TypeError: pass
- def test_default_new_init():
- """test cases to verify we do the right thing for the default new & init
- methods"""
- anyInitList = [
- int,
- long,
- float,
- complex,
- tuple,
- ]
- anyNewList = [list, # classes that take any set of args to __new__
- set,
- ]
-
- AssertError(TypeError, object().__init__, 1, 2, 3)
- for x in anyInitList:
- x().__init__(1, 2, 3)
-
- AssertError(TypeError, x.__new__, x, 1, 2, 3)
- AreEqual(isinstance(x.__new__(x), x), True)
-
- for x in anyNewList:
- AreEqual(len(x.__new__(x, 1, 2, 3)), 0)
- AssertError(TypeError, x.__new__(x).__init__, 1, 2, 3)
-
- class foo(object): pass
-
- AssertError(TypeError, foo, 1)
-
- class foo(list): pass
- AreEqual(list.__new__(list, sequence='abc'), [])
-
- x = list.__new__(foo, 1, 2, 3)
- AreEqual(len(x), 0)
- AreEqual(type(x), foo)
-
-
- # define only __init__. __new__ should be the same object
- # for both types, and calling it w/ different types should have
- # different responses.
- class foo(object):
- def __init__(self): pass
-
- AreEqual(id(foo.__new__), id(object.__new__))
-
- AssertError(TypeError, object.__new__, object, 1,2,3)
- AreEqual(type(object.__new__(foo, 1, 2, 3)), foo)
- # inheritance / mutating class hierarchy tests
-
- # overrides __new__ w/ object.__new__
- class x(object):
- __new__ = object.__new__
- AssertError(TypeError, x().__init__, 2)
- # inherits __new__, overrides w/ default __new__
- class x(object):
- def __new__(cls, *args):
- return object.__new__(cls)
-
- class y(x):
- __new__ = object.__new__
-
- AreEqual(y().__init__(2), None)
-
- # then deletes the base __new__
- del x.__new__
- AreEqual(y().__init__(2), None)
-
- # then deletes y.__new__
- del y.__new__
- AreEqual(y().__init__(2), None)
- # dynamically add __new__
- class x(object): pass
-
- x.__new__ = staticmethod(lambda cls : object.__new__(x))
-
- AreEqual(x().__init__(2), None)
-
- # __init__ versions
- # overrides __init__ w/ object.__init__
- class x(object):
- __init__ = object.__init__
- AssertError(TypeError, x, 2)
- # inherits __init__, overrides w/ default __init__
- class x(object):
- def __init__(cls, *args):
- return object.__init__(cls)
-
- class y(x):
- __init__ = object.__init__
-
- AssertError(TypeError, y, 2)
-
- # then deletes the base __init__
- del x.__init__
- AssertError(TypeError, y, 2)
-
- # then deletes y.__init__
- del y.__init__
- AssertError(TypeError, y, 2)
- # dynamically add __init__
- class x(object): pass
-
- x.__init__ = staticmethod(lambda cls : object.__init__(x))
-
- x(2)
-
- # switching bases doesn't change it either
- class x(object):
- def __new__(cls, *args):
- return object.__new__(cls)
-
- class z(object): pass
-
- class y(x):
- pass
-
- AreEqual(y().__init__(2), None)
- y.__bases__ = (z, )
- AreEqual(y().__init__(2), None)
- def test_hash():
- for x in [tuple, str, unicode, object, frozenset]:
- inst = x()
- AreEqual(inst.__hash__(), hash(inst))
-
- # old style hash can return longs, the result of which is
- # the hash of the long
- class foo:
- def __hash__(self): return 1<<35L
- if not is_net40: #http://ironpython.codeplex.com/WorkItem/View.aspx?WorkItemId=24550
- AreEqual(hash(foo()), 8)
- def test_NoneSelf():
- try:
- set.add(None)
- AssertUnreachable()
- except TypeError:
- pass
- def test_builtin_classmethod():
- descr = dict.__dict__["fromkeys"]
- AssertError(TypeError, descr.__get__, 42)
- AssertError(TypeError, descr.__get__, None, 42)
- AssertError(TypeError, descr.__get__, None, int)
- def test_classmethod():
- if is_ironpython: #http://ironpython.codeplex.com/workitem/27908
- AssertError(TypeError, classmethod, 1)
- else:
- cm = classmethod(1)
- AssertError(TypeError, cm.__get__, None)
- AssertError(TypeError, cm.__get__, None, None)
- def foo…
Large files files are truncated, but you can click here to view the full file