Python dis 模块,get_instructions() 实例源码

我们从Python开源项目中,提取了以下39个代码示例,用于说明如何使用dis.get_instructions()

项目:interface    作者:ssanderson    | 项目源码 | 文件源码
def accessed_attributes_of_local(f, local_name):
        """
        Get a list of attributes of ``local_name`` accessed by ``f``.

        The analysis performed by this function is conservative, meaning that
        it's not guaranteed to find **all** attributes used.
        """
        used = set()
        # Find sequences of the form: LOAD_FAST(local_name), LOAD_ATTR(<name>).
        # This will find all usages of the form ``local_name.<name>``.
        #
        # It will **NOT** find usages in which ``local_name`` is aliased to
        # another name.
        for first, second in sliding_window(dis.get_instructions(f), 2):
            if first.opname == 'LOAD_FAST' and first.argval == local_name:
                if second.opname in ('LOAD_ATTR', 'STORE_ATTR'):
                    used.add(second.argval)
        return used
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_elim_jump_after_return1(self):
        # Eliminate dead code: jumps immediately after returns can't be reached
        def f(cond1, cond2):
            if cond1: return 1
            if cond2: return 2
            while 1:
                return 3
            while 1:
                if cond1: return 4
                return 5
            return 6
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 6)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_constant_folding(self):
        # Issue #11244: aggressive constant folding.
        exprs = [
            '3 * -5',
            '-3 * 5',
            '2 * (3 * 4)',
            '(2 * 3) * 4',
            '(-1, 2, 3)',
            '(1, -2, 3)',
            '(1, 2, -3)',
            '(1, 2, -3) * 6',
            'lambda x: x in {(3 * -5) + (-1 - 6), (1, -2, 3) * 2, None}',
        ]
        for e in exprs:
            code = compile(e, '', 'single')
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('UNARY_'))
                self.assertFalse(instr.opname.startswith('BINARY_'))
                self.assertFalse(instr.opname.startswith('BUILD_'))
