14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport functools
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom weakref import proxy
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport pickle
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm@staticmethod
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef PythonPartial(func, *args, **keywords):
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    'Pure Python approximation of partial()'
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def newfunc(*fargs, **fkeywords):
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        newkeywords = keywords.copy()
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        newkeywords.update(fkeywords)
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return func(*(args + fargs), **newkeywords)
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newfunc.func = func
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newfunc.args = args
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newfunc.keywords = keywords
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return newfunc
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef capture(*args, **kw):
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """capture all positional and keyword arguments"""
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return args, kw
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef signature(part):
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """ return the signature of a partial object """
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return (part.func, part.args, part.keywords, part.__dict__)
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestPartial(unittest.TestCase):
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    thetype = functools.partial
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_basic_examples(self):
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture, 1, 2, a=10, b=20)
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(3, 4, b=30, c=40),
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         ((1, 2, 3, 4), dict(a=10, b=30, c=40)))
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(map, lambda x: x*10)
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40])
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_attributes(self):
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture, 1, 2, a=10, b=20)
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # attributes should be readable
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p.func, capture)
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p.args, (1, 2))
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p.keywords, dict(a=10, b=20))
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # attributes should not be writable
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if not isinstance(self.thetype, type):
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, setattr, p, 'func', map)
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(hex)
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            del p.__dict__
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except TypeError:
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.fail('partial object allowed __dict__ to be deleted')
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_argument_checking(self):
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.thetype)     # need at least a func arg
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.thetype(2)()
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except TypeError:
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.fail('First arg not checked for callability')
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_protection_of_callers_dict_argument(self):
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # a caller's dictionary should not be altered by partial
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def func(a=10, b=20):
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return a
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        d = {'a':3}
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(func, a=5)
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(**d), 3)
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(d, {'a':3})
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p(b=7)
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(d, {'a':3})
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_arg_combinations(self):
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # exercise special code paths for zero args in either partial
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # object or the caller
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture)
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(), ((), {}))
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(1,2), ((1,2), {}))
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture, 1, 2)
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(), ((1,2), {}))
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(3,4), ((1,2,3,4), {}))
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_kw_combinations(self):
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # exercise special code paths for no keyword args in
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # either the partial object or the caller
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture)
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(), ((), {}))
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(a=1), ((), {'a':1}))
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture, a=1)
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(), ((), {'a':1}))
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(b=2), ((), {'a':1, 'b':2}))
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # keyword args in the call override those in the partial object
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(p(a=3, b=2), ((), {'a':3, 'b':2}))
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_positional(self):
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # make sure positional arguments are captured correctly
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]:
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = self.thetype(capture, *args)
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            expected = args + ('x',)
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            got, empty = p('x')
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(expected == got and empty == {})
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_keyword(self):
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # make sure keyword arguments are captured correctly
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for a in ['a', 0, None, 3.5]:
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = self.thetype(capture, a=a)
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            expected = {'a':a,'x':None}
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            empty, got = p(x=None)
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(expected == got and empty == ())
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_no_side_effects(self):
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # make sure there are no side effects that affect subsequent calls
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = self.thetype(capture, 0, a=1)
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        args1, kw1 = p(1, b=2)
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(args1 == (0,1) and kw1 == {'a':1,'b':2})
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        args2, kw2 = p()
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(args2 == (0,) and kw2 == {'a':1})
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_error_propagation(self):
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f(x, y):
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            x // y
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0))
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0)
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0)
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1)
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_weakref(self):
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f = self.thetype(int, base=16)
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p = proxy(f)
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(f.func, p.func)
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f = None
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ReferenceError, getattr, p, 'func')
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_with_bound_and_unbound_methods(self):
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        data = map(str, range(10))
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        join = self.thetype(str.join, '')
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(join(data), '0123456789')
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        join = self.thetype(''.join)
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(join(data), '0123456789')
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_pickle(self):
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f = self.thetype(signature, 'asdf', bar=True)
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.add_something_to__dict__ = True
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f_copy = pickle.loads(pickle.dumps(f))
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(signature(f), signature(f_copy))
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass PartialSubclass(functools.partial):
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pass
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestPartialSubclass(TestPartial):
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    thetype = PartialSubclass
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestPythonPartial(TestPartial):
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    thetype = PythonPartial
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # the python version isn't picklable
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_pickle(self): pass
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestUpdateWrapper(unittest.TestCase):
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def check_wrapper(self, wrapper, wrapped,
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      assigned=functools.WRAPPER_ASSIGNMENTS,
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      updated=functools.WRAPPER_UPDATES):
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check attributes were assigned
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for name in assigned:
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name))
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check attributes were updated
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for name in updated:
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrapper_attr = getattr(wrapper, name)
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            wrapped_attr = getattr(wrapped, name)
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for key in wrapped_attr:
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(wrapped_attr[key] is wrapper_attr[key])
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def _default_update(self):
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """This is a test"""
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is also a test'
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        functools.update_wrapper(wrapper, f)
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return wrapper, f
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_default_update(self):
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wrapper, f = self._default_update()
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f)
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'f')
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.attr, 'This is also a test')
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    @unittest.skipIf(sys.flags.optimize >= 2,
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Docstrings are omitted with -O2 and above")
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_default_update_doc(self):
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wrapper, f = self._default_update()
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, 'This is a test')
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_no_update(self):
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """This is a test"""
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is also a test'
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        functools.update_wrapper(wrapper, f, (), ())
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f, (), ())
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'wrapper')
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, None)
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(hasattr(wrapper, 'attr'))
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_selective_update(self):
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is a different test'
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.dict_attr = dict(a=1, b=2, c=3)
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wrapper.dict_attr = {}
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        assign = ('attr',)
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        update = ('dict_attr',)
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        functools.update_wrapper(wrapper, f, assign, update)
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f, assign, update)
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'wrapper')
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, None)
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.attr, 'This is a different test')
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.dict_attr, f.dict_attr)
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_builtin_update(self):
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Test for bug #1576241
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        functools.update_wrapper(wrapper, max)
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'max')
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(wrapper.__doc__.startswith('max('))
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestWraps(TestUpdateWrapper):
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def _default_update(self):
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """This is a test"""
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is also a test'
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.wraps(f)
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f)
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return wrapper
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_default_update(self):
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wrapper = self._default_update()
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'f')
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.attr, 'This is also a test')
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    @unittest.skipIf(not sys.flags.optimize <= 1,
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Docstrings are omitted with -O2 and above")
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_default_update_doc(self):
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        wrapper = self._default_update()
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, 'This is a test')
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_no_update(self):
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            """This is a test"""
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is also a test'
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.wraps(f, (), ())
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f, (), ())
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'wrapper')
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, None)
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(hasattr(wrapper, 'attr'))
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_selective_update(self):
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def f():
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.attr = 'This is a different test'
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        f.dict_attr = dict(a=1, b=2, c=3)
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def add_dict_attr(f):
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            f.dict_attr = {}
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return f
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        assign = ('attr',)
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        update = ('dict_attr',)
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.wraps(f, assign, update)
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @add_dict_attr
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def wrapper():
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_wrapper(wrapper, f, assign, update)
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__name__, 'wrapper')
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.__doc__, None)
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.attr, 'This is a different test')
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(wrapper.dict_attr, f.dict_attr)
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestReduce(unittest.TestCase):
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_reduce(self):
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Squares:
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, max):
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.max = max
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.sofar = []
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __len__(self): return len(self.sofar)
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __getitem__(self, i):
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if not 0 <= i < self.max: raise IndexError
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                n = len(self.sofar)
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                while n <= i:
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sofar.append(n*n)
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    n += 1
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.sofar[i]
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        reduce = functools.reduce
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(lambda x, y: x+y, ['a', 'b', 'c'], ''), 'abc')
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            reduce(lambda x, y: x+y, [['a', 'c'], [], ['d', 'w']], []),
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ['a','c','d','w']
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        )
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040)
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            reduce(lambda x, y: x*y, range(2,21), 1L),
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            2432902008176640000L
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        )
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(lambda x, y: x+y, Squares(10)), 285)
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(lambda x, y: x+y, Squares(10), 0), 285)
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(lambda x, y: x+y, Squares(0), 0), 0)
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, reduce)
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, reduce, 42, 42)
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, reduce, 42, 42, 42)
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(42, "1"), "1") # func is never called with one item
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, reduce, 42, (42, 42))
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestCmpToKey(unittest.TestCase):
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_cmp_to_key(self):
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def mycmp(x, y):
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return y - x
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(sorted(range(5), key=functools.cmp_to_key(mycmp)),
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         [4, 3, 2, 1, 0])
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_hash(self):
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def mycmp(x, y):
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return y - x
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        key = functools.cmp_to_key(mycmp)
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        k = key(10)
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, hash(k))
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestTotalOrdering(unittest.TestCase):
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_total_ordering_lt(self):
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class A:
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, value):
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.value = value
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __lt__(self, other):
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value < other.value
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value == other.value
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) < A(2))
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) > A(1))
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) <= A(2))
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(1))
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) <= A(2))
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(2))
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_total_ordering_le(self):
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class A:
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, value):
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.value = value
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __le__(self, other):
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value <= other.value
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value == other.value
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) < A(2))
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) > A(1))
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) <= A(2))
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(1))
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) <= A(2))
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(2))
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_total_ordering_gt(self):
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class A:
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, value):
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.value = value
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __gt__(self, other):
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value > other.value
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value == other.value
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) < A(2))
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) > A(1))
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) <= A(2))
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(1))
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) <= A(2))
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(2))
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_total_ordering_ge(self):
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class A:
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, value):
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.value = value
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __ge__(self, other):
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value >= other.value
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.value == other.value
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) < A(2))
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) > A(1))
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(1) <= A(2))
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(1))
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) <= A(2))
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A(2) >= A(2))
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_total_ordering_no_overwrite(self):
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # new methods should not overwrite existing
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class A(str):
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("a") < A("b"))
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("b") > A("a"))
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("a") <= A("b"))
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("b") >= A("a"))
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("b") <= A("b"))
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(A("b") >= A("b"))
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_no_operations_defined(self):
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with self.assertRaises(ValueError):
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            @functools.total_ordering
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            class A:
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bug_10042(self):
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        @functools.total_ordering
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class TestTO:
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, value):
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.value = value
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if isinstance(other, TestTO):
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.value == other.value
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return False
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __lt__(self, other):
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if isinstance(other, TestTO):
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return self.value < other.value
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise TypeError
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with self.assertRaises(TypeError):
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            TestTO(8) <= ()
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main(verbose=None):
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_classes = (
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestPartial,
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestPartialSubclass,
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestPythonPartial,
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestUpdateWrapper,
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestTotalOrdering,
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestWraps,
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        TestReduce,
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    )
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_support.run_unittest(*test_classes)
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # verify reference counting
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if verbose and hasattr(sys, "gettotalrefcount"):
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import gc
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        counts = [None] * 5
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(len(counts)):
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            test_support.run_unittest(*test_classes)
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            gc.collect()
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            counts[i] = sys.gettotalrefcount()
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        print counts
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == '__main__':
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main(verbose=True)
479