1import dis
2from itertools import combinations, product
3import unittest
4
5from test.support.bytecode_helper import BytecodeTestCase
6
7
8def count_instr_recursively(f, opname):
9    count = 0
10    for instr in dis.get_instructions(f):
11        if instr.opname == opname:
12            count += 1
13    if hasattr(f, '__code__'):
14        f = f.__code__
15    for c in f.co_consts:
16        if hasattr(c, 'co_code'):
17            count += count_instr_recursively(c, opname)
18    return count
19
20
21class TestTranforms(BytecodeTestCase):
22
23    def check_jump_targets(self, code):
24        instructions = list(dis.get_instructions(code))
25        targets = {instr.offset: instr for instr in instructions}
26        for instr in instructions:
27            if 'JUMP_' not in instr.opname:
28                continue
29            tgt = targets[instr.argval]
30            # jump to unconditional jump
31            if tgt.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD'):
32                self.fail(f'{instr.opname} at {instr.offset} '
33                          f'jumps to {tgt.opname} at {tgt.offset}')
34            # unconditional jump to RETURN_VALUE
35            if (instr.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD') and
36                tgt.opname == 'RETURN_VALUE'):
37                self.fail(f'{instr.opname} at {instr.offset} '
38                          f'jumps to {tgt.opname} at {tgt.offset}')
39            # JUMP_IF_*_OR_POP jump to conditional jump
40            if '_OR_POP' in instr.opname and 'JUMP_IF_' in tgt.opname:
41                self.fail(f'{instr.opname} at {instr.offset} '
42                          f'jumps to {tgt.opname} at {tgt.offset}')
43
44    def check_lnotab(self, code):
45        "Check that the lnotab byte offsets are sensible."
46        code = dis._get_code_object(code)
47        lnotab = list(dis.findlinestarts(code))
48        # Don't bother checking if the line info is sensible, because
49        # most of the line info we can get at comes from lnotab.
50        min_bytecode = min(t[0] for t in lnotab)
51        max_bytecode = max(t[0] for t in lnotab)
52        self.assertGreaterEqual(min_bytecode, 0)
53        self.assertLess(max_bytecode, len(code.co_code))
54        # This could conceivably test more (and probably should, as there
55        # aren't very many tests of lnotab), if peepholer wasn't scheduled
56        # to be replaced anyway.
57
58    def test_unot(self):
59        # UNARY_NOT POP_JUMP_IF_FALSE  -->  POP_JUMP_IF_TRUE'
60        def unot(x):
61            if not x == 2:
62                del x
63        self.assertNotInBytecode(unot, 'UNARY_NOT')
64        self.assertNotInBytecode(unot, 'POP_JUMP_IF_FALSE')
65        self.assertInBytecode(unot, 'POP_JUMP_IF_TRUE')
66        self.check_lnotab(unot)
67
68    def test_elim_inversion_of_is_or_in(self):
69        for line, cmp_op, invert in (
70            ('not a is b', 'IS_OP', 1,),
71            ('not a is not b', 'IS_OP', 0,),
72            ('not a in b', 'CONTAINS_OP', 1,),
73            ('not a not in b', 'CONTAINS_OP', 0,),
74            ):
75            with self.subTest(line=line):
76                code = compile(line, '', 'single')
77                self.assertInBytecode(code, cmp_op, invert)
78                self.check_lnotab(code)
79
80    def test_global_as_constant(self):
81        # LOAD_GLOBAL None/True/False  -->  LOAD_CONST None/True/False
82        def f():
83            x = None
84            x = None
85            return x
86        def g():
87            x = True
88            return x
89        def h():
90            x = False
91            return x
92
93        for func, elem in ((f, None), (g, True), (h, False)):
94            with self.subTest(func=func):
95                self.assertNotInBytecode(func, 'LOAD_GLOBAL')
96                self.assertInBytecode(func, 'LOAD_CONST', elem)
97                self.check_lnotab(func)
98
99        def f():
100            'Adding a docstring made this test fail in Py2.5.0'
101            return None
102
103        self.assertNotInBytecode(f, 'LOAD_GLOBAL')
104        self.assertInBytecode(f, 'LOAD_CONST', None)
105        self.check_lnotab(f)
106
107    def test_while_one(self):
108        # Skip over:  LOAD_CONST trueconst  POP_JUMP_IF_FALSE xx
109        def f():
110            while 1:
111                pass
112            return list
113        for elem in ('LOAD_CONST', 'POP_JUMP_IF_FALSE'):
114            self.assertNotInBytecode(f, elem)
115        for elem in ('JUMP_ABSOLUTE',):
116            self.assertInBytecode(f, elem)
117        self.check_lnotab(f)
118
119    def test_pack_unpack(self):
120        for line, elem in (
121            ('a, = a,', 'LOAD_CONST',),
122            ('a, b = a, b', 'ROT_TWO',),
123            ('a, b, c = a, b, c', 'ROT_THREE',),
124            ):
125            with self.subTest(line=line):
126                code = compile(line,'','single')
127                self.assertInBytecode(code, elem)
128                self.assertNotInBytecode(code, 'BUILD_TUPLE')
129                self.assertNotInBytecode(code, 'UNPACK_TUPLE')
130                self.check_lnotab(code)
131
132    def test_folding_of_tuples_of_constants(self):
133        for line, elem in (
134            ('a = 1,2,3', (1, 2, 3)),
135            ('("a","b","c")', ('a', 'b', 'c')),
136            ('a,b,c = 1,2,3', (1, 2, 3)),
137            ('(None, 1, None)', (None, 1, None)),
138            ('((1, 2), 3, 4)', ((1, 2), 3, 4)),
139            ):
140            with self.subTest(line=line):
141                code = compile(line,'','single')
142                self.assertInBytecode(code, 'LOAD_CONST', elem)
143                self.assertNotInBytecode(code, 'BUILD_TUPLE')
144                self.check_lnotab(code)
145
146        # Long tuples should be folded too.
147        code = compile(repr(tuple(range(10000))),'','single')
148        self.assertNotInBytecode(code, 'BUILD_TUPLE')
149        # One LOAD_CONST for the tuple, one for the None return value
150        load_consts = [instr for instr in dis.get_instructions(code)
151                              if instr.opname == 'LOAD_CONST']
152        self.assertEqual(len(load_consts), 2)
153        self.check_lnotab(code)
154
155        # Bug 1053819:  Tuple of constants misidentified when presented with:
156        # . . . opcode_with_arg 100   unary_opcode   BUILD_TUPLE 1  . . .
157        # The following would segfault upon compilation
158        def crater():
159            (~[
160                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
161                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
162                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
163                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
164                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
165                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
166                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
167                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
168                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
169                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
170            ],)
171        self.check_lnotab(crater)
172
173    def test_folding_of_lists_of_constants(self):
174        for line, elem in (
175            # in/not in constants with BUILD_LIST should be folded to a tuple:
176            ('a in [1,2,3]', (1, 2, 3)),
177            ('a not in ["a","b","c"]', ('a', 'b', 'c')),
178            ('a in [None, 1, None]', (None, 1, None)),
179            ('a not in [(1, 2), 3, 4]', ((1, 2), 3, 4)),
180            ):
181            with self.subTest(line=line):
182                code = compile(line, '', 'single')
183                self.assertInBytecode(code, 'LOAD_CONST', elem)
184                self.assertNotInBytecode(code, 'BUILD_LIST')
185                self.check_lnotab(code)
186
187    def test_folding_of_sets_of_constants(self):
188        for line, elem in (
189            # in/not in constants with BUILD_SET should be folded to a frozenset:
190            ('a in {1,2,3}', frozenset({1, 2, 3})),
191            ('a not in {"a","b","c"}', frozenset({'a', 'c', 'b'})),
192            ('a in {None, 1, None}', frozenset({1, None})),
193            ('a not in {(1, 2), 3, 4}', frozenset({(1, 2), 3, 4})),
194            ('a in {1, 2, 3, 3, 2, 1}', frozenset({1, 2, 3})),
195            ):
196            with self.subTest(line=line):
197                code = compile(line, '', 'single')
198                self.assertNotInBytecode(code, 'BUILD_SET')
199                self.assertInBytecode(code, 'LOAD_CONST', elem)
200                self.check_lnotab(code)
201
202        # Ensure that the resulting code actually works:
203        def f(a):
204            return a in {1, 2, 3}
205
206        def g(a):
207            return a not in {1, 2, 3}
208
209        self.assertTrue(f(3))
210        self.assertTrue(not f(4))
211        self.check_lnotab(f)
212
213        self.assertTrue(not g(3))
214        self.assertTrue(g(4))
215        self.check_lnotab(g)
216
217
218    def test_folding_of_binops_on_constants(self):
219        for line, elem in (
220            ('a = 2+3+4', 9),                   # chained fold
221            ('"@"*4', '@@@@'),                  # check string ops
222            ('a="abc" + "def"', 'abcdef'),      # check string ops
223            ('a = 3**4', 81),                   # binary power
224            ('a = 3*4', 12),                    # binary multiply
225            ('a = 13//4', 3),                   # binary floor divide
226            ('a = 14%4', 2),                    # binary modulo
227            ('a = 2+3', 5),                     # binary add
228            ('a = 13-4', 9),                    # binary subtract
229            ('a = (12,13)[1]', 13),             # binary subscr
230            ('a = 13 << 2', 52),                # binary lshift
231            ('a = 13 >> 2', 3),                 # binary rshift
232            ('a = 13 & 7', 5),                  # binary and
233            ('a = 13 ^ 7', 10),                 # binary xor
234            ('a = 13 | 7', 15),                 # binary or
235            ):
236            with self.subTest(line=line):
237                code = compile(line, '', 'single')
238                self.assertInBytecode(code, 'LOAD_CONST', elem)
239                for instr in dis.get_instructions(code):
240                    self.assertFalse(instr.opname.startswith('BINARY_'))
241                self.check_lnotab(code)
242
243        # Verify that unfoldables are skipped
244        code = compile('a=2+"b"', '', 'single')
245        self.assertInBytecode(code, 'LOAD_CONST', 2)
246        self.assertInBytecode(code, 'LOAD_CONST', 'b')
247        self.check_lnotab(code)
248
249        # Verify that large sequences do not result from folding
250        code = compile('a="x"*10000', '', 'single')
251        self.assertInBytecode(code, 'LOAD_CONST', 10000)
252        self.assertNotIn("x"*10000, code.co_consts)
253        self.check_lnotab(code)
254        code = compile('a=1<<1000', '', 'single')
255        self.assertInBytecode(code, 'LOAD_CONST', 1000)
256        self.assertNotIn(1<<1000, code.co_consts)
257        self.check_lnotab(code)
258        code = compile('a=2**1000', '', 'single')
259        self.assertInBytecode(code, 'LOAD_CONST', 1000)
260        self.assertNotIn(2**1000, code.co_consts)
261        self.check_lnotab(code)
262
263    def test_binary_subscr_on_unicode(self):
264        # valid code get optimized
265        code = compile('"foo"[0]', '', 'single')
266        self.assertInBytecode(code, 'LOAD_CONST', 'f')
267        self.assertNotInBytecode(code, 'BINARY_SUBSCR')
268        self.check_lnotab(code)
269        code = compile('"\u0061\uffff"[1]', '', 'single')
270        self.assertInBytecode(code, 'LOAD_CONST', '\uffff')
271        self.assertNotInBytecode(code,'BINARY_SUBSCR')
272        self.check_lnotab(code)
273
274        # With PEP 393, non-BMP char get optimized
275        code = compile('"\U00012345"[0]', '', 'single')
276        self.assertInBytecode(code, 'LOAD_CONST', '\U00012345')
277        self.assertNotInBytecode(code, 'BINARY_SUBSCR')
278        self.check_lnotab(code)
279
280        # invalid code doesn't get optimized
281        # out of range
282        code = compile('"fuu"[10]', '', 'single')
283        self.assertInBytecode(code, 'BINARY_SUBSCR')
284        self.check_lnotab(code)
285
286    def test_folding_of_unaryops_on_constants(self):
287        for line, elem in (
288            ('-0.5', -0.5),                     # unary negative
289            ('-0.0', -0.0),                     # -0.0
290            ('-(1.0-1.0)', -0.0),               # -0.0 after folding
291            ('-0', 0),                          # -0
292            ('~-2', 1),                         # unary invert
293            ('+1', 1),                          # unary positive
294        ):
295            with self.subTest(line=line):
296                code = compile(line, '', 'single')
297                self.assertInBytecode(code, 'LOAD_CONST', elem)
298                for instr in dis.get_instructions(code):
299                    self.assertFalse(instr.opname.startswith('UNARY_'))
300                self.check_lnotab(code)
301
302        # Check that -0.0 works after marshaling
303        def negzero():
304            return -(1.0-1.0)
305
306        for instr in dis.get_instructions(negzero):
307            self.assertFalse(instr.opname.startswith('UNARY_'))
308        self.check_lnotab(negzero)
309
310        # Verify that unfoldables are skipped
311        for line, elem, opname in (
312            ('-"abc"', 'abc', 'UNARY_NEGATIVE'),
313            ('~"abc"', 'abc', 'UNARY_INVERT'),
314        ):
315            with self.subTest(line=line):
316                code = compile(line, '', 'single')
317                self.assertInBytecode(code, 'LOAD_CONST', elem)
318                self.assertInBytecode(code, opname)
319                self.check_lnotab(code)
320
321    def test_elim_extra_return(self):
322        # RETURN LOAD_CONST None RETURN  -->  RETURN
323        def f(x):
324            return x
325        self.assertNotInBytecode(f, 'LOAD_CONST', None)
326        returns = [instr for instr in dis.get_instructions(f)
327                          if instr.opname == 'RETURN_VALUE']
328        self.assertEqual(len(returns), 1)
329        self.check_lnotab(f)
330
331    def test_elim_jump_to_return(self):
332        # JUMP_FORWARD to RETURN -->  RETURN
333        def f(cond, true_value, false_value):
334            # Intentionally use two-line expression to test issue37213.
335            return (true_value if cond
336                    else false_value)
337        self.check_jump_targets(f)
338        self.assertNotInBytecode(f, 'JUMP_FORWARD')
339        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
340        returns = [instr for instr in dis.get_instructions(f)
341                          if instr.opname == 'RETURN_VALUE']
342        self.assertEqual(len(returns), 2)
343        self.check_lnotab(f)
344
345    def test_elim_jump_to_uncond_jump(self):
346        # POP_JUMP_IF_FALSE to JUMP_FORWARD --> POP_JUMP_IF_FALSE to non-jump
347        def f():
348            if a:
349                # Intentionally use two-line expression to test issue37213.
350                if (c
351                    or d):
352                    foo()
353            else:
354                baz()
355        self.check_jump_targets(f)
356        self.check_lnotab(f)
357
358    def test_elim_jump_to_uncond_jump2(self):
359        # POP_JUMP_IF_FALSE to JUMP_ABSOLUTE --> POP_JUMP_IF_FALSE to non-jump
360        def f():
361            while a:
362                # Intentionally use two-line expression to test issue37213.
363                if (c
364                    or d):
365                    a = foo()
366        self.check_jump_targets(f)
367        self.check_lnotab(f)
368
369    def test_elim_jump_to_uncond_jump3(self):
370        # Intentionally use two-line expressions to test issue37213.
371        # JUMP_IF_FALSE_OR_POP to JUMP_IF_FALSE_OR_POP --> JUMP_IF_FALSE_OR_POP to non-jump
372        def f(a, b, c):
373            return ((a and b)
374                    and c)
375        self.check_jump_targets(f)
376        self.check_lnotab(f)
377        self.assertEqual(count_instr_recursively(f, 'JUMP_IF_FALSE_OR_POP'), 2)
378        # JUMP_IF_TRUE_OR_POP to JUMP_IF_TRUE_OR_POP --> JUMP_IF_TRUE_OR_POP to non-jump
379        def f(a, b, c):
380            return ((a or b)
381                    or c)
382        self.check_jump_targets(f)
383        self.check_lnotab(f)
384        self.assertEqual(count_instr_recursively(f, 'JUMP_IF_TRUE_OR_POP'), 2)
385        # JUMP_IF_FALSE_OR_POP to JUMP_IF_TRUE_OR_POP --> POP_JUMP_IF_FALSE to non-jump
386        def f(a, b, c):
387            return ((a and b)
388                    or c)
389        self.check_jump_targets(f)
390        self.check_lnotab(f)
391        self.assertNotInBytecode(f, 'JUMP_IF_FALSE_OR_POP')
392        self.assertInBytecode(f, 'JUMP_IF_TRUE_OR_POP')
393        self.assertInBytecode(f, 'POP_JUMP_IF_FALSE')
394        # JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump
395        def f(a, b, c):
396            return ((a or b)
397                    and c)
398        self.check_jump_targets(f)
399        self.check_lnotab(f)
400        self.assertNotInBytecode(f, 'JUMP_IF_TRUE_OR_POP')
401        self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP')
402        self.assertInBytecode(f, 'POP_JUMP_IF_TRUE')
403
404    def test_elim_jump_after_return1(self):
405        # Eliminate dead code: jumps immediately after returns can't be reached
406        def f(cond1, cond2):
407            if cond1: return 1
408            if cond2: return 2
409            while 1:
410                return 3
411            while 1:
412                if cond1: return 4
413                return 5
414            return 6
415        self.assertNotInBytecode(f, 'JUMP_FORWARD')
416        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
417        returns = [instr for instr in dis.get_instructions(f)
418                          if instr.opname == 'RETURN_VALUE']
419        self.assertLessEqual(len(returns), 6)
420        self.check_lnotab(f)
421
422    def test_make_function_doesnt_bail(self):
423        def f():
424            def g()->1+1:
425                pass
426            return g
427        self.assertNotInBytecode(f, 'BINARY_OP')
428        self.check_lnotab(f)
429
430    def test_constant_folding(self):
431        # Issue #11244: aggressive constant folding.
432        exprs = [
433            '3 * -5',
434            '-3 * 5',
435            '2 * (3 * 4)',
436            '(2 * 3) * 4',
437            '(-1, 2, 3)',
438            '(1, -2, 3)',
439            '(1, 2, -3)',
440            '(1, 2, -3) * 6',
441            'lambda x: x in {(3 * -5) + (-1 - 6), (1, -2, 3) * 2, None}',
442        ]
443        for e in exprs:
444            with self.subTest(e=e):
445                code = compile(e, '', 'single')
446                for instr in dis.get_instructions(code):
447                    self.assertFalse(instr.opname.startswith('UNARY_'))
448                    self.assertFalse(instr.opname.startswith('BINARY_'))
449                    self.assertFalse(instr.opname.startswith('BUILD_'))
450                self.check_lnotab(code)
451
452    def test_in_literal_list(self):
453        def containtest():
454            return x in [a, b]
455        self.assertEqual(count_instr_recursively(containtest, 'BUILD_LIST'), 0)
456        self.check_lnotab(containtest)
457
458    def test_iterate_literal_list(self):
459        def forloop():
460            for x in [a, b]:
461                pass
462        self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0)
463        self.check_lnotab(forloop)
464
465    def test_condition_with_binop_with_bools(self):
466        def f():
467            if True or False:
468                return 1
469            return 0
470        self.assertEqual(f(), 1)
471        self.check_lnotab(f)
472
473    def test_if_with_if_expression(self):
474        # Check bpo-37289
475        def f(x):
476            if (True if x else False):
477                return True
478            return False
479        self.assertTrue(f(True))
480        self.check_lnotab(f)
481
482    def test_trailing_nops(self):
483        # Check the lnotab of a function that even after trivial
484        # optimization has trailing nops, which the lnotab adjustment has to
485        # handle properly (bpo-38115).
486        def f(x):
487            while 1:
488                return 3
489            while 1:
490                return 5
491            return 6
492        self.check_lnotab(f)
493
494    def test_assignment_idiom_in_comprehensions(self):
495        def listcomp():
496            return [y for x in a for y in [f(x)]]
497        self.assertEqual(count_instr_recursively(listcomp, 'FOR_ITER'), 1)
498        def setcomp():
499            return {y for x in a for y in [f(x)]}
500        self.assertEqual(count_instr_recursively(setcomp, 'FOR_ITER'), 1)
501        def dictcomp():
502            return {y: y for x in a for y in [f(x)]}
503        self.assertEqual(count_instr_recursively(dictcomp, 'FOR_ITER'), 1)
504        def genexpr():
505            return (y for x in a for y in [f(x)])
506        self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1)
507
508    def test_format_combinations(self):
509        flags = '-+ #0'
510        testcases = [
511            *product(('', '1234', 'абвг'), 'sra'),
512            *product((1234, -1234), 'duioxX'),
513            *product((1234.5678901, -1234.5678901), 'duifegFEG'),
514            *product((float('inf'), -float('inf')), 'fegFEG'),
515        ]
516        width_precs = [
517            *product(('', '1', '30'), ('', '.', '.0', '.2')),
518            ('', '.40'),
519            ('30', '.40'),
520        ]
521        for value, suffix in testcases:
522            for width, prec in width_precs:
523                for r in range(len(flags) + 1):
524                    for spec in combinations(flags, r):
525                        fmt = '%' + ''.join(spec) + width + prec + suffix
526                        with self.subTest(fmt=fmt, value=value):
527                            s1 = fmt % value
528                            s2 = eval(f'{fmt!r} % (x,)', {'x': value})
529                            self.assertEqual(s2, s1, f'{fmt = }')
530
531    def test_format_misc(self):
532        def format(fmt, *values):
533            vars = [f'x{i+1}' for i in range(len(values))]
534            if len(vars) == 1:
535                args = '(' + vars[0] + ',)'
536            else:
537                args = '(' + ', '.join(vars) + ')'
538            return eval(f'{fmt!r} % {args}', dict(zip(vars, values)))
539
540        self.assertEqual(format('string'), 'string')
541        self.assertEqual(format('x = %s!', 1234), 'x = 1234!')
542        self.assertEqual(format('x = %d!', 1234), 'x = 1234!')
543        self.assertEqual(format('x = %x!', 1234), 'x = 4d2!')
544        self.assertEqual(format('x = %f!', 1234), 'x = 1234.000000!')
545        self.assertEqual(format('x = %s!', 1234.5678901), 'x = 1234.5678901!')
546        self.assertEqual(format('x = %f!', 1234.5678901), 'x = 1234.567890!')
547        self.assertEqual(format('x = %d!', 1234.5678901), 'x = 1234!')
548        self.assertEqual(format('x = %s%% %%%%', 1234), 'x = 1234% %%')
549        self.assertEqual(format('x = %s!', '%% %s'), 'x = %% %s!')
550        self.assertEqual(format('x = %s, y = %d', 12, 34), 'x = 12, y = 34')
551
552    def test_format_errors(self):
553        with self.assertRaisesRegex(TypeError,
554                    'not enough arguments for format string'):
555            eval("'%s' % ()")
556        with self.assertRaisesRegex(TypeError,
557                    'not all arguments converted during string formatting'):
558            eval("'%s' % (x, y)", {'x': 1, 'y': 2})
559        with self.assertRaisesRegex(ValueError, 'incomplete format'):
560            eval("'%s%' % (x,)", {'x': 1234})
561        with self.assertRaisesRegex(ValueError, 'incomplete format'):
562            eval("'%s%%%' % (x,)", {'x': 1234})
563        with self.assertRaisesRegex(TypeError,
564                    'not enough arguments for format string'):
565            eval("'%s%z' % (x,)", {'x': 1234})
566        with self.assertRaisesRegex(ValueError, 'unsupported format character'):
567            eval("'%s%z' % (x, 5)", {'x': 1234})
568        with self.assertRaisesRegex(TypeError, 'a real number is required, not str'):
569            eval("'%d' % (x,)", {'x': '1234'})
570        with self.assertRaisesRegex(TypeError, 'an integer is required, not float'):
571            eval("'%x' % (x,)", {'x': 1234.56})
572        with self.assertRaisesRegex(TypeError, 'an integer is required, not str'):
573            eval("'%x' % (x,)", {'x': '1234'})
574        with self.assertRaisesRegex(TypeError, 'must be real number, not str'):
575            eval("'%f' % (x,)", {'x': '1234'})
576        with self.assertRaisesRegex(TypeError,
577                    'not enough arguments for format string'):
578            eval("'%s, %s' % (x, *y)", {'x': 1, 'y': []})
579        with self.assertRaisesRegex(TypeError,
580                    'not all arguments converted during string formatting'):
581            eval("'%s, %s' % (x, *y)", {'x': 1, 'y': [2, 3]})
582
583
584class TestBuglets(unittest.TestCase):
585
586    def test_bug_11510(self):
587        # folded constant set optimization was commingled with the tuple
588        # unpacking optimization which would fail if the set had duplicate
589        # elements so that the set length was unexpected
590        def f():
591            x, y = {1, 1}
592            return x, y
593        with self.assertRaises(ValueError):
594            f()
595
596    def test_bpo_42057(self):
597        for i in range(10):
598            try:
599                raise Exception
600            except Exception or Exception:
601                pass
602
603    def test_bpo_45773_pop_jump_if_true(self):
604        compile("while True or spam: pass", "<test>", "exec")
605
606    def test_bpo_45773_pop_jump_if_false(self):
607        compile("while True or not spam: pass", "<test>", "exec")
608
609
610if __name__ == "__main__":
611    unittest.main()
612