DebugClients/Python/coverage/bytecode.py

Sun, 03 Jul 2011 18:01:53 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 03 Jul 2011 18:01:53 +0200
changeset 1166
a94b0a2fafd7
parent 790
2c0ea0163ef4
child 3495
fac17a82b431
permissions
-rw-r--r--

Extended the unit test interface to support skipped tests, expected failures and unexpected successes and to better cope with Python2 scripts when run from the eric IDE.

"""Bytecode manipulation for coverage.py"""

import opcode, sys, types

class ByteCode(object):
    """A single bytecode."""
    def __init__(self):
        self.offset = -1
        self.op = -1
        self.arg = -1
        self.next_offset = -1
        self.jump_to = -1


class ByteCodes(object):
    """Iterator over byte codes in `code`.

    Returns `ByteCode` objects.

    """
    def __init__(self, code):
        self.code = code
        self.offset = 0

    if sys.hexversion > 0x03000000:
        def __getitem__(self, i):
            return self.code[i]
    else:
        def __getitem__(self, i):
            return ord(self.code[i])

    def __iter__(self):
        return self

    def __next__(self):
        if self.offset >= len(self.code):
            raise StopIteration

        bc = ByteCode()
        bc.op = self[self.offset]
        bc.offset = self.offset

        next_offset = self.offset+1
        if bc.op >= opcode.HAVE_ARGUMENT:
            bc.arg = self[self.offset+1] + 256*self[self.offset+2]
            next_offset += 2

            label = -1
            if bc.op in opcode.hasjrel:
                label = next_offset + bc.arg
            elif bc.op in opcode.hasjabs:
                label = bc.arg
            bc.jump_to = label

        bc.next_offset = self.offset = next_offset
        return bc

    next = __next__     # Py2k uses an old-style non-dunder name.


class CodeObjects(object):
    """Iterate over all the code objects in `code`."""
    def __init__(self, code):
        self.stack = [code]

    def __iter__(self):
        return self

    def __next__(self):
        if self.stack:
            # We're going to return the code object on the stack, but first
            # push its children for later returning.
            code = self.stack.pop()
            for c in code.co_consts:
                if isinstance(c, types.CodeType):
                    self.stack.append(c)
            return code

        raise StopIteration

    next = __next__

#
# eflag: FileType = Python2

eric ide

mercurial