1import unittest
2import pickle
3import sys
4
5from test import support
6from test.support import import_helper
7
8
9py_operator = import_helper.import_fresh_module('operator',
10                                                blocked=['_operator'])
11c_operator = import_helper.import_fresh_module('operator',
12                                               fresh=['_operator'])
13
14class Seq1:
15    def __init__(self, lst):
16        self.lst = lst
17    def __len__(self):
18        return len(self.lst)
19    def __getitem__(self, i):
20        return self.lst[i]
21    def __add__(self, other):
22        return self.lst + other.lst
23    def __mul__(self, other):
24        return self.lst * other
25    def __rmul__(self, other):
26        return other * self.lst
27
28class Seq2(object):
29    def __init__(self, lst):
30        self.lst = lst
31    def __len__(self):
32        return len(self.lst)
33    def __getitem__(self, i):
34        return self.lst[i]
35    def __add__(self, other):
36        return self.lst + other.lst
37    def __mul__(self, other):
38        return self.lst * other
39    def __rmul__(self, other):
40        return other * self.lst
41
42class BadIterable:
43    def __iter__(self):
44        raise ZeroDivisionError
45
46
47class OperatorTestCase:
48    def test___all__(self):
49        operator = self.module
50        actual_all = set(operator.__all__)
51        computed_all = set()
52        for name in vars(operator):
53            if name.startswith('__'):
54                continue
55            value = getattr(operator, name)
56            if value.__module__ in ('operator', '_operator'):
57                computed_all.add(name)
58        self.assertSetEqual(computed_all, actual_all)
59
60    def test_lt(self):
61        operator = self.module
62        self.assertRaises(TypeError, operator.lt)
63        self.assertRaises(TypeError, operator.lt, 1j, 2j)
64        self.assertFalse(operator.lt(1, 0))
65        self.assertFalse(operator.lt(1, 0.0))
66        self.assertFalse(operator.lt(1, 1))
67        self.assertFalse(operator.lt(1, 1.0))
68        self.assertTrue(operator.lt(1, 2))
69        self.assertTrue(operator.lt(1, 2.0))
70
71    def test_le(self):
72        operator = self.module
73        self.assertRaises(TypeError, operator.le)
74        self.assertRaises(TypeError, operator.le, 1j, 2j)
75        self.assertFalse(operator.le(1, 0))
76        self.assertFalse(operator.le(1, 0.0))
77        self.assertTrue(operator.le(1, 1))
78        self.assertTrue(operator.le(1, 1.0))
79        self.assertTrue(operator.le(1, 2))
80        self.assertTrue(operator.le(1, 2.0))
81
82    def test_eq(self):
83        operator = self.module
84        class C(object):
85            def __eq__(self, other):
86                raise SyntaxError
87        self.assertRaises(TypeError, operator.eq)
88        self.assertRaises(SyntaxError, operator.eq, C(), C())
89        self.assertFalse(operator.eq(1, 0))
90        self.assertFalse(operator.eq(1, 0.0))
91        self.assertTrue(operator.eq(1, 1))
92        self.assertTrue(operator.eq(1, 1.0))
93        self.assertFalse(operator.eq(1, 2))
94        self.assertFalse(operator.eq(1, 2.0))
95
96    def test_ne(self):
97        operator = self.module
98        class C(object):
99            def __ne__(self, other):
100                raise SyntaxError
101        self.assertRaises(TypeError, operator.ne)
102        self.assertRaises(SyntaxError, operator.ne, C(), C())
103        self.assertTrue(operator.ne(1, 0))
104        self.assertTrue(operator.ne(1, 0.0))
105        self.assertFalse(operator.ne(1, 1))
106        self.assertFalse(operator.ne(1, 1.0))
107        self.assertTrue(operator.ne(1, 2))
108        self.assertTrue(operator.ne(1, 2.0))
109
110    def test_ge(self):
111        operator = self.module
112        self.assertRaises(TypeError, operator.ge)
113        self.assertRaises(TypeError, operator.ge, 1j, 2j)
114        self.assertTrue(operator.ge(1, 0))
115        self.assertTrue(operator.ge(1, 0.0))
116        self.assertTrue(operator.ge(1, 1))
117        self.assertTrue(operator.ge(1, 1.0))
118        self.assertFalse(operator.ge(1, 2))
119        self.assertFalse(operator.ge(1, 2.0))
120
121    def test_gt(self):
122        operator = self.module
123        self.assertRaises(TypeError, operator.gt)
124        self.assertRaises(TypeError, operator.gt, 1j, 2j)
125        self.assertTrue(operator.gt(1, 0))
126        self.assertTrue(operator.gt(1, 0.0))
127        self.assertFalse(operator.gt(1, 1))
128        self.assertFalse(operator.gt(1, 1.0))
129        self.assertFalse(operator.gt(1, 2))
130        self.assertFalse(operator.gt(1, 2.0))
131
132    def test_abs(self):
133        operator = self.module
134        self.assertRaises(TypeError, operator.abs)
135        self.assertRaises(TypeError, operator.abs, None)
136        self.assertEqual(operator.abs(-1), 1)
137        self.assertEqual(operator.abs(1), 1)
138
139    def test_add(self):
140        operator = self.module
141        self.assertRaises(TypeError, operator.add)
142        self.assertRaises(TypeError, operator.add, None, None)
143        self.assertEqual(operator.add(3, 4), 7)
144
145    def test_bitwise_and(self):
146        operator = self.module
147        self.assertRaises(TypeError, operator.and_)
148        self.assertRaises(TypeError, operator.and_, None, None)
149        self.assertEqual(operator.and_(0xf, 0xa), 0xa)
150
151    def test_concat(self):
152        operator = self.module
153        self.assertRaises(TypeError, operator.concat)
154        self.assertRaises(TypeError, operator.concat, None, None)
155        self.assertEqual(operator.concat('py', 'thon'), 'python')
156        self.assertEqual(operator.concat([1, 2], [3, 4]), [1, 2, 3, 4])
157        self.assertEqual(operator.concat(Seq1([5, 6]), Seq1([7])), [5, 6, 7])
158        self.assertEqual(operator.concat(Seq2([5, 6]), Seq2([7])), [5, 6, 7])
159        self.assertRaises(TypeError, operator.concat, 13, 29)
160
161    def test_countOf(self):
162        operator = self.module
163        self.assertRaises(TypeError, operator.countOf)
164        self.assertRaises(TypeError, operator.countOf, None, None)
165        self.assertRaises(ZeroDivisionError, operator.countOf, BadIterable(), 1)
166        self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 3), 1)
167        self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 5), 0)
168        # is but not ==
169        nan = float("nan")
170        self.assertEqual(operator.countOf([nan, nan, 21], nan), 2)
171        # == but not is
172        self.assertEqual(operator.countOf([{}, 1, {}, 2], {}), 2)
173
174    def test_delitem(self):
175        operator = self.module
176        a = [4, 3, 2, 1]
177        self.assertRaises(TypeError, operator.delitem, a)
178        self.assertRaises(TypeError, operator.delitem, a, None)
179        self.assertIsNone(operator.delitem(a, 1))
180        self.assertEqual(a, [4, 2, 1])
181
182    def test_floordiv(self):
183        operator = self.module
184        self.assertRaises(TypeError, operator.floordiv, 5)
185        self.assertRaises(TypeError, operator.floordiv, None, None)
186        self.assertEqual(operator.floordiv(5, 2), 2)
187
188    def test_truediv(self):
189        operator = self.module
190        self.assertRaises(TypeError, operator.truediv, 5)
191        self.assertRaises(TypeError, operator.truediv, None, None)
192        self.assertEqual(operator.truediv(5, 2), 2.5)
193
194    def test_getitem(self):
195        operator = self.module
196        a = range(10)
197        self.assertRaises(TypeError, operator.getitem)
198        self.assertRaises(TypeError, operator.getitem, a, None)
199        self.assertEqual(operator.getitem(a, 2), 2)
200
201    def test_indexOf(self):
202        operator = self.module
203        self.assertRaises(TypeError, operator.indexOf)
204        self.assertRaises(TypeError, operator.indexOf, None, None)
205        self.assertRaises(ZeroDivisionError, operator.indexOf, BadIterable(), 1)
206        self.assertEqual(operator.indexOf([4, 3, 2, 1], 3), 1)
207        self.assertRaises(ValueError, operator.indexOf, [4, 3, 2, 1], 0)
208        nan = float("nan")
209        self.assertEqual(operator.indexOf([nan, nan, 21], nan), 0)
210        self.assertEqual(operator.indexOf([{}, 1, {}, 2], {}), 0)
211        it = iter('leave the iterator at exactly the position after the match')
212        self.assertEqual(operator.indexOf(it, 'a'), 2)
213        self.assertEqual(next(it), 'v')
214
215    def test_invert(self):
216        operator = self.module
217        self.assertRaises(TypeError, operator.invert)
218        self.assertRaises(TypeError, operator.invert, None)
219        self.assertEqual(operator.inv(4), -5)
220
221    def test_lshift(self):
222        operator = self.module
223        self.assertRaises(TypeError, operator.lshift)
224        self.assertRaises(TypeError, operator.lshift, None, 42)
225        self.assertEqual(operator.lshift(5, 1), 10)
226        self.assertEqual(operator.lshift(5, 0), 5)
227        self.assertRaises(ValueError, operator.lshift, 2, -1)
228
229    def test_mod(self):
230        operator = self.module
231        self.assertRaises(TypeError, operator.mod)
232        self.assertRaises(TypeError, operator.mod, None, 42)
233        self.assertEqual(operator.mod(5, 2), 1)
234
235    def test_mul(self):
236        operator = self.module
237        self.assertRaises(TypeError, operator.mul)
238        self.assertRaises(TypeError, operator.mul, None, None)
239        self.assertEqual(operator.mul(5, 2), 10)
240
241    def test_matmul(self):
242        operator = self.module
243        self.assertRaises(TypeError, operator.matmul)
244        self.assertRaises(TypeError, operator.matmul, 42, 42)
245        class M:
246            def __matmul__(self, other):
247                return other - 1
248        self.assertEqual(M() @ 42, 41)
249
250    def test_neg(self):
251        operator = self.module
252        self.assertRaises(TypeError, operator.neg)
253        self.assertRaises(TypeError, operator.neg, None)
254        self.assertEqual(operator.neg(5), -5)
255        self.assertEqual(operator.neg(-5), 5)
256        self.assertEqual(operator.neg(0), 0)
257        self.assertEqual(operator.neg(-0), 0)
258
259    def test_bitwise_or(self):
260        operator = self.module
261        self.assertRaises(TypeError, operator.or_)
262        self.assertRaises(TypeError, operator.or_, None, None)
263        self.assertEqual(operator.or_(0xa, 0x5), 0xf)
264
265    def test_pos(self):
266        operator = self.module
267        self.assertRaises(TypeError, operator.pos)
268        self.assertRaises(TypeError, operator.pos, None)
269        self.assertEqual(operator.pos(5), 5)
270        self.assertEqual(operator.pos(-5), -5)
271        self.assertEqual(operator.pos(0), 0)
272        self.assertEqual(operator.pos(-0), 0)
273
274    def test_pow(self):
275        operator = self.module
276        self.assertRaises(TypeError, operator.pow)
277        self.assertRaises(TypeError, operator.pow, None, None)
278        self.assertEqual(operator.pow(3,5), 3**5)
279        self.assertRaises(TypeError, operator.pow, 1)
280        self.assertRaises(TypeError, operator.pow, 1, 2, 3)
281
282    def test_rshift(self):
283        operator = self.module
284        self.assertRaises(TypeError, operator.rshift)
285        self.assertRaises(TypeError, operator.rshift, None, 42)
286        self.assertEqual(operator.rshift(5, 1), 2)
287        self.assertEqual(operator.rshift(5, 0), 5)
288        self.assertRaises(ValueError, operator.rshift, 2, -1)
289
290    def test_contains(self):
291        operator = self.module
292        self.assertRaises(TypeError, operator.contains)
293        self.assertRaises(TypeError, operator.contains, None, None)
294        self.assertRaises(ZeroDivisionError, operator.contains, BadIterable(), 1)
295        self.assertTrue(operator.contains(range(4), 2))
296        self.assertFalse(operator.contains(range(4), 5))
297
298    def test_setitem(self):
299        operator = self.module
300        a = list(range(3))
301        self.assertRaises(TypeError, operator.setitem, a)
302        self.assertRaises(TypeError, operator.setitem, a, None, None)
303        self.assertIsNone(operator.setitem(a, 0, 2))
304        self.assertEqual(a, [2, 1, 2])
305        self.assertRaises(IndexError, operator.setitem, a, 4, 2)
306
307    def test_sub(self):
308        operator = self.module
309        self.assertRaises(TypeError, operator.sub)
310        self.assertRaises(TypeError, operator.sub, None, None)
311        self.assertEqual(operator.sub(5, 2), 3)
312
313    def test_truth(self):
314        operator = self.module
315        class C(object):
316            def __bool__(self):
317                raise SyntaxError
318        self.assertRaises(TypeError, operator.truth)
319        self.assertRaises(SyntaxError, operator.truth, C())
320        self.assertTrue(operator.truth(5))
321        self.assertTrue(operator.truth([0]))
322        self.assertFalse(operator.truth(0))
323        self.assertFalse(operator.truth([]))
324
325    def test_bitwise_xor(self):
326        operator = self.module
327        self.assertRaises(TypeError, operator.xor)
328        self.assertRaises(TypeError, operator.xor, None, None)
329        self.assertEqual(operator.xor(0xb, 0xc), 0x7)
330
331    def test_is(self):
332        operator = self.module
333        a = b = 'xyzpdq'
334        c = a[:3] + b[3:]
335        self.assertRaises(TypeError, operator.is_)
336        self.assertTrue(operator.is_(a, b))
337        self.assertFalse(operator.is_(a,c))
338
339    def test_is_not(self):
340        operator = self.module
341        a = b = 'xyzpdq'
342        c = a[:3] + b[3:]
343        self.assertRaises(TypeError, operator.is_not)
344        self.assertFalse(operator.is_not(a, b))
345        self.assertTrue(operator.is_not(a,c))
346
347    def test_attrgetter(self):
348        operator = self.module
349        class A:
350            pass
351        a = A()
352        a.name = 'arthur'
353        f = operator.attrgetter('name')
354        self.assertEqual(f(a), 'arthur')
355        self.assertRaises(TypeError, f)
356        self.assertRaises(TypeError, f, a, 'dent')
357        self.assertRaises(TypeError, f, a, surname='dent')
358        f = operator.attrgetter('rank')
359        self.assertRaises(AttributeError, f, a)
360        self.assertRaises(TypeError, operator.attrgetter, 2)
361        self.assertRaises(TypeError, operator.attrgetter)
362
363        # multiple gets
364        record = A()
365        record.x = 'X'
366        record.y = 'Y'
367        record.z = 'Z'
368        self.assertEqual(operator.attrgetter('x','z','y')(record), ('X', 'Z', 'Y'))
369        self.assertRaises(TypeError, operator.attrgetter, ('x', (), 'y'))
370
371        class C(object):
372            def __getattr__(self, name):
373                raise SyntaxError
374        self.assertRaises(SyntaxError, operator.attrgetter('foo'), C())
375
376        # recursive gets
377        a = A()
378        a.name = 'arthur'
379        a.child = A()
380        a.child.name = 'thomas'
381        f = operator.attrgetter('child.name')
382        self.assertEqual(f(a), 'thomas')
383        self.assertRaises(AttributeError, f, a.child)
384        f = operator.attrgetter('name', 'child.name')
385        self.assertEqual(f(a), ('arthur', 'thomas'))
386        f = operator.attrgetter('name', 'child.name', 'child.child.name')
387        self.assertRaises(AttributeError, f, a)
388        f = operator.attrgetter('child.')
389        self.assertRaises(AttributeError, f, a)
390        f = operator.attrgetter('.child')
391        self.assertRaises(AttributeError, f, a)
392
393        a.child.child = A()
394        a.child.child.name = 'johnson'
395        f = operator.attrgetter('child.child.name')
396        self.assertEqual(f(a), 'johnson')
397        f = operator.attrgetter('name', 'child.name', 'child.child.name')
398        self.assertEqual(f(a), ('arthur', 'thomas', 'johnson'))
399
400    def test_itemgetter(self):
401        operator = self.module
402        a = 'ABCDE'
403        f = operator.itemgetter(2)
404        self.assertEqual(f(a), 'C')
405        self.assertRaises(TypeError, f)
406        self.assertRaises(TypeError, f, a, 3)
407        self.assertRaises(TypeError, f, a, size=3)
408        f = operator.itemgetter(10)
409        self.assertRaises(IndexError, f, a)
410
411        class C(object):
412            def __getitem__(self, name):
413                raise SyntaxError
414        self.assertRaises(SyntaxError, operator.itemgetter(42), C())
415
416        f = operator.itemgetter('name')
417        self.assertRaises(TypeError, f, a)
418        self.assertRaises(TypeError, operator.itemgetter)
419
420        d = dict(key='val')
421        f = operator.itemgetter('key')
422        self.assertEqual(f(d), 'val')
423        f = operator.itemgetter('nonkey')
424        self.assertRaises(KeyError, f, d)
425
426        # example used in the docs
427        inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
428        getcount = operator.itemgetter(1)
429        self.assertEqual(list(map(getcount, inventory)), [3, 2, 5, 1])
430        self.assertEqual(sorted(inventory, key=getcount),
431            [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)])
432
433        # multiple gets
434        data = list(map(str, range(20)))
435        self.assertEqual(operator.itemgetter(2,10,5)(data), ('2', '10', '5'))
436        self.assertRaises(TypeError, operator.itemgetter(2, 'x', 5), data)
437
438        # interesting indices
439        t = tuple('abcde')
440        self.assertEqual(operator.itemgetter(-1)(t), 'e')
441        self.assertEqual(operator.itemgetter(slice(2, 4))(t), ('c', 'd'))
442
443        # interesting sequences
444        class T(tuple):
445            'Tuple subclass'
446            pass
447        self.assertEqual(operator.itemgetter(0)(T('abc')), 'a')
448        self.assertEqual(operator.itemgetter(0)(['a', 'b', 'c']), 'a')
449        self.assertEqual(operator.itemgetter(0)(range(100, 200)), 100)
450
451    def test_methodcaller(self):
452        operator = self.module
453        self.assertRaises(TypeError, operator.methodcaller)
454        self.assertRaises(TypeError, operator.methodcaller, 12)
455        class A:
456            def foo(self, *args, **kwds):
457                return args[0] + args[1]
458            def bar(self, f=42):
459                return f
460            def baz(*args, **kwds):
461                return kwds['name'], kwds['self']
462        a = A()
463        f = operator.methodcaller('foo')
464        self.assertRaises(IndexError, f, a)
465        f = operator.methodcaller('foo', 1, 2)
466        self.assertEqual(f(a), 3)
467        self.assertRaises(TypeError, f)
468        self.assertRaises(TypeError, f, a, 3)
469        self.assertRaises(TypeError, f, a, spam=3)
470        f = operator.methodcaller('bar')
471        self.assertEqual(f(a), 42)
472        self.assertRaises(TypeError, f, a, a)
473        f = operator.methodcaller('bar', f=5)
474        self.assertEqual(f(a), 5)
475        f = operator.methodcaller('baz', name='spam', self='eggs')
476        self.assertEqual(f(a), ('spam', 'eggs'))
477
478    def test_inplace(self):
479        operator = self.module
480        class C(object):
481            def __iadd__     (self, other): return "iadd"
482            def __iand__     (self, other): return "iand"
483            def __ifloordiv__(self, other): return "ifloordiv"
484            def __ilshift__  (self, other): return "ilshift"
485            def __imod__     (self, other): return "imod"
486            def __imul__     (self, other): return "imul"
487            def __imatmul__  (self, other): return "imatmul"
488            def __ior__      (self, other): return "ior"
489            def __ipow__     (self, other): return "ipow"
490            def __irshift__  (self, other): return "irshift"
491            def __isub__     (self, other): return "isub"
492            def __itruediv__ (self, other): return "itruediv"
493            def __ixor__     (self, other): return "ixor"
494            def __getitem__(self, other): return 5  # so that C is a sequence
495        c = C()
496        self.assertEqual(operator.iadd     (c, 5), "iadd")
497        self.assertEqual(operator.iand     (c, 5), "iand")
498        self.assertEqual(operator.ifloordiv(c, 5), "ifloordiv")
499        self.assertEqual(operator.ilshift  (c, 5), "ilshift")
500        self.assertEqual(operator.imod     (c, 5), "imod")
501        self.assertEqual(operator.imul     (c, 5), "imul")
502        self.assertEqual(operator.imatmul  (c, 5), "imatmul")
503        self.assertEqual(operator.ior      (c, 5), "ior")
504        self.assertEqual(operator.ipow     (c, 5), "ipow")
505        self.assertEqual(operator.irshift  (c, 5), "irshift")
506        self.assertEqual(operator.isub     (c, 5), "isub")
507        self.assertEqual(operator.itruediv (c, 5), "itruediv")
508        self.assertEqual(operator.ixor     (c, 5), "ixor")
509        self.assertEqual(operator.iconcat  (c, c), "iadd")
510
511    def test_length_hint(self):
512        operator = self.module
513        class X(object):
514            def __init__(self, value):
515                self.value = value
516
517            def __length_hint__(self):
518                if type(self.value) is type:
519                    raise self.value
520                else:
521                    return self.value
522
523        self.assertEqual(operator.length_hint([], 2), 0)
524        self.assertEqual(operator.length_hint(iter([1, 2, 3])), 3)
525
526        self.assertEqual(operator.length_hint(X(2)), 2)
527        self.assertEqual(operator.length_hint(X(NotImplemented), 4), 4)
528        self.assertEqual(operator.length_hint(X(TypeError), 12), 12)
529        with self.assertRaises(TypeError):
530            operator.length_hint(X("abc"))
531        with self.assertRaises(ValueError):
532            operator.length_hint(X(-2))
533        with self.assertRaises(LookupError):
534            operator.length_hint(X(LookupError))
535
536    def test_call(self):
537        operator = self.module
538
539        def func(*args, **kwargs): return args, kwargs
540
541        self.assertEqual(operator.call(func), ((), {}))
542        self.assertEqual(operator.call(func, 0, 1), ((0, 1), {}))
543        self.assertEqual(operator.call(func, a=2, obj=3),
544                         ((), {"a": 2, "obj": 3}))
545        self.assertEqual(operator.call(func, 0, 1, a=2, obj=3),
546                         ((0, 1), {"a": 2, "obj": 3}))
547
548    def test_dunder_is_original(self):
549        operator = self.module
550
551        names = [name for name in dir(operator) if not name.startswith('_')]
552        for name in names:
553            orig = getattr(operator, name)
554            dunder = getattr(operator, '__' + name.strip('_') + '__', None)
555            if dunder:
556                self.assertIs(dunder, orig)
557
558class PyOperatorTestCase(OperatorTestCase, unittest.TestCase):
559    module = py_operator
560
561@unittest.skipUnless(c_operator, 'requires _operator')
562class COperatorTestCase(OperatorTestCase, unittest.TestCase):
563    module = c_operator
564
565
566class OperatorPickleTestCase:
567    def copy(self, obj, proto):
568        with support.swap_item(sys.modules, 'operator', self.module):
569            pickled = pickle.dumps(obj, proto)
570        with support.swap_item(sys.modules, 'operator', self.module2):
571            return pickle.loads(pickled)
572
573    def test_attrgetter(self):
574        attrgetter = self.module.attrgetter
575        class A:
576            pass
577        a = A()
578        a.x = 'X'
579        a.y = 'Y'
580        a.z = 'Z'
581        a.t = A()
582        a.t.u = A()
583        a.t.u.v = 'V'
584        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
585            with self.subTest(proto=proto):
586                f = attrgetter('x')
587                f2 = self.copy(f, proto)
588                self.assertEqual(repr(f2), repr(f))
589                self.assertEqual(f2(a), f(a))
590                # multiple gets
591                f = attrgetter('x', 'y', 'z')
592                f2 = self.copy(f, proto)
593                self.assertEqual(repr(f2), repr(f))
594                self.assertEqual(f2(a), f(a))
595                # recursive gets
596                f = attrgetter('t.u.v')
597                f2 = self.copy(f, proto)
598                self.assertEqual(repr(f2), repr(f))
599                self.assertEqual(f2(a), f(a))
600
601    def test_itemgetter(self):
602        itemgetter = self.module.itemgetter
603        a = 'ABCDE'
604        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
605            with self.subTest(proto=proto):
606                f = itemgetter(2)
607                f2 = self.copy(f, proto)
608                self.assertEqual(repr(f2), repr(f))
609                self.assertEqual(f2(a), f(a))
610                # multiple gets
611                f = itemgetter(2, 0, 4)
612                f2 = self.copy(f, proto)
613                self.assertEqual(repr(f2), repr(f))
614                self.assertEqual(f2(a), f(a))
615
616    def test_methodcaller(self):
617        methodcaller = self.module.methodcaller
618        class A:
619            def foo(self, *args, **kwds):
620                return args[0] + args[1]
621            def bar(self, f=42):
622                return f
623            def baz(*args, **kwds):
624                return kwds['name'], kwds['self']
625        a = A()
626        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
627            with self.subTest(proto=proto):
628                f = methodcaller('bar')
629                f2 = self.copy(f, proto)
630                self.assertEqual(repr(f2), repr(f))
631                self.assertEqual(f2(a), f(a))
632                # positional args
633                f = methodcaller('foo', 1, 2)
634                f2 = self.copy(f, proto)
635                self.assertEqual(repr(f2), repr(f))
636                self.assertEqual(f2(a), f(a))
637                # keyword args
638                f = methodcaller('bar', f=5)
639                f2 = self.copy(f, proto)
640                self.assertEqual(repr(f2), repr(f))
641                self.assertEqual(f2(a), f(a))
642                f = methodcaller('baz', self='eggs', name='spam')
643                f2 = self.copy(f, proto)
644                # Can't test repr consistently with multiple keyword args
645                self.assertEqual(f2(a), f(a))
646
647class PyPyOperatorPickleTestCase(OperatorPickleTestCase, unittest.TestCase):
648    module = py_operator
649    module2 = py_operator
650
651@unittest.skipUnless(c_operator, 'requires _operator')
652class PyCOperatorPickleTestCase(OperatorPickleTestCase, unittest.TestCase):
653    module = py_operator
654    module2 = c_operator
655
656@unittest.skipUnless(c_operator, 'requires _operator')
657class CPyOperatorPickleTestCase(OperatorPickleTestCase, unittest.TestCase):
658    module = c_operator
659    module2 = py_operator
660
661@unittest.skipUnless(c_operator, 'requires _operator')
662class CCOperatorPickleTestCase(OperatorPickleTestCase, unittest.TestCase):
663    module = c_operator
664    module2 = c_operator
665
666
667if __name__ == "__main__":
668    unittest.main()
669