项目:pure_interface    作者:aranzgeo    | 项目源码 | 文件源码
def _get_instructions(code_obj):
    if hasattr(dis, 'get_instructions'):
        return list(dis.get_instructions(code_obj))

    instructions = []
    instruction = None
    for byte in code_obj.co_code:
        byte = _six_ord(byte)
        if instruction is None:
            instruction = [byte]
        else:
            instruction.append(byte)
        if instruction[0] < dis.HAVE_ARGUMENT or len(instruction) == 3:
            op_code = instruction[0]
            op_name = dis.opname[op_code]
            if instruction[0] < dis.HAVE_ARGUMENT:
                instructions.append(_Instruction(op_code, op_name, None, None))
            else:
                arg = instruction[1]
                instructions.append(_Instruction(op_code, op_name, arg, arg))
            instruction = None
    return instructions
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_elim_jump_after_return1(self):
        # Eliminate dead code: jumps immediately after returns can't be reached
        def f(cond1, cond2):
            if cond1: return 1
            if cond2: return 2
            while 1:
                return 3
            while 1:
                if cond1: return 4
                return 5
            return 6
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 6)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_constant_folding(self):
        # Issue #11244: aggressive constant folding.
        exprs = [
            '3 * -5',
            '-3 * 5',
            '2 * (3 * 4)',
            '(2 * 3) * 4',
            '(-1, 2, 3)',
            '(1, -2, 3)',
            '(1, 2, -3)',
            '(1, 2, -3) * 6',
            'lambda x: x in {(3 * -5) + (-1 - 6), (1, -2, 3) * 2, None}',
        ]
        for e in exprs:
            code = compile(e, '', 'single')
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('UNARY_'))
                self.assertFalse(instr.opname.startswith('BINARY_'))
                self.assertFalse(instr.opname.startswith('BUILD_'))
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def assertInBytecode(self, x, opname, argval=_UNSPECIFIED):
        """Returns instr if op is found, otherwise throws AssertionError"""
        for instr in dis.get_instructions(x):
            if instr.opname == opname:
                if argval is _UNSPECIFIED or instr.argval == argval:
                    return instr
        disassembly = self.get_disassembly_as_string(x)
        if argval is _UNSPECIFIED:
            msg = '%s not found in bytecode:\n%s' % (opname, disassembly)
        else:
            msg = '(%s,%r) not found in bytecode:\n%s'
            msg = msg % (opname, argval, disassembly)
        self.fail(msg)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED):
        """Throws AssertionError if op is found"""
        for instr in dis.get_instructions(x):
            if instr.opname == opname:
                disassembly = self.get_disassembly_as_string(co)
                if opargval is _UNSPECIFIED:
                    msg = '%s occurs in bytecode:\n%s' % (opname, disassembly)
                elif instr.argval == argval:
                    msg = '(%s,%r) occurs in bytecode:\n%s'
                    msg = msg % (opname, argval, disassembly)
                self.fail(msg)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_folding_of_tuples_of_constants(self):
        for line, elem in (
            ('a = 1,2,3', (1, 2, 3)),
            ('("a","b","c")', ('a', 'b', 'c')),
            ('a,b,c = 1,2,3', (1, 2, 3)),
            ('(None, 1, None)', (None, 1, None)),
            ('((1, 2), 3, 4)', ((1, 2), 3, 4)),
            ):
            code = compile(line,'','single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            self.assertNotInBytecode(code, 'BUILD_TUPLE')

        # Long tuples should be folded too.
        code = compile(repr(tuple(range(10000))),'','single')
        self.assertNotInBytecode(code, 'BUILD_TUPLE')
        # One LOAD_CONST for the tuple, one for the None return value
        load_consts = [instr for instr in dis.get_instructions(code)
                              if instr.opname == 'LOAD_CONST']
        self.assertEqual(len(load_consts), 2)

        # Bug 1053819:  Tuple of constants misidentified when presented with:
        # . . . opcode_with_arg 100   unary_opcode   BUILD_TUPLE 1  . . .
        # The following would segfault upon compilation
        def crater():
            (~[
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
            ],)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_folding_of_binops_on_constants(self):
        for line, elem in (
            ('a = 2+3+4', 9),                   # chained fold
            ('"@"*4', '@@@@'),                  # check string ops
            ('a="abc" + "def"', 'abcdef'),      # check string ops
            ('a = 3**4', 81),                   # binary power
            ('a = 3*4', 12),                    # binary multiply
            ('a = 13//4', 3),                   # binary floor divide
            ('a = 14%4', 2),                    # binary modulo
            ('a = 2+3', 5),                     # binary add
            ('a = 13-4', 9),                    # binary subtract
            ('a = (12,13)[1]', 13),             # binary subscr
            ('a = 13 << 2', 52),                # binary lshift
            ('a = 13 >> 2', 3),                 # binary rshift
            ('a = 13 & 7', 5),                  # binary and
            ('a = 13 ^ 7', 10),                 # binary xor
            ('a = 13 | 7', 15),                 # binary or
            ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('BINARY_'))

        # Verify that unfoldables are skipped
        code = compile('a=2+"b"', '', 'single')
        self.assertInBytecode(code, 'LOAD_CONST', 2)
        self.assertInBytecode(code, 'LOAD_CONST', 'b')

        # Verify that large sequences do not result from folding
        code = compile('a="x"*1000', '', 'single')
        self.assertInBytecode(code, 'LOAD_CONST', 1000)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_folding_of_unaryops_on_constants(self):
        for line, elem in (
            ('-0.5', -0.5),                     # unary negative
            ('-0.0', -0.0),                     # -0.0
            ('-(1.0-1.0)', -0.0),               # -0.0 after folding
            ('-0', 0),                          # -0
            ('~-2', 1),                         # unary invert
            ('+1', 1),                          # unary positive
        ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('UNARY_'))

        # Check that -0.0 works after marshaling
        def negzero():
            return -(1.0-1.0)

        for instr in dis.get_instructions(code):
            self.assertFalse(instr.opname.startswith('UNARY_'))

        # Verify that unfoldables are skipped
        for line, elem, opname in (
            ('-"abc"', 'abc', 'UNARY_NEGATIVE'),
            ('~"abc"', 'abc', 'UNARY_INVERT'),
        ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            self.assertInBytecode(code, opname)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_elim_jump_to_return(self):
        # JUMP_FORWARD to RETURN -->  RETURN
        def f(cond, true_value, false_value):
            return true_value if cond else false_value
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 2)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_elim_jump_after_return2(self):
        # Eliminate dead code: jumps immediately after returns can't be reached
        def f(cond1, cond2):
            while 1:
                if cond1: return 4
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        # There should be one jump for the while loop.
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'JUMP_ABSOLUTE']
        self.assertEqual(len(returns), 1)
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 2)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_default_first_line(self):
        actual = dis.get_instructions(simple)
        self.assertEqual(list(actual), expected_opinfo_simple)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_outer(self):
        actual = dis.get_instructions(outer, first_line=expected_outer_line)
        self.assertEqual(list(actual), expected_opinfo_outer)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_nested(self):
        with captured_stdout():
            f = outer()
        actual = dis.get_instructions(f, first_line=expected_f_line)
        self.assertEqual(list(actual), expected_opinfo_f)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_doubly_nested(self):
        with captured_stdout():
            inner = outer()()
        actual = dis.get_instructions(inner, first_line=expected_inner_line)
        self.assertEqual(list(actual), expected_opinfo_inner)
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_jumpy(self):
        actual = dis.get_instructions(jumpy, first_line=expected_jumpy_line)
        self.assertEqual(list(actual), expected_opinfo_jumpy)

