<commit_before>#!/usr/bin/env python3
import unittest
from bytecode import Label, Instr, ConcreteInstr, Bytecode, BytecodeBlocks
from bytecode.tests import disassemble, TestCase, get_code


class BytecodeBlocksTests(TestCase):
    maxDiff = 80 * 100

    def test_constructor(self):
        code = BytecodeBlocks()
        self.assertEqual(code.name, "<module>")
        self.assertEqual(code.filename, "<string>")
        self.assertEqual(code.flags, 0)
        self.assertBlocksEqual(code, [])

    def test_attr(self):
        source = """
            first_line = 1

            def func(arg1, arg2, *, arg3):
                x = 1
                y = 2
                return arg1
        """
        code = disassemble(source, filename="hello.py", function=True)
        self.assertEqual(code.argcount, 2)
        self.assertEqual(code.filename, "hello.py")
        self.assertEqual(code.first_lineno, 3)
        self.assertEqual(code.kw_only_argcount, 1)
        self.assertEqual(code.name, "func")
        self.assertEqual(code.cellvars, [])

        code.name = "name"
        code.filename = "filename"
        code.flags = 123
        self.assertEqual(code.name, "name")
        self.assertEqual(code.filename, "filename")
        self.assertEqual(code.flags, 123)

        # FIXME: test non-empty cellvars

    def test_add_del_block(self):
        code = BytecodeBlocks()
        code[0].append(Instr('LOAD_CONST', 0))

        block = code.add_block()
        self.assertEqual(len(code), 2)
        self.assertIs(block, code[1])

        code[1].append(Instr('LOAD_CONST', 2))
        self.assertBlocksEqual(code,
                               [Instr('LOAD_CONST', 0)],
                               [Instr('LOAD_CONST', 2)])

        del code[0]
        self.assertBlocksEqual(code,
                               [Instr('LOAD_CONST', 2)])

        del code[0]
        self.assertEqual(len(code), 0)

    def test_to_bytecode(self):
        blocks = BytecodeBlocks()
        block1 = blocks.add_block()
        blocks[0].extend([Instr('LOAD_NAME', 'test', lineno=1),
                          Instr('POP_JUMP_IF_FALSE', block1, lineno=1),
                          Instr('LOAD_CONST', 5, lineno=2),
                          Instr('STORE_NAME', 'x', lineno=2),
                          Instr('JUMP_FORWARD', block1, lineno=2),
                          Instr('LOAD_CONST', 7, lineno=4),
                          Instr('STORE_NAME', 'x', lineno=4)])
        blocks[1].extend([Instr('LOAD_CONST', None, lineno=4),
                          Instr('RETURN_VALUE', lineno=4)])

        bytecode = blocks.to_bytecode()

        label = Label()
        self.assertEqual(bytecode,
                         [Instr('LOAD_NAME', 'test', lineno=1),
                          Instr('POP_JUMP_IF_FALSE', label, lineno=1),
                          Instr('LOAD_CONST', 5, lineno=2),
                          Instr('STORE_NAME', 'x', lineno=2),
                          Instr('JUMP_FORWARD', label, lineno=2),
                          Instr('LOAD_CONST', 7, lineno=4),
                          Instr('STORE_NAME', 'x', lineno=4),
                          label,
                          Instr('LOAD_CONST', None, lineno=4),
                          Instr('RETURN_VALUE', lineno=4)])
        # FIXME: test other attributes

    def test_to_bytecode_labels(self):
        blocks = BytecodeBlocks()
        label = Label()
        blocks[0].extend([Instr('LOAD_NAME', 'test'),
                          Instr('POP_JUMP_IF_FALSE', label),
                          label])

        with self.assertRaises(ValueError) as cm:
            blocks.to_bytecode()
        self.assertEqual(str(cm.exception), 'Label must not be used in blocks')


    def test_from_bytecode(self):
        bytecode = Bytecode()
        label = Label()<commit_msg>fix test_blocks<commit_after>#!/usr/bin/env python3
import unittest
from bytecode import Label, Instr, ConcreteInstr, Bytecode, BytecodeBlocks
from bytecode.tests import disassemble, TestCase, get_code


