PageRenderTime 106ms CodeModel.GetById 10ms app.highlight 78ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_descr.py

http://unladen-swallow.googlecode.com/
Python | 4425 lines | 4040 code | 242 blank | 143 comment | 149 complexity | 154a82e1036326d97a17bd58f1abf836 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1import __builtin__
   2import sys
   3import types
   4import unittest
   5import warnings
   6
   7from copy import deepcopy
   8from test import test_support
   9
  10
  11class OperatorsTest(unittest.TestCase):
  12
  13    def __init__(self, *args, **kwargs):
  14        unittest.TestCase.__init__(self, *args, **kwargs)
  15        self.binops = {
  16            'add': '+',
  17            'sub': '-',
  18            'mul': '*',
  19            'div': '/',
  20            'divmod': 'divmod',
  21            'pow': '**',
  22            'lshift': '<<',
  23            'rshift': '>>',
  24            'and': '&',
  25            'xor': '^',
  26            'or': '|',
  27            'cmp': 'cmp',
  28            'lt': '<',
  29            'le': '<=',
  30            'eq': '==',
  31            'ne': '!=',
  32            'gt': '>',
  33            'ge': '>=',
  34        }
  35
  36        for name, expr in self.binops.items():
  37            if expr.islower():
  38                expr = expr + "(a, b)"
  39            else:
  40                expr = 'a %s b' % expr
  41            self.binops[name] = expr
  42
  43        self.unops = {
  44            'pos': '+',
  45            'neg': '-',
  46            'abs': 'abs',
  47            'invert': '~',
  48            'int': 'int',
  49            'long': 'long',
  50            'float': 'float',
  51            'oct': 'oct',
  52            'hex': 'hex',
  53        }
  54
  55        for name, expr in self.unops.items():
  56            if expr.islower():
  57                expr = expr + "(a)"
  58            else:
  59                expr = '%s a' % expr
  60            self.unops[name] = expr
  61
  62    def setUp(self):
  63        self.original_filters = warnings.filters[:]
  64        warnings.filterwarnings("ignore",
  65                 r'complex divmod\(\), // and % are deprecated$',
  66                 DeprecationWarning, r'(<string>|%s)$' % __name__)
  67
  68    def tearDown(self):
  69        warnings.filters = self.original_filters
  70
  71    def unop_test(self, a, res, expr="len(a)", meth="__len__"):
  72        d = {'a': a}
  73        self.assertEqual(eval(expr, d), res)
  74        t = type(a)
  75        m = getattr(t, meth)
  76
  77        # Find method in parent class
  78        while meth not in t.__dict__:
  79            t = t.__bases__[0]
  80
  81        self.assertEqual(m, t.__dict__[meth])
  82        self.assertEqual(m(a), res)
  83        bm = getattr(a, meth)
  84        self.assertEqual(bm(), res)
  85
  86    def binop_test(self, a, b, res, expr="a+b", meth="__add__"):
  87        d = {'a': a, 'b': b}
  88
  89        # XXX Hack so this passes before 2.3 when -Qnew is specified.
  90        if meth == "__div__" and 1/2 == 0.5:
  91            meth = "__truediv__"
  92
  93        if meth == '__divmod__': pass
  94
  95        self.assertEqual(eval(expr, d), res)
  96        t = type(a)
  97        m = getattr(t, meth)
  98        while meth not in t.__dict__:
  99            t = t.__bases__[0]
 100        self.assertEqual(m, t.__dict__[meth])
 101        self.assertEqual(m(a, b), res)
 102        bm = getattr(a, meth)
 103        self.assertEqual(bm(b), res)
 104
 105    def ternop_test(self, a, b, c, res, expr="a[b:c]", meth="__getslice__"):
 106        d = {'a': a, 'b': b, 'c': c}
 107        self.assertEqual(eval(expr, d), res)
 108        t = type(a)
 109        m = getattr(t, meth)
 110        while meth not in t.__dict__:
 111            t = t.__bases__[0]
 112        self.assertEqual(m, t.__dict__[meth])
 113        self.assertEqual(m(a, b, c), res)
 114        bm = getattr(a, meth)
 115        self.assertEqual(bm(b, c), res)
 116
 117    def setop_test(self, a, b, res, stmt="a+=b", meth="__iadd__"):
 118        d = {'a': deepcopy(a), 'b': b}
 119        exec stmt in d
 120        self.assertEqual(d['a'], res)
 121        t = type(a)
 122        m = getattr(t, meth)
 123        while meth not in t.__dict__:
 124            t = t.__bases__[0]
 125        self.assertEqual(m, t.__dict__[meth])
 126        d['a'] = deepcopy(a)
 127        m(d['a'], b)
 128        self.assertEqual(d['a'], res)
 129        d['a'] = deepcopy(a)
 130        bm = getattr(d['a'], meth)
 131        bm(b)
 132        self.assertEqual(d['a'], res)
 133
 134    def set2op_test(self, a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
 135        d = {'a': deepcopy(a), 'b': b, 'c': c}
 136        exec stmt in d
 137        self.assertEqual(d['a'], res)
 138        t = type(a)
 139        m = getattr(t, meth)
 140        while meth not in t.__dict__:
 141            t = t.__bases__[0]
 142        self.assertEqual(m, t.__dict__[meth])
 143        d['a'] = deepcopy(a)
 144        m(d['a'], b, c)
 145        self.assertEqual(d['a'], res)
 146        d['a'] = deepcopy(a)
 147        bm = getattr(d['a'], meth)
 148        bm(b, c)
 149        self.assertEqual(d['a'], res)
 150
 151    def set3op_test(self, a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
 152        dictionary = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
 153        exec stmt in dictionary
 154        self.assertEqual(dictionary['a'], res)
 155        t = type(a)
 156        while meth not in t.__dict__:
 157            t = t.__bases__[0]
 158        m = getattr(t, meth)
 159        self.assertEqual(m, t.__dict__[meth])
 160        dictionary['a'] = deepcopy(a)
 161        m(dictionary['a'], b, c, d)
 162        self.assertEqual(dictionary['a'], res)
 163        dictionary['a'] = deepcopy(a)
 164        bm = getattr(dictionary['a'], meth)
 165        bm(b, c, d)
 166        self.assertEqual(dictionary['a'], res)
 167
 168    def test_lists(self):
 169        # Testing list operations...
 170        # Asserts are within individual test methods
 171        self.binop_test([1], [2], [1,2], "a+b", "__add__")
 172        self.binop_test([1,2,3], 2, 1, "b in a", "__contains__")
 173        self.binop_test([1,2,3], 4, 0, "b in a", "__contains__")
 174        self.binop_test([1,2,3], 1, 2, "a[b]", "__getitem__")
 175        self.ternop_test([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
 176        self.setop_test([1], [2], [1,2], "a+=b", "__iadd__")
 177        self.setop_test([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
 178        self.unop_test([1,2,3], 3, "len(a)", "__len__")
 179        self.binop_test([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
 180        self.binop_test([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
 181        self.set2op_test([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
 182        self.set3op_test([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d",
 183                        "__setslice__")
 184
 185    def test_dicts(self):
 186        # Testing dict operations...
 187        self.binop_test({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
 188        self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__")
 189        self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__")
 190        self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
 191
 192        d = {1:2, 3:4}
 193        l1 = []
 194        for i in d.keys():
 195            l1.append(i)
 196        l = []
 197        for i in iter(d):
 198            l.append(i)
 199        self.assertEqual(l, l1)
 200        l = []
 201        for i in d.__iter__():
 202            l.append(i)
 203        self.assertEqual(l, l1)
 204        l = []
 205        for i in dict.__iter__(d):
 206            l.append(i)
 207        self.assertEqual(l, l1)
 208        d = {1:2, 3:4}
 209        self.unop_test(d, 2, "len(a)", "__len__")
 210        self.assertEqual(eval(repr(d), {}), d)
 211        self.assertEqual(eval(d.__repr__(), {}), d)
 212        self.set2op_test({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c",
 213                        "__setitem__")
 214
 215    # Tests for unary and binary operators
 216    def number_operators(self, a, b, skip=[]):
 217        dict = {'a': a, 'b': b}
 218
 219        for name, expr in self.binops.items():
 220            if name not in skip:
 221                name = "__%s__" % name
 222                if hasattr(a, name):
 223                    res = eval(expr, dict)
 224                    self.binop_test(a, b, res, expr, name)
 225
 226        for name, expr in self.unops.items():
 227            if name not in skip:
 228                name = "__%s__" % name
 229                if hasattr(a, name):
 230                    res = eval(expr, dict)
 231                    self.unop_test(a, res, expr, name)
 232
 233    def test_ints(self):
 234        # Testing int operations...
 235        self.number_operators(100, 3)
 236        # The following crashes in Python 2.2
 237        self.assertEqual((1).__nonzero__(), 1)
 238        self.assertEqual((0).__nonzero__(), 0)
 239        # This returns 'NotImplemented' in Python 2.2
 240        class C(int):
 241            def __add__(self, other):
 242                return NotImplemented
 243        self.assertEqual(C(5L), 5)
 244        try:
 245            C() + ""
 246        except TypeError:
 247            pass
 248        else:
 249            self.fail("NotImplemented should have caused TypeError")
 250        import sys
 251        try:
 252            C(sys.maxint+1)
 253        except OverflowError:
 254            pass
 255        else:
 256            self.fail("should have raised OverflowError")
 257
 258    def test_longs(self):
 259        # Testing long operations...
 260        self.number_operators(100L, 3L)
 261
 262    def test_floats(self):
 263        # Testing float operations...
 264        self.number_operators(100.0, 3.0)
 265
 266    def test_complexes(self):
 267        # Testing complex operations...
 268        self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge',
 269                                                  'int', 'long', 'float'])
 270
 271        class Number(complex):
 272            __slots__ = ['prec']
 273            def __new__(cls, *args, **kwds):
 274                result = complex.__new__(cls, *args)
 275                result.prec = kwds.get('prec', 12)
 276                return result
 277            def __repr__(self):
 278                prec = self.prec
 279                if self.imag == 0.0:
 280                    return "%.*g" % (prec, self.real)
 281                if self.real == 0.0:
 282                    return "%.*gj" % (prec, self.imag)
 283                return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
 284            __str__ = __repr__
 285
 286        a = Number(3.14, prec=6)
 287        self.assertEqual(repr(a), "3.14")
 288        self.assertEqual(a.prec, 6)
 289
 290        a = Number(a, prec=2)
 291        self.assertEqual(repr(a), "3.1")
 292        self.assertEqual(a.prec, 2)
 293
 294        a = Number(234.5)
 295        self.assertEqual(repr(a), "234.5")
 296        self.assertEqual(a.prec, 12)
 297
 298    def test_spam_lists(self):
 299        # Testing spamlist operations...
 300        import copy, xxsubtype as spam
 301
 302        def spamlist(l, memo=None):
 303            import xxsubtype as spam
 304            return spam.spamlist(l)
 305
 306        # This is an ugly hack:
 307        copy._deepcopy_dispatch[spam.spamlist] = spamlist
 308
 309        self.binop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b",
 310                       "__add__")
 311        self.binop_test(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
 312        self.binop_test(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
 313        self.binop_test(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
 314        self.ternop_test(spamlist([1,2,3]), 0, 2, spamlist([1,2]), "a[b:c]",
 315                        "__getslice__")
 316        self.setop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+=b",
 317                       "__iadd__")
 318        self.setop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b",
 319                       "__imul__")
 320        self.unop_test(spamlist([1,2,3]), 3, "len(a)", "__len__")
 321        self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b",
 322                       "__mul__")
 323        self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a",
 324                       "__rmul__")
 325        self.set2op_test(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c",
 326                        "__setitem__")
 327        self.set3op_test(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
 328                   spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
 329        # Test subclassing
 330        class C(spam.spamlist):
 331            def foo(self): return 1
 332        a = C()
 333        self.assertEqual(a, [])
 334        self.assertEqual(a.foo(), 1)
 335        a.append(100)
 336        self.assertEqual(a, [100])
 337        self.assertEqual(a.getstate(), 0)
 338        a.setstate(42)
 339        self.assertEqual(a.getstate(), 42)
 340
 341    def test_spam_dicts(self):
 342        # Testing spamdict operations...
 343        import copy, xxsubtype as spam
 344        def spamdict(d, memo=None):
 345            import xxsubtype as spam
 346            sd = spam.spamdict()
 347            for k, v in d.items():
 348                sd[k] = v
 349            return sd
 350        # This is an ugly hack:
 351        copy._deepcopy_dispatch[spam.spamdict] = spamdict
 352
 353        self.binop_test(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)",
 354                       "__cmp__")
 355        self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
 356        self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
 357        self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
 358        d = spamdict({1:2,3:4})
 359        l1 = []
 360        for i in d.keys():
 361            l1.append(i)
 362        l = []
 363        for i in iter(d):
 364            l.append(i)
 365        self.assertEqual(l, l1)
 366        l = []
 367        for i in d.__iter__():
 368            l.append(i)
 369        self.assertEqual(l, l1)
 370        l = []
 371        for i in type(spamdict({})).__iter__(d):
 372            l.append(i)
 373        self.assertEqual(l, l1)
 374        straightd = {1:2, 3:4}
 375        spamd = spamdict(straightd)
 376        self.unop_test(spamd, 2, "len(a)", "__len__")
 377        self.unop_test(spamd, repr(straightd), "repr(a)", "__repr__")
 378        self.set2op_test(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
 379                   "a[b]=c", "__setitem__")
 380        # Test subclassing
 381        class C(spam.spamdict):
 382            def foo(self): return 1
 383        a = C()
 384        self.assertEqual(a.items(), [])
 385        self.assertEqual(a.foo(), 1)
 386        a['foo'] = 'bar'
 387        self.assertEqual(a.items(), [('foo', 'bar')])
 388        self.assertEqual(a.getstate(), 0)
 389        a.setstate(100)
 390        self.assertEqual(a.getstate(), 100)
 391
 392class ClassPropertiesAndMethods(unittest.TestCase):
 393
 394    def test_python_dicts(self):
 395        # Testing Python subclass of dict...
 396        self.assert_(issubclass(dict, dict))
 397        self.assert_(isinstance({}, dict))
 398        d = dict()
 399        self.assertEqual(d, {})
 400        self.assert_(d.__class__ is dict)
 401        self.assert_(isinstance(d, dict))
 402        class C(dict):
 403            state = -1
 404            def __init__(self_local, *a, **kw):
 405                if a:
 406                    self.assertEqual(len(a), 1)
 407                    self_local.state = a[0]
 408                if kw:
 409                    for k, v in kw.items():
 410                        self_local[v] = k
 411            def __getitem__(self, key):
 412                return self.get(key, 0)
 413            def __setitem__(self_local, key, value):
 414                self.assert_(isinstance(key, type(0)))
 415                dict.__setitem__(self_local, key, value)
 416            def setstate(self, state):
 417                self.state = state
 418            def getstate(self):
 419                return self.state
 420        self.assert_(issubclass(C, dict))
 421        a1 = C(12)
 422        self.assertEqual(a1.state, 12)
 423        a2 = C(foo=1, bar=2)
 424        self.assertEqual(a2[1] == 'foo' and a2[2], 'bar')
 425        a = C()
 426        self.assertEqual(a.state, -1)
 427        self.assertEqual(a.getstate(), -1)
 428        a.setstate(0)
 429        self.assertEqual(a.state, 0)
 430        self.assertEqual(a.getstate(), 0)
 431        a.setstate(10)
 432        self.assertEqual(a.state, 10)
 433        self.assertEqual(a.getstate(), 10)
 434        self.assertEqual(a[42], 0)
 435        a[42] = 24
 436        self.assertEqual(a[42], 24)
 437        N = 50
 438        for i in range(N):
 439            a[i] = C()
 440            for j in range(N):
 441                a[i][j] = i*j
 442        for i in range(N):
 443            for j in range(N):
 444                self.assertEqual(a[i][j], i*j)
 445
 446    def test_python_lists(self):
 447        # Testing Python subclass of list...
 448        class C(list):
 449            def __getitem__(self, i):
 450                return list.__getitem__(self, i) + 100
 451            def __getslice__(self, i, j):
 452                return (i, j)
 453        a = C()
 454        a.extend([0,1,2])
 455        self.assertEqual(a[0], 100)
 456        self.assertEqual(a[1], 101)
 457        self.assertEqual(a[2], 102)
 458        self.assertEqual(a[100:200], (100,200))
 459
 460    def test_metaclass(self):
 461        # Testing __metaclass__...
 462        class C:
 463            __metaclass__ = type
 464            def __init__(self):
 465                self.__state = 0
 466            def getstate(self):
 467                return self.__state
 468            def setstate(self, state):
 469                self.__state = state
 470        a = C()
 471        self.assertEqual(a.getstate(), 0)
 472        a.setstate(10)
 473        self.assertEqual(a.getstate(), 10)
 474        class D:
 475            class __metaclass__(type):
 476                def myself(cls): return cls
 477        self.assertEqual(D.myself(), D)
 478        d = D()
 479        self.assertEqual(d.__class__, D)
 480        class M1(type):
 481            def __new__(cls, name, bases, dict):
 482                dict['__spam__'] = 1
 483                return type.__new__(cls, name, bases, dict)
 484        class C:
 485            __metaclass__ = M1
 486        self.assertEqual(C.__spam__, 1)
 487        c = C()
 488        self.assertEqual(c.__spam__, 1)
 489
 490        class _instance(object):
 491            pass
 492        class M2(object):
 493            @staticmethod
 494            def __new__(cls, name, bases, dict):
 495                self = object.__new__(cls)
 496                self.name = name
 497                self.bases = bases
 498                self.dict = dict
 499                return self
 500            def __call__(self):
 501                it = _instance()
 502                # Early binding of methods
 503                for key in self.dict:
 504                    if key.startswith("__"):
 505                        continue
 506                    setattr(it, key, self.dict[key].__get__(it, self))
 507                return it
 508        class C:
 509            __metaclass__ = M2
 510            def spam(self):
 511                return 42
 512        self.assertEqual(C.name, 'C')
 513        self.assertEqual(C.bases, ())
 514        self.assert_('spam' in C.dict)
 515        c = C()
 516        self.assertEqual(c.spam(), 42)
 517
 518        # More metaclass examples
 519
 520        class autosuper(type):
 521            # Automatically add __super to the class
 522            # This trick only works for dynamic classes
 523            def __new__(metaclass, name, bases, dict):
 524                cls = super(autosuper, metaclass).__new__(metaclass,
 525                                                          name, bases, dict)
 526                # Name mangling for __super removes leading underscores
 527                while name[:1] == "_":
 528                    name = name[1:]
 529                if name:
 530                    name = "_%s__super" % name
 531                else:
 532                    name = "__super"
 533                setattr(cls, name, super(cls))
 534                return cls
 535        class A:
 536            __metaclass__ = autosuper
 537            def meth(self):
 538                return "A"
 539        class B(A):
 540            def meth(self):
 541                return "B" + self.__super.meth()
 542        class C(A):
 543            def meth(self):
 544                return "C" + self.__super.meth()
 545        class D(C, B):
 546            def meth(self):
 547                return "D" + self.__super.meth()
 548        self.assertEqual(D().meth(), "DCBA")
 549        class E(B, C):
 550            def meth(self):
 551                return "E" + self.__super.meth()
 552        self.assertEqual(E().meth(), "EBCA")
 553
 554        class autoproperty(type):
 555            # Automatically create property attributes when methods
 556            # named _get_x and/or _set_x are found
 557            def __new__(metaclass, name, bases, dict):
 558                hits = {}
 559                for key, val in dict.iteritems():
 560                    if key.startswith("_get_"):
 561                        key = key[5:]
 562                        get, set = hits.get(key, (None, None))
 563                        get = val
 564                        hits[key] = get, set
 565                    elif key.startswith("_set_"):
 566                        key = key[5:]
 567                        get, set = hits.get(key, (None, None))
 568                        set = val
 569                        hits[key] = get, set
 570                for key, (get, set) in hits.iteritems():
 571                    dict[key] = property(get, set)
 572                return super(autoproperty, metaclass).__new__(metaclass,
 573                                                            name, bases, dict)
 574        class A:
 575            __metaclass__ = autoproperty
 576            def _get_x(self):
 577                return -self.__x
 578            def _set_x(self, x):
 579                self.__x = -x
 580        a = A()
 581        self.assert_(not hasattr(a, "x"))
 582        a.x = 12
 583        self.assertEqual(a.x, 12)
 584        self.assertEqual(a._A__x, -12)
 585
 586        class multimetaclass(autoproperty, autosuper):
 587            # Merge of multiple cooperating metaclasses
 588            pass
 589        class A:
 590            __metaclass__ = multimetaclass
 591            def _get_x(self):
 592                return "A"
 593        class B(A):
 594            def _get_x(self):
 595                return "B" + self.__super._get_x()
 596        class C(A):
 597            def _get_x(self):
 598                return "C" + self.__super._get_x()
 599        class D(C, B):
 600            def _get_x(self):
 601                return "D" + self.__super._get_x()
 602        self.assertEqual(D().x, "DCBA")
 603
 604        # Make sure type(x) doesn't call x.__class__.__init__
 605        class T(type):
 606            counter = 0
 607            def __init__(self, *args):
 608                T.counter += 1
 609        class C:
 610            __metaclass__ = T
 611        self.assertEqual(T.counter, 1)
 612        a = C()
 613        self.assertEqual(type(a), C)
 614        self.assertEqual(T.counter, 1)
 615
 616        class C(object): pass
 617        c = C()
 618        try: c()
 619        except TypeError: pass
 620        else: self.fail("calling object w/o call method should raise "
 621                        "TypeError")
 622
 623        # Testing code to find most derived baseclass
 624        class A(type):
 625            def __new__(*args, **kwargs):
 626                return type.__new__(*args, **kwargs)
 627
 628        class B(object):
 629            pass
 630
 631        class C(object):
 632            __metaclass__ = A
 633
 634        # The most derived metaclass of D is A rather than type.
 635        class D(B, C):
 636            pass
 637
 638    def test_module_subclasses(self):
 639        # Testing Python subclass of module...
 640        log = []
 641        import types, sys
 642        MT = type(sys)
 643        class MM(MT):
 644            def __init__(self, name):
 645                MT.__init__(self, name)
 646            def __getattribute__(self, name):
 647                log.append(("getattr", name))
 648                return MT.__getattribute__(self, name)
 649            def __setattr__(self, name, value):
 650                log.append(("setattr", name, value))
 651                MT.__setattr__(self, name, value)
 652            def __delattr__(self, name):
 653                log.append(("delattr", name))
 654                MT.__delattr__(self, name)
 655        a = MM("a")
 656        a.foo = 12
 657        x = a.foo
 658        del a.foo
 659        self.assertEqual(log, [("setattr", "foo", 12),
 660                               ("getattr", "foo"),
 661                               ("delattr", "foo")])
 662
 663        # http://python.org/sf/1174712
 664        try:
 665            class Module(types.ModuleType, str):
 666                pass
 667        except TypeError:
 668            pass
 669        else:
 670            self.fail("inheriting from ModuleType and str at the same time "
 671                      "should fail")
 672
 673    def test_multiple_inheritence(self):
 674        # Testing multiple inheritance...
 675        class C(object):
 676            def __init__(self):
 677                self.__state = 0
 678            def getstate(self):
 679                return self.__state
 680            def setstate(self, state):
 681                self.__state = state
 682        a = C()
 683        self.assertEqual(a.getstate(), 0)
 684        a.setstate(10)
 685        self.assertEqual(a.getstate(), 10)
 686        class D(dict, C):
 687            def __init__(self):
 688                type({}).__init__(self)
 689                C.__init__(self)
 690        d = D()
 691        self.assertEqual(d.keys(), [])
 692        d["hello"] = "world"
 693        self.assertEqual(d.items(), [("hello", "world")])
 694        self.assertEqual(d["hello"], "world")
 695        self.assertEqual(d.getstate(), 0)
 696        d.setstate(10)
 697        self.assertEqual(d.getstate(), 10)
 698        self.assertEqual(D.__mro__, (D, dict, C, object))
 699
 700        # SF bug #442833
 701        class Node(object):
 702            def __int__(self):
 703                return int(self.foo())
 704            def foo(self):
 705                return "23"
 706        class Frag(Node, list):
 707            def foo(self):
 708                return "42"
 709        self.assertEqual(Node().__int__(), 23)
 710        self.assertEqual(int(Node()), 23)
 711        self.assertEqual(Frag().__int__(), 42)
 712        self.assertEqual(int(Frag()), 42)
 713
 714        # MI mixing classic and new-style classes.
 715
 716        class A:
 717            x = 1
 718
 719        class B(A):
 720            pass
 721
 722        class C(A):
 723            x = 2
 724
 725        class D(B, C):
 726            pass
 727        self.assertEqual(D.x, 1)
 728
 729        # Classic MRO is preserved for a classic base class.
 730        class E(D, object):
 731            pass
 732        self.assertEqual(E.__mro__, (E, D, B, A, C, object))
 733        self.assertEqual(E.x, 1)
 734
 735        # But with a mix of classic bases, their MROs are combined using
 736        # new-style MRO.
 737        class F(B, C, object):
 738            pass
 739        self.assertEqual(F.__mro__, (F, B, C, A, object))
 740        self.assertEqual(F.x, 2)
 741
 742        # Try something else.
 743        class C:
 744            def cmethod(self):
 745                return "C a"
 746            def all_method(self):
 747                return "C b"
 748
 749        class M1(C, object):
 750            def m1method(self):
 751                return "M1 a"
 752            def all_method(self):
 753                return "M1 b"
 754
 755        self.assertEqual(M1.__mro__, (M1, C, object))
 756        m = M1()
 757        self.assertEqual(m.cmethod(), "C a")
 758        self.assertEqual(m.m1method(), "M1 a")
 759        self.assertEqual(m.all_method(), "M1 b")
 760
 761        class D(C):
 762            def dmethod(self):
 763                return "D a"
 764            def all_method(self):
 765                return "D b"
 766
 767        class M2(D, object):
 768            def m2method(self):
 769                return "M2 a"
 770            def all_method(self):
 771                return "M2 b"
 772
 773        self.assertEqual(M2.__mro__, (M2, D, C, object))
 774        m = M2()
 775        self.assertEqual(m.cmethod(), "C a")
 776        self.assertEqual(m.dmethod(), "D a")
 777        self.assertEqual(m.m2method(), "M2 a")
 778        self.assertEqual(m.all_method(), "M2 b")
 779
 780        class M3(M1, M2, object):
 781            def m3method(self):
 782                return "M3 a"
 783            def all_method(self):
 784                return "M3 b"
 785        self.assertEqual(M3.__mro__, (M3, M1, M2, D, C, object))
 786        m = M3()
 787        self.assertEqual(m.cmethod(), "C a")
 788        self.assertEqual(m.dmethod(), "D a")
 789        self.assertEqual(m.m1method(), "M1 a")
 790        self.assertEqual(m.m2method(), "M2 a")
 791        self.assertEqual(m.m3method(), "M3 a")
 792        self.assertEqual(m.all_method(), "M3 b")
 793
 794        class Classic:
 795            pass
 796        try:
 797            class New(Classic):
 798                __metaclass__ = type
 799        except TypeError:
 800            pass
 801        else:
 802            self.fail("new class with only classic bases - shouldn't be")
 803
 804    def test_diamond_inheritence(self):
 805        # Testing multiple inheritance special cases...
 806        class A(object):
 807            def spam(self): return "A"
 808        self.assertEqual(A().spam(), "A")
 809        class B(A):
 810            def boo(self): return "B"
 811            def spam(self): return "B"
 812        self.assertEqual(B().spam(), "B")
 813        self.assertEqual(B().boo(), "B")
 814        class C(A):
 815            def boo(self): return "C"
 816        self.assertEqual(C().spam(), "A")
 817        self.assertEqual(C().boo(), "C")
 818        class D(B, C): pass
 819        self.assertEqual(D().spam(), "B")
 820        self.assertEqual(D().boo(), "B")
 821        self.assertEqual(D.__mro__, (D, B, C, A, object))
 822        class E(C, B): pass
 823        self.assertEqual(E().spam(), "B")
 824        self.assertEqual(E().boo(), "C")
 825        self.assertEqual(E.__mro__, (E, C, B, A, object))
 826        # MRO order disagreement
 827        try:
 828            class F(D, E): pass
 829        except TypeError:
 830            pass
 831        else:
 832            self.fail("expected MRO order disagreement (F)")
 833        try:
 834            class G(E, D): pass
 835        except TypeError:
 836            pass
 837        else:
 838            self.fail("expected MRO order disagreement (G)")
 839
 840    # see thread python-dev/2002-October/029035.html
 841    def test_ex5_from_c3_switch(self):
 842        # Testing ex5 from C3 switch discussion...
 843        class A(object): pass
 844        class B(object): pass
 845        class C(object): pass
 846        class X(A): pass
 847        class Y(A): pass
 848        class Z(X,B,Y,C): pass
 849        self.assertEqual(Z.__mro__, (Z, X, B, Y, A, C, object))
 850
 851    # see "A Monotonic Superclass Linearization for Dylan",
 852    # by Kim Barrett et al. (OOPSLA 1996)
 853    def test_monotonicity(self):
 854        # Testing MRO monotonicity...
 855        class Boat(object): pass
 856        class DayBoat(Boat): pass
 857        class WheelBoat(Boat): pass
 858        class EngineLess(DayBoat): pass
 859        class SmallMultihull(DayBoat): pass
 860        class PedalWheelBoat(EngineLess,WheelBoat): pass
 861        class SmallCatamaran(SmallMultihull): pass
 862        class Pedalo(PedalWheelBoat,SmallCatamaran): pass
 863
 864        self.assertEqual(PedalWheelBoat.__mro__,
 865              (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat, object))
 866        self.assertEqual(SmallCatamaran.__mro__,
 867              (SmallCatamaran, SmallMultihull, DayBoat, Boat, object))
 868        self.assertEqual(Pedalo.__mro__,
 869              (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran,
 870               SmallMultihull, DayBoat, WheelBoat, Boat, object))
 871
 872    # see "A Monotonic Superclass Linearization for Dylan",
 873    # by Kim Barrett et al. (OOPSLA 1996)
 874    def test_consistency_with_epg(self):
 875        # Testing consistentcy with EPG...
 876        class Pane(object): pass
 877        class ScrollingMixin(object): pass
 878        class EditingMixin(object): pass
 879        class ScrollablePane(Pane,ScrollingMixin): pass
 880        class EditablePane(Pane,EditingMixin): pass
 881        class EditableScrollablePane(ScrollablePane,EditablePane): pass
 882
 883        self.assertEqual(EditableScrollablePane.__mro__,
 884              (EditableScrollablePane, ScrollablePane, EditablePane, Pane,
 885                ScrollingMixin, EditingMixin, object))
 886
 887    def test_mro_disagreement(self):
 888        # Testing error messages for MRO disagreement...
 889        mro_err_msg = """Cannot create a consistent method resolution
 890order (MRO) for bases """
 891
 892        def raises(exc, expected, callable, *args):
 893            try:
 894                callable(*args)
 895            except exc, msg:
 896                if not str(msg).startswith(expected):
 897                    self.fail("Message %r, expected %r" % (str(msg), expected))
 898            else:
 899                self.fail("Expected %s" % exc)
 900
 901        class A(object): pass
 902        class B(A): pass
 903        class C(object): pass
 904
 905        # Test some very simple errors
 906        raises(TypeError, "duplicate base class A",
 907               type, "X", (A, A), {})
 908        raises(TypeError, mro_err_msg,
 909               type, "X", (A, B), {})
 910        raises(TypeError, mro_err_msg,
 911               type, "X", (A, C, B), {})
 912        # Test a slightly more complex error
 913        class GridLayout(object): pass
 914        class HorizontalGrid(GridLayout): pass
 915        class VerticalGrid(GridLayout): pass
 916        class HVGrid(HorizontalGrid, VerticalGrid): pass
 917        class VHGrid(VerticalGrid, HorizontalGrid): pass
 918        raises(TypeError, mro_err_msg,
 919               type, "ConfusedGrid", (HVGrid, VHGrid), {})
 920
 921    def test_object_class(self):
 922        # Testing object class...
 923        a = object()
 924        self.assertEqual(a.__class__, object)
 925        self.assertEqual(type(a), object)
 926        b = object()
 927        self.assertNotEqual(a, b)
 928        self.assertFalse(hasattr(a, "foo"))
 929        try:
 930            a.foo = 12
 931        except (AttributeError, TypeError):
 932            pass
 933        else:
 934            self.fail("object() should not allow setting a foo attribute")
 935        self.assertFalse(hasattr(object(), "__dict__"))
 936
 937        class Cdict(object):
 938            pass
 939        x = Cdict()
 940        self.assertEqual(x.__dict__, {})
 941        x.foo = 1
 942        self.assertEqual(x.foo, 1)
 943        self.assertEqual(x.__dict__, {'foo': 1})
 944
 945    def test_slots(self):
 946        # Testing __slots__...
 947        class C0(object):
 948            __slots__ = []
 949        x = C0()
 950        self.assertFalse(hasattr(x, "__dict__"))
 951        self.assertFalse(hasattr(x, "foo"))
 952
 953        class C1(object):
 954            __slots__ = ['a']
 955        x = C1()
 956        self.assertFalse(hasattr(x, "__dict__"))
 957        self.assertFalse(hasattr(x, "a"))
 958        x.a = 1
 959        self.assertEqual(x.a, 1)
 960        x.a = None
 961        self.assertEqual(x.a, None)
 962        del x.a
 963        self.assertFalse(hasattr(x, "a"))
 964
 965        class C3(object):
 966            __slots__ = ['a', 'b', 'c']
 967        x = C3()
 968        self.assertFalse(hasattr(x, "__dict__"))
 969        self.assertFalse(hasattr(x, 'a'))
 970        self.assertFalse(hasattr(x, 'b'))
 971        self.assertFalse(hasattr(x, 'c'))
 972        x.a = 1
 973        x.b = 2
 974        x.c = 3
 975        self.assertEqual(x.a, 1)
 976        self.assertEqual(x.b, 2)
 977        self.assertEqual(x.c, 3)
 978
 979        class C4(object):
 980            """Validate name mangling"""
 981            __slots__ = ['__a']
 982            def __init__(self, value):
 983                self.__a = value
 984            def get(self):
 985                return self.__a
 986        x = C4(5)
 987        self.assertFalse(hasattr(x, '__dict__'))
 988        self.assertFalse(hasattr(x, '__a'))
 989        self.assertEqual(x.get(), 5)
 990        try:
 991            x.__a = 6
 992        except AttributeError:
 993            pass
 994        else:
 995            self.fail("Double underscored names not mangled")
 996
 997        # Make sure slot names are proper identifiers
 998        try:
 999            class C(object):
1000                __slots__ = [None]
1001        except TypeError:
1002            pass
1003        else:
1004            self.fail("[None] slots not caught")
1005        try:
1006            class C(object):
1007                __slots__ = ["foo bar"]
1008        except TypeError:
1009            pass
1010        else:
1011            self.fail("['foo bar'] slots not caught")
1012        try:
1013            class C(object):
1014                __slots__ = ["foo\0bar"]
1015        except TypeError:
1016            pass
1017        else:
1018            self.fail("['foo\\0bar'] slots not caught")
1019        try:
1020            class C(object):
1021                __slots__ = ["1"]
1022        except TypeError:
1023            pass
1024        else:
1025            self.fail("['1'] slots not caught")
1026        try:
1027            class C(object):
1028                __slots__ = [""]
1029        except TypeError:
1030            pass
1031        else:
1032            self.fail("[''] slots not caught")
1033        class C(object):
1034            __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
1035        # XXX(nnorwitz): was there supposed to be something tested
1036        # from the class above?
1037
1038        # Test a single string is not expanded as a sequence.
1039        class C(object):
1040            __slots__ = "abc"
1041        c = C()
1042        c.abc = 5
1043        self.assertEqual(c.abc, 5)
1044
1045        # Test unicode slot names
1046        try:
1047            unicode
1048        except NameError:
1049            pass
1050        else:
1051            # Test a single unicode string is not expanded as a sequence.
1052            class C(object):
1053                __slots__ = unicode("abc")
1054            c = C()
1055            c.abc = 5
1056            self.assertEqual(c.abc, 5)
1057
1058            # _unicode_to_string used to modify slots in certain circumstances
1059            slots = (unicode("foo"), unicode("bar"))
1060            class C(object):
1061                __slots__ = slots
1062            x = C()
1063            x.foo = 5
1064            self.assertEqual(x.foo, 5)
1065            self.assertEqual(type(slots[0]), unicode)
1066            # this used to leak references
1067            try:
1068                class C(object):
1069                    __slots__ = [unichr(128)]
1070            except (TypeError, UnicodeEncodeError):
1071                pass
1072            else:
1073                self.fail("[unichr(128)] slots not caught")
1074
1075        # Test leaks
1076        class Counted(object):
1077            counter = 0    # counts the number of instances alive
1078            def __init__(self):
1079                Counted.counter += 1
1080            def __del__(self):
1081                Counted.counter -= 1
1082        class C(object):
1083            __slots__ = ['a', 'b', 'c']
1084        x = C()
1085        x.a = Counted()
1086        x.b = Counted()
1087        x.c = Counted()
1088        self.assertEqual(Counted.counter, 3)
1089        del x
1090        self.assertEqual(Counted.counter, 0)
1091        class D(C):
1092            pass
1093        x = D()
1094        x.a = Counted()
1095        x.z = Counted()
1096        self.assertEqual(Counted.counter, 2)
1097        del x
1098        self.assertEqual(Counted.counter, 0)
1099        class E(D):
1100            __slots__ = ['e']
1101        x = E()
1102        x.a = Counted()
1103        x.z = Counted()
1104        x.e = Counted()
1105        self.assertEqual(Counted.counter, 3)
1106        del x
1107        self.assertEqual(Counted.counter, 0)
1108
1109        # Test cyclical leaks [SF bug 519621]
1110        class F(object):
1111            __slots__ = ['a', 'b']
1112        log = []
1113        s = F()
1114        s.a = [Counted(), s]
1115        self.assertEqual(Counted.counter, 1)
1116        s = None
1117        import gc
1118        gc.collect()
1119        self.assertEqual(Counted.counter, 0)
1120
1121        # Test lookup leaks [SF bug 572567]
1122        import sys,gc
1123        class G(object):
1124            def __cmp__(self, other):
1125                return 0
1126            __hash__ = None # Silence Py3k warning
1127        g = G()
1128        orig_objects = len(gc.get_objects())
1129        for i in xrange(10):
1130            g==g
1131        new_objects = len(gc.get_objects())
1132        self.assertEqual(orig_objects, new_objects)
1133        class H(object):
1134            __slots__ = ['a', 'b']
1135            def __init__(self):
1136                self.a = 1
1137                self.b = 2
1138            def __del__(self_):
1139                self.assertEqual(self_.a, 1)
1140                self.assertEqual(self_.b, 2)
1141        with test_support.captured_output('stderr') as s:
1142            h = H()
1143            del h
1144        self.assertEqual(s.getvalue(), '')
1145
1146    def test_slots_special(self):
1147        # Testing __dict__ and __weakref__ in __slots__...
1148        class D(object):
1149            __slots__ = ["__dict__"]
1150        a = D()
1151        self.assert_(hasattr(a, "__dict__"))
1152        self.assertFalse(hasattr(a, "__weakref__"))
1153        a.foo = 42
1154        self.assertEqual(a.__dict__, {"foo": 42})
1155
1156        class W(object):
1157            __slots__ = ["__weakref__"]
1158        a = W()
1159        self.assert_(hasattr(a, "__weakref__"))
1160        self.assertFalse(hasattr(a, "__dict__"))
1161        try:
1162            a.foo = 42
1163        except AttributeError:
1164            pass
1165        else:
1166            self.fail("shouldn't be allowed to set a.foo")
1167
1168        class C1(W, D):
1169            __slots__ = []
1170        a = C1()
1171        self.assert_(hasattr(a, "__dict__"))
1172        self.assert_(hasattr(a, "__weakref__"))
1173        a.foo = 42
1174        self.assertEqual(a.__dict__, {"foo": 42})
1175
1176        class C2(D, W):
1177            __slots__ = []
1178        a = C2()
1179        self.assert_(hasattr(a, "__dict__"))
1180        self.assert_(hasattr(a, "__weakref__"))
1181        a.foo = 42
1182        self.assertEqual(a.__dict__, {"foo": 42})
1183
1184    def test_slots_descriptor(self):
1185        # Issue2115: slot descriptors did not correctly check
1186        # the type of the given object
1187        import abc
1188        class MyABC:
1189            __metaclass__ = abc.ABCMeta
1190            __slots__ = "a"
1191
1192        class Unrelated(object):
1193            pass
1194        MyABC.register(Unrelated)
1195
1196        u = Unrelated()
1197        self.assert_(isinstance(u, MyABC))
1198
1199        # This used to crash
1200        self.assertRaises(TypeError, MyABC.a.__set__, u, 3)
1201
1202    def test_dynamics(self):
1203        # Testing class attribute propagation...
1204        class D(object):
1205            pass
1206        class E(D):
1207            pass
1208        class F(D):
1209            pass
1210        D.foo = 1
1211        self.assertEqual(D.foo, 1)
1212        # Test that dynamic attributes are inherited
1213        self.assertEqual(E.foo, 1)
1214        self.assertEqual(F.foo, 1)
1215        # Test dynamic instances
1216        class C(object):
1217            pass
1218        a = C()
1219        self.assertFalse(hasattr(a, "foobar"))
1220        C.foobar = 2
1221        self.assertEqual(a.foobar, 2)
1222        C.method = lambda self: 42
1223        self.assertEqual(a.method(), 42)
1224        C.__repr__ = lambda self: "C()"
1225        self.assertEqual(repr(a), "C()")
1226        C.__int__ = lambda self: 100
1227        self.assertEqual(int(a), 100)
1228        self.assertEqual(a.foobar, 2)
1229        self.assertFalse(hasattr(a, "spam"))
1230        def mygetattr(self, name):
1231            if name == "spam":
1232                return "spam"
1233            raise AttributeError
1234        C.__getattr__ = mygetattr
1235        self.assertEqual(a.spam, "spam")
1236        a.new = 12
1237        self.assertEqual(a.new, 12)
1238        def mysetattr(self, name, value):
1239            if name == "spam":
1240                raise AttributeError
1241            return object.__setattr__(self, name, value)
1242        C.__setattr__ = mysetattr
1243        try:
1244            a.spam = "not spam"
1245        except AttributeError:
1246            pass
1247        else:
1248            self.fail("expected AttributeError")
1249        self.assertEqual(a.spam, "spam")
1250        class D(C):
1251            pass
1252        d = D()
1253        d.foo = 1
1254        self.assertEqual(d.foo, 1)
1255
1256        # Test handling of int*seq and seq*int
1257        class I(int):
1258            pass
1259        self.assertEqual("a"*I(2), "aa")
1260        self.assertEqual(I(2)*"a", "aa")
1261        self.assertEqual(2*I(3), 6)
1262        self.assertEqual(I(3)*2, 6)
1263        self.assertEqual(I(3)*I(2), 6)
1264
1265        # Test handling of long*seq and seq*long
1266        class L(long):
1267            pass
1268        self.assertEqual("a"*L(2L), "aa")
1269        self.assertEqual(L(2L)*"a", "aa")
1270        self.assertEqual(2*L(3), 6)
1271        self.assertEqual(L(3)*2, 6)
1272        self.assertEqual(L(3)*L(2), 6)
1273
1274        # Test comparison of classes with dynamic metaclasses
1275        class dynamicmetaclass(type):
1276            pass
1277        class someclass:
1278            __metaclass__ = dynamicmetaclass
1279        self.assertNotEqual(someclass, object)
1280
1281    def test_errors(self):
1282        # Testing errors...
1283        try:
1284            class C(list, dict):
1285                pass
1286        except TypeError:
1287            pass
1288        else:
1289            self.fail("inheritance from both list and dict should be illegal")
1290
1291        try:
1292            class C(object, None):
1293                pass
1294        except TypeError:
1295            pass
1296        else:
1297            self.fail("inheritance from non-type should be illegal")
1298        class Classic:
1299            pass
1300
1301        try:
1302            class C(type(len)):
1303                pass
1304        except TypeError:
1305            pass
1306        else:
1307            self.fail("inheritance from CFunction should be illegal")
1308
1309        try:
1310            class C(object):
1311                __slots__ = 1
1312        except TypeError:
1313            pass
1314        else:
1315            self.fail("__slots__ = 1 should be illegal")
1316
1317        try:
1318            class C(object):
1319                __slots__ = [1]
1320        except TypeError:
1321            pass
1322        else:
1323            self.fail("__slots__ = [1] should be illegal")
1324
1325        class M1(type):
1326            pass
1327        class M2(type):
1328            pass
1329        class A1(object):
1330            __metaclass__ = M1
1331        class A2(object):
1332            __metaclass__ = M2
1333        try:
1334            class B(A1, A2):
1335                pass
1336        except TypeError:
1337            pass
1338        else:
1339            self.fail("finding the most derived metaclass should have failed")
1340
1341    def test_classmethods(self):
1342        # Testing class methods...
1343        class C(object):
1344            def foo(*a): return a
1345            goo = classmethod(foo)
1346        c = C()
1347        self.assertEqual(C.goo(1), (C, 1))
1348        self.assertEqual(c.goo(1), (C, 1))
1349        self.assertEqual(c.foo(1), (c, 1))
1350        class D(C):
1351            pass
1352        d = D()
1353        self.assertEqual(D.goo(1), (D, 1))
1354        self.assertEqual(d.goo(1), (D, 1))
1355        self.assertEqual(d.foo(1), (d, 1))
1356        self.assertEqual(D.foo(d, 1), (d, 1))
1357        # Test for a specific crash (SF bug 528132)
1358        def f(cls, arg): return (cls, arg)
1359        ff = classmethod(f)
1360        self.assertEqual(ff.__get__(0, int)(42), (int, 42))
1361        self.assertEqual(ff.__get__(0)(42), (int, 42))
1362
1363        # Test super() with classmethods (SF bug 535444)
1364        self.assertEqual(C.goo.im_self, C)
1365        self.assertEqual(D.goo.im_self, D)
1366        self.assertEqual(super(D,D).goo.im_self, D)
1367        self.assertEqual(super(D,d).goo.im_self, D)
1368        self.assertEqual(super(D,D).goo(), (D,))
1369        self.assertEqual(super(D,d).goo(), (D,))
1370
1371        # Verify that argument is checked for callability (SF bug 753451)
1372        try:
1373            classmethod(1).__get__(1)
1374        except TypeError:
1375            pass
1376        else:
1377            self.fail("classmethod should check for callability")
1378
1379        # Verify that classmethod() doesn't allow keyword args
1380        try:
1381            classmethod(f, kw=1)
1382        except TypeError:
1383            pass
1384        else:
1385            self.fail("classmethod shouldn't accept keyword args")
1386
1387    def test_classmethods_in_c(self):
1388        # Testing C-based class methods...
1389        import xxsubtype as spam
1390        a = (1, 2, 3)
1391        d = {'abc': 123}
1392        x, a1, d1 = spam.spamlist.classmeth(*a, **d)
1393        self.assertEqual(x, spam.spamlist)
1394        self.assertEqual(a, a1)
1395        self.assertEqual(d, d1)
1396        x, a1, d1 = spam.spamlist().classmeth(*a, **d)
1397        self.assertEqual(x, spam.spamlist)
1398        self.assertEqual(a, a1)
1399        self.assertEqual(d, d1)
1400
1401    def test_staticmethods(self):
1402        # Testing static methods...
1403        class C(object):
1404            def foo(*a): return a
1405            goo = staticmethod(foo)
1406        c = C()
1407        self.assertEqual(C.goo(1), (1,))
1408        self.assertEqual(c.goo(1), (1,))
1409        self.assertEqual(c.foo(1), (c, 1,))
1410        class D(C):
1411            pass
1412        d = D()
1413        self.assertEqual(D.goo(1), (1,))
1414        self.assertEqual(d.goo(1), (1,))
1415        self.assertEqual(d.foo(1), (d, 1))
1416        self.assertEqual(D.foo(d, 1), (d, 1))
1417
1418    def test_staticmethods_in_c(self):
1419        # Testing C-based static methods...
1420        import xxsubtype as spam
1421        a = (1, 2, 3)
1422        d = {"abc": 123}
1423        x, a1, d1 = spam.spamlist.staticmeth(*a, **d)
1424        self.assertEqual(x, None)
1425        self.assertEqual(a, a1)
1426        self.assertEqual(d, d1)
1427        x, a1, d2 = spam.spamlist().staticmeth(*a, **d)
1428        self.assertEqual(x, None)
1429        self.assertEqual(a, a1)
1430        self.assertEqual(d, d1)
1431
1432    def test_classic(self):
1433        # Testing classic classes...
1434        class C:
1435            def foo(*a): return a
1436            goo = classmethod(foo)
1437        c = C()
1438        self.assertEqual(C.goo(1), (C, 1))
1439        self.assertEqual(c.goo(1), (C, 1))
1440        self.assertEqual(c.foo(1), (c, 1))
1441        class D(C):
1442            pass
1443        d = D()
1444        self.assertEqual(D.goo(1), (D, 1))
1445        self.assertEqual(d.goo(1), (D, 1))
1446        self.assertEqual(d.foo(1), (d, 1))
1447        self.assertEqual(D.foo(d, 1), (d, 1))
1448        class E: # *not* subclassing from C
1449            foo = C.foo
1450        self.assertEqual(E().foo, C.foo) # i.e., unbound
1451        self.assert_(repr(C.foo.__get__(C())).startswith("<bound method "))
1452
1453    def test_compattr(self):
1454        # Testing computed attributes...
1455        class C(object):
1456            class computed_attribute(object):
1457                def __init__(self, get, set=None, delete=None):
1458                    self.__get = get
1459                    self.__set = set
1460                    self.__delete = delete
1461                def __get__(self, obj, type=None):
1462                    return self.__get(obj)
1463                def __set__(self, obj, value):
1464                    return self.__set(obj, value)
1465                def __delete__(self, obj):
1466                    return self.__delete(obj)
1467            def __init__(self):
1468                self.__x = 0
1469            def __get_x(self):
1470                x = self.__x
1471                self.__x = x+1
1472                return x
1473            def __set_x(self, x):
1474                self.__x = x
1475            def __delete_x(self):
1476                del self.__x
1477            x = computed_attribute(__get_x, __set_x, __delete_x)
1478        a = C()
1479        self.assertEqual(a.x, 0)
1480        self.assertEqual(a.x, 1)
1481        a.x = 10
1482        self.assertEqual(a.x, 10)
1483        self.assertEqual(a.x, 11)
1484        del a.x
1485        self.assertEqual(hasattr(a, 'x'), 0)
1486
1487    def test_newslots(self):
1488        # Testing __new__ slot override...
1489        class C(list):
1490            def __new__(cls):
1491                self = list.__new__(cls)
1492                self.foo = 1
1493                return self
1494            def __init__(self):
1495                self.foo = self.foo + 2
1496        a = C()
1497        self.assertEqual(a.foo, 3)
1498        self.assertEqual(a.__class__, C)
1499        class D(C):
1500            pass
1501        b = D()
1502        self.assertEqual(b.foo, 3)
1503        self.assertEqual(b.__class__, D)
1504
1505    def test_altmro(self):
1506        # Testing mro() and overriding it...
1507        class A(object):
1508            def f(self): return "A"
1509        class B(A):
1510            pass
1511        class C(A):
1512            def f(self): return "C"
1513        class D(B, C):
1514            pass
1515        self.assertEqual(D.mro(), [D, B, C, A, object])
1516        self.assertEqual(D.__mro__, (D, B, C, A, object))
1517        self.assertEqual(D().f(), "C")
1518
1519        class PerverseMetaType(type):
1520            def mro(cls):
1521                L = type.mro(cls)
1522                L.reverse()
1523                return L
1524        class X(D,B,C,A):
1525            __metaclass__ = PerverseMetaType
1526        self.assertEqual(X.__mro__, (object, A, C, B, D, X))
1527        self.assertEqual(X().f(), "A")
1528
1529        try:
1530            class X(object):
1531                class __metaclass__(type):
1532                    

Large files files are truncated, but you can click here to view the full file