# get_instructions has its own tests above, so can rely on it to validate
# the object oriented API
项目:ouroboros    作者:pybee    | 项目源码 | 文件源码
def test_iteration(self):
        for obj in [_f, _C(1).__init__, "a=1", _f.__code__]:
            with self.subTest(obj=obj):
                via_object = list(dis.Bytecode(obj))
                via_generator = list(dis.get_instructions(obj))
                self.assertEqual(via_object, via_generator)
项目:Vanstein    作者:SunDwarf    | 项目源码 | 文件源码
def instructions(self):
        if not self._instructions:
            self._instructions = list(dis.get_instructions(self))

        return self._instructions
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def assertInBytecode(self, x, opname, argval=_UNSPECIFIED):
        """Returns instr if op is found, otherwise throws AssertionError"""
        for instr in dis.get_instructions(x):
            if instr.opname == opname:
                if argval is _UNSPECIFIED or instr.argval == argval:
                    return instr
        disassembly = self.get_disassembly_as_string(x)
        if argval is _UNSPECIFIED:
            msg = '%s not found in bytecode:\n%s' % (opname, disassembly)
        else:
            msg = '(%s,%r) not found in bytecode:\n%s'
            msg = msg % (opname, argval, disassembly)
        self.fail(msg)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED):
        """Throws AssertionError if op is found"""
        for instr in dis.get_instructions(x):
            if instr.opname == opname:
                disassembly = self.get_disassembly_as_string(co)
                if opargval is _UNSPECIFIED:
                    msg = '%s occurs in bytecode:\n%s' % (opname, disassembly)
                elif instr.argval == argval:
                    msg = '(%s,%r) occurs in bytecode:\n%s'
                    msg = msg % (opname, argval, disassembly)
                self.fail(msg)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_folding_of_tuples_of_constants(self):
        for line, elem in (
            ('a = 1,2,3', (1, 2, 3)),
            ('("a","b","c")', ('a', 'b', 'c')),
            ('a,b,c = 1,2,3', (1, 2, 3)),
            ('(None, 1, None)', (None, 1, None)),
            ('((1, 2), 3, 4)', ((1, 2), 3, 4)),
            ):
            code = compile(line,'','single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            self.assertNotInBytecode(code, 'BUILD_TUPLE')

        # Long tuples should be folded too.
        code = compile(repr(tuple(range(10000))),'','single')
        self.assertNotInBytecode(code, 'BUILD_TUPLE')
        # One LOAD_CONST for the tuple, one for the None return value
        load_consts = [instr for instr in dis.get_instructions(code)
                              if instr.opname == 'LOAD_CONST']
        self.assertEqual(len(load_consts), 2)

        # Bug 1053819:  Tuple of constants misidentified when presented with:
        # . . . opcode_with_arg 100   unary_opcode   BUILD_TUPLE 1  . . .
        # The following would segfault upon compilation
        def crater():
            (~[
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
            ],)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_folding_of_binops_on_constants(self):
        for line, elem in (
            ('a = 2+3+4', 9),                   # chained fold
            ('"@"*4', '@@@@'),                  # check string ops
            ('a="abc" + "def"', 'abcdef'),      # check string ops
            ('a = 3**4', 81),                   # binary power
            ('a = 3*4', 12),                    # binary multiply
            ('a = 13//4', 3),                   # binary floor divide
            ('a = 14%4', 2),                    # binary modulo
            ('a = 2+3', 5),                     # binary add
            ('a = 13-4', 9),                    # binary subtract
            ('a = (12,13)[1]', 13),             # binary subscr
            ('a = 13 << 2', 52),                # binary lshift
            ('a = 13 >> 2', 3),                 # binary rshift
            ('a = 13 & 7', 5),                  # binary and
            ('a = 13 ^ 7', 10),                 # binary xor
            ('a = 13 | 7', 15),                 # binary or
            ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('BINARY_'))

        # Verify that unfoldables are skipped
        code = compile('a=2+"b"', '', 'single')
        self.assertInBytecode(code, 'LOAD_CONST', 2)
        self.assertInBytecode(code, 'LOAD_CONST', 'b')

        # Verify that large sequences do not result from folding
        code = compile('a="x"*1000', '', 'single')
        self.assertInBytecode(code, 'LOAD_CONST', 1000)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_folding_of_unaryops_on_constants(self):
        for line, elem in (
            ('-0.5', -0.5),                     # unary negative
            ('-0.0', -0.0),                     # -0.0
            ('-(1.0-1.0)', -0.0),               # -0.0 after folding
            ('-0', 0),                          # -0
            ('~-2', 1),                         # unary invert
            ('+1', 1),                          # unary positive
        ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            for instr in dis.get_instructions(code):
                self.assertFalse(instr.opname.startswith('UNARY_'))

        # Check that -0.0 works after marshaling
        def negzero():
            return -(1.0-1.0)

        for instr in dis.get_instructions(code):
            self.assertFalse(instr.opname.startswith('UNARY_'))

        # Verify that unfoldables are skipped
        for line, elem, opname in (
            ('-"abc"', 'abc', 'UNARY_NEGATIVE'),
            ('~"abc"', 'abc', 'UNARY_INVERT'),
        ):
            code = compile(line, '', 'single')
            self.assertInBytecode(code, 'LOAD_CONST', elem)
            self.assertInBytecode(code, opname)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_elim_jump_to_return(self):
        # JUMP_FORWARD to RETURN -->  RETURN
        def f(cond, true_value, false_value):
            return true_value if cond else false_value
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        self.assertNotInBytecode(f, 'JUMP_ABSOLUTE')
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 2)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_elim_jump_after_return2(self):
        # Eliminate dead code: jumps immediately after returns can't be reached
        def f(cond1, cond2):
            while 1:
                if cond1: return 4
        self.assertNotInBytecode(f, 'JUMP_FORWARD')
        # There should be one jump for the while loop.
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'JUMP_ABSOLUTE']
        self.assertEqual(len(returns), 1)
        returns = [instr for instr in dis.get_instructions(f)
                          if instr.opname == 'RETURN_VALUE']
        self.assertEqual(len(returns), 2)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_default_first_line(self):
        actual = dis.get_instructions(simple)
        self.assertEqual(list(actual), expected_opinfo_simple)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_outer(self):
        actual = dis.get_instructions(outer, first_line=expected_outer_line)
        self.assertEqual(list(actual), expected_opinfo_outer)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_nested(self):
        with captured_stdout():
            f = outer()
        actual = dis.get_instructions(f, first_line=expected_f_line)
        self.assertEqual(list(actual), expected_opinfo_f)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_doubly_nested(self):
        with captured_stdout():
            inner = outer()()
        actual = dis.get_instructions(inner, first_line=expected_inner_line)
        self.assertEqual(list(actual), expected_opinfo_inner)
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_jumpy(self):
        actual = dis.get_instructions(jumpy, first_line=expected_jumpy_line)
        self.assertEqual(list(actual), expected_opinfo_jumpy)