class BytecodeBlocksTests(TestCase):
    maxDiff = 80 * 100

    def test_constructor(self):
        code = BytecodeBlocks()
        self.assertEqual(code.name, "<module>")
        self.assertEqual(code.filename, "<string>")
        self.assertEqual(code.flags, 0)
        self.assertBlocksEqual(code, [])

    def test_attr(self):
        source = """
            first_line = 1

            def func(arg1, arg2, *, arg3):
                x = 1
                y = 2
                return arg1
        """
        code = disassemble(source, filename="hello.py", function=True)
        self.assertEqual(code.argcount, 2)
        self.assertEqual(code.filename, "hello.py")
        self.assertEqual(code.first_lineno, 3)
        self.assertEqual(code.kw_only_argcount, 1)
        self.assertEqual(code.name, "func")
        self.assertEqual(code.cellvars, [])

        code.name = "name"
        code.filename = "filename"
        code.flags = 123
        self.assertEqual(code.name, "name")
        self.assertEqual(code.filename, "filename")
        self.assertEqual(code.flags, 123)

        # FIXME: test non-empty cellvars

    def test_add_del_block(self):
        code = BytecodeBlocks()
        code[0].append(Instr('LOAD_CONST', 0))

        block = code.add_block()
        self.assertEqual(len(code), 2)
        self.assertIs(block, code[1])

        code[1].append(Instr('LOAD_CONST', 2))
        self.assertBlocksEqual(code,
                               [Instr('LOAD_CONST', 0)],
                               [Instr('LOAD_CONST', 2)])

        del code[0]
        self.assertBlocksEqual(code,
                               [Instr('LOAD_CONST', 2)])

        del code[0]
        self.assertEqual(len(code), 0)

    def test_to_bytecode(self):
        # if test:
        #     x = 2
        # x = 5
        blocks = BytecodeBlocks()
        blocks.add_block()
        blocks.add_block()
        blocks[0].extend([Instr('LOAD_NAME', 'test', lineno=1),
                          Instr('POP_JUMP_IF_FALSE', blocks[2], lineno=1)])

        blocks[1].extend([Instr('LOAD_CONST', 5, lineno=2),
                          Instr('STORE_NAME', 'x', lineno=2),
                          Instr('JUMP_FORWARD', blocks[2], lineno=2)])

        blocks[2].extend([Instr('LOAD_CONST', 7, lineno=3),
                          Instr('STORE_NAME', 'x', lineno=3),
                          Instr('LOAD_CONST', None, lineno=3),
                          Instr('RETURN_VALUE', lineno=3)])

        bytecode = blocks.to_bytecode()
        label = Label()
        self.assertEqual(bytecode,
                         [Instr('LOAD_NAME', 'test', lineno=1),
                          Instr('POP_JUMP_IF_FALSE', label, lineno=1),
                              Instr('LOAD_CONST', 5, lineno=2),
                              Instr('STORE_NAME', 'x', lineno=2),
                              Instr('JUMP_FORWARD', label, lineno=2),
                          label,
                              Instr('LOAD_CONST', 7, lineno=3),
                              Instr('STORE_NAME', 'x', lineno=3),
                              Instr('LOAD_CONST', None, lineno=3),
                              Instr('RETURN_VALUE', lineno=3)])
        # FIXME: test other attributes

    def test_to_bytecode_labels(self):
        blocks = BytecodeBlocks()
        label = Label()
        blocks[0].extend([Instr('LOAD_NAME', 'test'),
                          Instr('POP_JUMP_IF_FALSE', label),
                          label])

        with self.assertRaises(ValueError) as cm:
            blocks.to_bytecode()
        self.assertEqual(str(cm.exception), 'Label must not be used in blocks')


    def test_from_bytecode(self):
        bytecode = Bytecode()
        label = Label()
{'fraction_non_alphanumeric': 0.12591357866393127, 'fraction_numerical': 0.016412360559046033, 'mean_word_length': 1.7669386307201136, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1854784', 'n_tokens_mistral': 2413, 'n_tokens_neox': 2207, 'n_words': 418}