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