# get_instructions has its own tests above, so can rely on it to validate
# the object oriented API
项目:kbe_server    作者:xiaohaoppy    | 项目源码 | 文件源码
def test_iteration(self):
        for obj in [_f, _C(1).__init__, "a=1", _f.__code__]:
            with self.subTest(obj=obj):
                via_object = list(dis.Bytecode(obj))
                via_generator = list(dis.get_instructions(obj))
                self.assertEqual(via_object, via_generator)
项目:OpTrace    作者:tsyganov-ivan    | 项目源码 | 文件源码
def print_codeobj(self, codeobj):
        dis.dis(codeobj)
        self.print_codeobj_attr(codeobj)
        print('!'*80)
        for st in dis.get_instructions(codeobj):
            print(st.offset, st, sep=' -> ')
        print('!' * 80)
        for code in codeobj.co_code:
            print(opcode.opname[code])
项目:mac-package-build    作者:persepolisdm    | 项目源码 | 文件源码
def get_instructions(code):
        """
        Iterator parsing the bytecode into easy-usable minimal emulation of
        Python 3.4 `dis.Instruction` instances.
        """

        # shortcuts
        HAVE_ARGUMENT = dis.HAVE_ARGUMENT
        EXTENDED_ARG = dis.EXTENDED_ARG

        class Instruction:
            # Minimal emulation of Python 3.4 dis.Instruction
            def __init__(self, opcode, oparg):
                self.opname = dis.opname[opcode]
                self.arg = oparg
                # opcode, argval, argrepr, offset, is_jump_target and
                # starts_line are not used by our code, so we leave them away
                # here.

        code = code.co_code
        extended_arg = 0
        i = 0
        n = len(code)
        while i < n:
            c = code[i]
            i = i + 1
            op = _cOrd(c)
            if op >= HAVE_ARGUMENT:
                oparg = _cOrd(code[i]) + _cOrd(code[i + 1]) * 256 + extended_arg
                extended_arg = 0
                i += 2
                if op == EXTENDED_ARG:
                    extended_arg = oparg*65536
            else:
                oparg = None
            yield Instruction(op, oparg)


