10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport functools
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom weakref import proxy
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport pickle
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao@staticmethod
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef PythonPartial(func, *args, **keywords):
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'Pure Python approximation of partial()'
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def newfunc(*fargs, **fkeywords):
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        newkeywords = keywords.copy()
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        newkeywords.update(fkeywords)
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return func(*(args + fargs), **newkeywords)
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    newfunc.func = func
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    newfunc.args = args
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    newfunc.keywords = keywords
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return newfunc
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef capture(*args, **kw):
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """capture all positional and keyword arguments"""
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return args, kw
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef signature(part):
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """ return the signature of a partial object """
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (part.func, part.args, part.keywords, part.__dict__)
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestPartial(unittest.TestCase):
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    thetype = functools.partial
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_examples(self):
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture, 1, 2, a=10, b=20)
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(3, 4, b=30, c=40),
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ((1, 2, 3, 4), dict(a=10, b=30, c=40)))
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(map, lambda x: x*10)
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40])
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_attributes(self):
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture, 1, 2, a=10, b=20)
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # attributes should be readable
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p.func, capture)
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p.args, (1, 2))
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p.keywords, dict(a=10, b=20))
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # attributes should not be writable
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not isinstance(self.thetype, type):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, setattr, p, 'func', map)
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(hex)
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            del p.__dict__
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except TypeError:
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('partial object allowed __dict__ to be deleted')
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_argument_checking(self):
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, self.thetype)     # need at least a func arg
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.thetype(2)()
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except TypeError:
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('First arg not checked for callability')
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_protection_of_callers_dict_argument(self):
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # a caller's dictionary should not be altered by partial
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def func(a=10, b=20):
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return a
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = {'a':3}
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(func, a=5)
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(**d), 3)
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, {'a':3})
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p(b=7)
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, {'a':3})
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_arg_combinations(self):
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # exercise special code paths for zero args in either partial
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # object or the caller
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture)
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(), ((), {}))
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(1,2), ((1,2), {}))
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture, 1, 2)
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(), ((1,2), {}))
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(3,4), ((1,2,3,4), {}))
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_kw_combinations(self):
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # exercise special code paths for no keyword args in
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # either the partial object or the caller
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture)
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(), ((), {}))
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(a=1), ((), {'a':1}))
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture, a=1)
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(), ((), {'a':1}))
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(b=2), ((), {'a':1, 'b':2}))
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # keyword args in the call override those in the partial object
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(p(a=3, b=2), ((), {'a':3, 'b':2}))
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_positional(self):
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # make sure positional arguments are captured correctly
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]:
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            p = self.thetype(capture, *args)
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = args + ('x',)
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got, empty = p('x')
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(expected == got and empty == {})
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_keyword(self):
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # make sure keyword arguments are captured correctly
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for a in ['a', 0, None, 3.5]:
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            p = self.thetype(capture, a=a)
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = {'a':a,'x':None}
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            empty, got = p(x=None)
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(expected == got and empty == ())
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_no_side_effects(self):
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # make sure there are no side effects that affect subsequent calls
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = self.thetype(capture, 0, a=1)
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args1, kw1 = p(1, b=2)
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(args1 == (0,1) and kw1 == {'a':1,'b':2})
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args2, kw2 = p()
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(args2 == (0,) and kw2 == {'a':1})
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_error_propagation(self):
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f(x, y):
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            x // y
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0))
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0)
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0)
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1)
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_weakref(self):
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.thetype(int, base=16)
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = proxy(f)
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.func, p.func)
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = None
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ReferenceError, getattr, p, 'func')
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_with_bound_and_unbound_methods(self):
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data = map(str, range(10))
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        join = self.thetype(str.join, '')
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(join(data), '0123456789')
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        join = self.thetype(''.join)
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(join(data), '0123456789')
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickle(self):
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.thetype(signature, 'asdf', bar=True)
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.add_something_to__dict__ = True
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f_copy = pickle.loads(pickle.dumps(f))
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(signature(f), signature(f_copy))
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Issue 6083: Reference counting bug
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_setstate_refcount(self):
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class BadSequence:
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __len__(self):
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 4
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __getitem__(self, key):
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if key == 0:
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return max
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elif key == 1:
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return tuple(range(1000000))
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elif key in (2, 3):
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return {}
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise IndexError
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.thetype(object)
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(SystemError, f.__setstate__, BadSequence())
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass PartialSubclass(functools.partial):
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pass
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestPartialSubclass(TestPartial):
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    thetype = PartialSubclass
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestPythonPartial(TestPartial):
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    thetype = PythonPartial
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # the python version isn't picklable
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickle(self): pass
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_setstate_refcount(self): pass
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestUpdateWrapper(unittest.TestCase):
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def check_wrapper(self, wrapper, wrapped,
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      assigned=functools.WRAPPER_ASSIGNMENTS,
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      updated=functools.WRAPPER_UPDATES):
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check attributes were assigned
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name in assigned:
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name))
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check attributes were updated
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name in updated:
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            wrapper_attr = getattr(wrapper, name)
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            wrapped_attr = getattr(wrapped, name)
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for key in wrapped_attr:
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertTrue(wrapped_attr[key] is wrapper_attr[key])
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _default_update(self):
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            """This is a test"""
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is also a test'
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        functools.update_wrapper(wrapper, f)
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return wrapper, f
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_default_update(self):
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wrapper, f = self._default_update()
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f)
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'f')
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.attr, 'This is also a test')
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(sys.flags.optimize >= 2,
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     "Docstrings are omitted with -O2 and above")
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_default_update_doc(self):
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wrapper, f = self._default_update()
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, 'This is a test')
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_no_update(self):
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            """This is a test"""
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is also a test'
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        functools.update_wrapper(wrapper, f, (), ())
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f, (), ())
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'wrapper')
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, None)
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(hasattr(wrapper, 'attr'))
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_selective_update(self):
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is a different test'
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.dict_attr = dict(a=1, b=2, c=3)
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wrapper.dict_attr = {}
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assign = ('attr',)
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        update = ('dict_attr',)
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        functools.update_wrapper(wrapper, f, assign, update)
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f, assign, update)
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'wrapper')
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, None)
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.attr, 'This is a different test')
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.dict_attr, f.dict_attr)
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @test_support.requires_docstrings
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_builtin_update(self):
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test for bug #1576241
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        functools.update_wrapper(wrapper, max)
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'max')
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(wrapper.__doc__.startswith('max('))
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestWraps(TestUpdateWrapper):
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _default_update(self):
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            """This is a test"""
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is also a test'
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.wraps(f)
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f)
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return wrapper
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_default_update(self):
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wrapper = self._default_update()
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'f')
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.attr, 'This is also a test')
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(sys.flags.optimize >= 2,
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     "Docstrings are omitted with -O2 and above")
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_default_update_doc(self):
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wrapper = self._default_update()
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, 'This is a test')
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_no_update(self):
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            """This is a test"""
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is also a test'
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.wraps(f, (), ())
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f, (), ())
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'wrapper')
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, None)
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(hasattr(wrapper, 'attr'))
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_selective_update(self):
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.attr = 'This is a different test'
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.dict_attr = dict(a=1, b=2, c=3)
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def add_dict_attr(f):
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.dict_attr = {}
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return f
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assign = ('attr',)
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        update = ('dict_attr',)
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.wraps(f, assign, update)
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @add_dict_attr
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper():
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_wrapper(wrapper, f, assign, update)
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__name__, 'wrapper')
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.__doc__, None)
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.attr, 'This is a different test')
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(wrapper.dict_attr, f.dict_attr)
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestReduce(unittest.TestCase):
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_reduce(self):
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Squares:
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, max):
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.max = max
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.sofar = []
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __len__(self): return len(self.sofar)
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __getitem__(self, i):
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if not 0 <= i < self.max: raise IndexError
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                n = len(self.sofar)
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                while n <= i:
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.sofar.append(n*n)
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    n += 1
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.sofar[i]
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        reduce = functools.reduce
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(lambda x, y: x+y, ['a', 'b', 'c'], ''), 'abc')
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            reduce(lambda x, y: x+y, [['a', 'c'], [], ['d', 'w']], []),
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ['a','c','d','w']
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040)
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            reduce(lambda x, y: x*y, range(2,21), 1L),
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            2432902008176640000L
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(lambda x, y: x+y, Squares(10)), 285)
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(lambda x, y: x+y, Squares(10), 0), 285)
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(lambda x, y: x+y, Squares(0), 0), 0)
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, reduce)
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, reduce, 42, 42)
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, reduce, 42, 42, 42)
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(42, "1"), "1") # func is never called with one item
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, reduce, 42, (42, 42))
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestCmpToKey(unittest.TestCase):
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_cmp_to_key(self):
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def mycmp(x, y):
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return y - x
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(sorted(range(5), key=functools.cmp_to_key(mycmp)),
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         [4, 3, 2, 1, 0])
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash(self):
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def mycmp(x, y):
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return y - x
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        key = functools.cmp_to_key(mycmp)
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        k = key(10)
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, hash(k))
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTotalOrdering(unittest.TestCase):
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_ordering_lt(self):
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A:
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, value):
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.value = value
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __lt__(self, other):
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value < other.value
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __eq__(self, other):
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value == other.value
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) < A(2))
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) > A(1))
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) <= A(2))
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(1))
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) <= A(2))
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(2))
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_ordering_le(self):
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A:
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, value):
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.value = value
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __le__(self, other):
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value <= other.value
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __eq__(self, other):
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value == other.value
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) < A(2))
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) > A(1))
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) <= A(2))
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(1))
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) <= A(2))
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(2))
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_ordering_gt(self):
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A:
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, value):
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.value = value
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __gt__(self, other):
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value > other.value
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __eq__(self, other):
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value == other.value
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) < A(2))
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) > A(1))
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) <= A(2))
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(1))
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) <= A(2))
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(2))
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_ordering_ge(self):
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A:
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, value):
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.value = value
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __ge__(self, other):
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value >= other.value
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __eq__(self, other):
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.value == other.value
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) < A(2))
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) > A(1))
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(1) <= A(2))
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(1))
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) <= A(2))
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A(2) >= A(2))
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_ordering_no_overwrite(self):
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # new methods should not overwrite existing
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(str):
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("a") < A("b"))
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("b") > A("a"))
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("a") <= A("b"))
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("b") >= A("a"))
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("b") <= A("b"))
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(A("b") >= A("b"))
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_no_operations_defined(self):
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with self.assertRaises(ValueError):
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            @functools.total_ordering
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            class A:
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bug_10042(self):
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @functools.total_ordering
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class TestTO:
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, value):
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.value = value
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __eq__(self, other):
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(other, TestTO):
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return self.value == other.value
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return False
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __lt__(self, other):
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(other, TestTO):
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return self.value < other.value
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise TypeError
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with self.assertRaises(TypeError):
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            TestTO(8) <= ()
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main(verbose=None):
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_classes = (
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestPartial,
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestPartialSubclass,
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestPythonPartial,
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestUpdateWrapper,
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestTotalOrdering,
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestWraps,
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestReduce,
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    )
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_support.run_unittest(*test_classes)
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # verify reference counting
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if verbose and hasattr(sys, "gettotalrefcount"):
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import gc
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        counts = [None] * 5
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in xrange(len(counts)):
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            test_support.run_unittest(*test_classes)
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gc.collect()
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            counts[i] = sys.gettotalrefcount()
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print counts
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main(verbose=True)
498