#FIXME: Leverage this rather than magic numbers below.
项目:pywren    作者:pywren    | 项目源码 | 文件源码
def _walk_global_ops(code):
        """
        Yield (opcode, argument number) tuples for all
        global-referencing instructions in *code*.
        """
        for instr in dis.get_instructions(code):
            op = instr.opcode
            if op in GLOBAL_OPS:
                yield op, instr.arg
项目:pythia    作者:elazarg    | 项目源码 | 文件源码
def get_instructions(f):
    return update_break_instruction(dis.get_instructions(f))
项目:zenchmarks    作者:squeaky-pl    | 项目源码 | 文件源码
def _is_safe_generator(code):
    '''
    Examine the code of an async generator to see if it appears
    unsafe with respect to async finalization.  A generator
    is unsafe if it utilizes any of the following constructs:

    1. Use of async-code in a finally block

       try:
           yield v
       finally:
           await coro()

    2. Use of yield inside an async context manager

       async with m:
           ...
           yield v
           ...

    3. Use of async-code in try-except

       try:
           yield v
       except Exception:
           await coro()
    '''
    def _is_unsafe_block(instr, end_offset=-1):
        is_generator = False
        in_final = False
        is_unsafe = False
        for op in instr:
            if op.offset == end_offset:
                in_final = True
            if op.opname == 'YIELD_VALUE':
                is_generator = True
            if op.opname == 'END_FINALLY':
                return (is_generator, is_unsafe)
            if op.opname in {'SETUP_FINALLY', 'SETUP_EXCEPT', 'SETUP_ASYNC_WITH'}:
                is_g, is_u = _is_unsafe_block(instr, op.argval)
                is_generator |= is_g
                is_unsafe |= is_u
            if op.opname == 'YIELD_FROM' and is_generator and in_final:
                is_unsafe = True
        return (is_generator, is_unsafe)

    return not _is_unsafe_block(dis.get_instructions(code))[1]
项目:OpTrace    作者:tsyganov-ivan    | 项目源码 | 文件源码
def wrap_code(self, codeobj, codeobj_id=0):
        codes = []
        constants = [
            self.wrap_code(item, self.get_codeobj_id())
            if isinstance(item, CodeType) else item
            for item in codeobj.co_consts
        ]

        update_offset = partial(self.calculate_offset, code=codeobj.co_code)
        for st in dis.get_instructions(codeobj):
            self.mark(codeobj_id, st)
            constants.append(
                lambda co_id=codeobj_id, opcode=st: self.visit(co_id, opcode)
            )
            codes.extend(self.make_trace(len(constants) - 1))
            codes.append(st.opcode)

            if st.opcode in opcode.hasjrel:
                current_position = update_offset(st.offset)
                taget_position = update_offset(st.argval) - self.TRACE_CODE_LEN - self.TRACE_CODE_LEN
                new_delta = taget_position - current_position
                codes.extend(self.make_args(new_delta - self.AGR_OP_LEN))
            elif st.opcode in opcode.hasjabs:
                codes.extend(self.make_args(
                    update_offset(st.arg) - self.TRACE_CODE_LEN - self.TRACE_CODE_LEN
                ))
            elif st.opcode >= opcode.HAVE_ARGUMENT:
                codes.extend(self.make_args(st.arg))

        new_code = CodeType(
            codeobj.co_argcount,
            codeobj.co_kwonlyargcount,
            codeobj.co_nlocals,
            codeobj.co_stacksize + self.AGR_OP_LEN,
            codeobj.co_flags,
            bytes(codes),  # codestring
            tuple(constants),  # constants
            codeobj.co_names,
            codeobj.co_varnames,
            codeobj.co_filename,
            codeobj.co_name,
            codeobj.co_firstlineno,
            codeobj.co_lnotab,
            codeobj.co_freevars,
            codeobj.co_cellvars,
        )
        return new_code