Пример #1
0
def dis(x=None):
    """
    Disassemble classes, methods, functions, or code.

    With no argument, disassemble the last traceback.
    """

    if x is None:
        dismodule.distb()
        return
    if type(x) is types.InstanceType:
        x = x.__class__
    if hasattr(x, 'im_func'):
        x = x.im_func
    if isinstance(x, types.FunctionType):
        x = sys.get_func_code(x)
    if hasattr(x, '__dict__'):
        items = x.__dict__.items()
        items.sort()
        for name, x1 in items:
            if type(x1) in (types.MethodType, types.FunctionType,
                            types.CodeType, types.ClassType):
                print "Disassembly of %s:" % name
                try:
                    dis(x1)
                except TypeError, msg:
                    print "Sorry:", msg
                print
Пример #2
0
def findsource(object):
    """Return the entire source file and starting line number for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of all the lines
    in the file and the line number indexes a line in that list.  An IOError
    is raised if the source code cannot be retrieved."""
    file = inspect.getsourcefile(object) or inspect.getfile(object)
    module = inspect.getmodule(object, file)
    if module:
        lines = linecache.getlines(file, module.__dict__)
    else:
        lines = linecache.getlines(file)
    if not lines:
        raise IOError('could not get source code')

    if inspect.ismodule(object):
        return lines, 0

    if inspect.isclass(object):
        name = object.__name__
        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
        # make some effort to find the best matching class definition:
        # use the one with the least indentation, which is the one
        # that's most probably not inside a function definition.
        candidates = []
        for i in range(len(lines)):
            match = pat.match(lines[i])
            if match:
                # if it's at toplevel, it's already the best one
                if lines[i][0] == 'c':
                    return lines, i
                # else add whitespace to candidate list
                candidates.append((match.group(1), i))
        if candidates:
            # this will sort by whitespace, and by line number,
            # less whitespace first
            candidates.sort()
            return lines, candidates[0][1]
        else:
            raise IOError('could not find class definition')

    if inspect.ismethod(object):
        object = object.__func__
    if inspect.isfunction(object):
        object = sys.get_func_code(object)
    if inspect.istraceback(object):
        object = object.tb_frame
    if inspect.isframe(object):
        object = object.f_code
    if inspect.iscode(object):
        if not hasattr(object, 'co_firstlineno'):
            raise IOError('could not find function definition')
        lnum = object.co_firstlineno - 1
        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
        while lnum > 0:
            if pat.match(lines[lnum]): break
            lnum = lnum - 1
        return lines, lnum
    raise IOError('could not find code object')
Пример #3
0
def findsource(object):
    """Return the entire source file and starting line number for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of all the lines
    in the file and the line number indexes a line in that list.  An IOError
    is raised if the source code cannot be retrieved."""
    file = inspect.getsourcefile(object) or inspect.getfile(object)
    module = inspect.getmodule(object, file)
    if module:
        lines = linecache.getlines(file, module.__dict__)
    else:
        lines = linecache.getlines(file)
    if not lines:
        raise IOError('could not get source code')

    if inspect.ismodule(object):
        return lines, 0

    if inspect.isclass(object):
        name = object.__name__
        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
        # make some effort to find the best matching class definition:
        # use the one with the least indentation, which is the one
        # that's most probably not inside a function definition.
        candidates = []
        for i in range(len(lines)):
            match = pat.match(lines[i])
            if match:
                # if it's at toplevel, it's already the best one
                if lines[i][0] == 'c':
                    return lines, i
                # else add whitespace to candidate list
                candidates.append((match.group(1), i))
        if candidates:
            # this will sort by whitespace, and by line number,
            # less whitespace first
            candidates.sort()
            return lines, candidates[0][1]
        else:
            raise IOError('could not find class definition')

    if inspect.ismethod(object):
        object = object.im_func
    if isinstance(object, FunctionType):
        object = sys.get_func_code(object)
    if inspect.istraceback(object):
        object = object.tb_frame
    if inspect.isframe(object):
        object = object.f_code
    if inspect.iscode(object):
        if not hasattr(object, 'co_firstlineno'):
            raise IOError('could not find function definition')
        lnum = object.co_firstlineno - 1
        pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
        while lnum > 0:
            if pat.match(lines[lnum]): break
            lnum = lnum - 1
        return lines, lnum
    raise IOError('could not find code object')
Пример #4
0
def dis(x=None):
    """Disassemble classes, methods, functions, or code.

    With no argument, disassemble the last traceback.

    """
    if x is None:
        dismodule.distb()
        return
    if hasattr(x, '__func__'):
        x = x.__func__
    if hasattr(x, '__code__'):
        x = getattr(x, '__code__')
    if isinstance(x, FunctionType):
        x = sys.get_func_code(x)
    if hasattr(x, '__dict__'):
        items = sorted(x.__dict__.items())
        for name, x1 in items:
            if isinstance(x1, (types.MethodType, types.FunctionType,
                               types.CodeType, type)):
                print("Disassembly of %s:" % name)
                try:
                    dis(x1)
                except TypeError as msg:
                    print("Sorry:", msg)
                print()
    elif hasattr(x, 'co_code'):
        dismodule.disassemble(x)
    elif isinstance(x, (bytes, bytearray)):
        dismodule.disassemble_string(x)
    else:
        raise TypeError("don't know how to disassemble %s objects" %
                        type(x).__name__)
Пример #5
0
def dis(x=None):
    """
    Disassemble classes, methods, functions, or code.

    With no argument, disassemble the last traceback.
    """

    if x is None:
        dismodule.distb()
        return
    if type(x) is types.InstanceType:
        x = x.__class__
    if hasattr(x, "im_func"):
        x = x.im_func
    if isinstance(x, types.FunctionType):
        x = sys.get_func_code(x)
    if hasattr(x, "__dict__"):
        items = x.__dict__.items()
        items.sort()
        for name, x1 in items:
            if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType):
                print "Disassembly of %s:" % name
                try:
                    dis(x1)
                except TypeError, msg:
                    print "Sorry:", msg
                print
Пример #6
0
def dis(x=None):
    """Disassemble classes, methods, functions, or code.

    With no argument, disassemble the last traceback.

    """
    if x is None:
        dismodule.distb()
        return
    if hasattr(x, '__func__'):
        x = x.__func__
    if hasattr(x, '__code__'):
        x = getattr(x, '__code__')
    if isinstance(x, FunctionType):
        x = sys.get_func_code(x)
    if hasattr(x, '__dict__'):
        items = sorted(x.__dict__.items())
        for name, x1 in items:
            if isinstance(
                    x1,
                (types.MethodType, types.FunctionType, types.CodeType, type)):
                print("Disassembly of %s:" % name)
                try:
                    dis(x1)
                except TypeError as msg:
                    print("Sorry:", msg)
                print()
    elif hasattr(x, 'co_code'):
        dismodule.disassemble(x)
    elif isinstance(x, (bytes, bytearray)):
        dismodule.disassemble_string(x)
    else:
        raise TypeError("don't know how to disassemble %s objects" %
                        type(x).__name__)
Пример #7
0
def isgeneratorfunction(object):
    """Return true if the object is a user-defined generator function.

    Generator function objects provides same attributes as functions.

    See isfunction.__doc__ for attributes listing."""
    if (isinstance(object, FunctionType) or inspect.ismethod(object)) and \
        sys.get_func_code(object).co_flags & CO_GENERATOR:
        return True
Пример #8
0
def isgeneratorfunction(object):
    """Return true if the object is a user-defined generator function.

    Generator function objects provides same attributes as functions.

    See isfunction.__doc__ for attributes listing."""
    if (isinstance(object, FunctionType) or inspect.ismethod(object)) and \
        sys.get_func_code(object).co_flags & CO_GENERATOR:
        return True
Пример #9
0
def getargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of four things is returned: (args, varargs, varkw, defaults).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    """

    if inspect.ismethod(func):
        func = func.im_func
    if not inspect.isfunction(func):
        raise TypeError('arg is not a Python function')
    args, varargs, varkw = inspect.getargs(sys.get_func_code(func))
    return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
Пример #10
0
def getargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of four things is returned: (args, varargs, varkw, defaults).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    """

    if inspect.ismethod(func):
        func = func.im_func
    if not inspect.isfunction(func):
        raise TypeError("arg is not a Python function")
    args, varargs, varkw = inspect.getargs(sys.get_func_code(func))
    return args, varargs, varkw, func.func_defaults
Пример #11
0
def getfullargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    'kwonlyargs' is a list of keyword-only argument names.
    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
    'annotations' is a dictionary mapping argument names to annotations.

    The first four items in the tuple correspond to getargspec().
    """

    if inspect.ismethod(func):
        func = func.__func__
    if not inspect.isfunction(func):
        raise TypeError('arg is not a Python function')
    args, varargs, kwonlyargs, varkw = inspect._getfullargs(sys.get_func_code(func))
    return inspect.FullArgSpec(args, varargs, varkw, func.__defaults__,
            kwonlyargs, func.__kwdefaults__, func.__annotations__)
Пример #12
0
def getfile(object):
    """Work out which source or compiled file an object was defined in."""
    if inspect.ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('arg is a built-in module')
    if inspect.isclass(object):
        object = sys.modules.get(object.__module__)
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('arg is a built-in class')
    if inspect.ismethod(object):
        object = object.__func__
    if inspect.isfunction(object):
        object = sys.get_func_code(object)
    if inspect.istraceback(object):
        object = object.tb_frame
    if inspect.isframe(object):
        object = object.f_code
    if inspect.iscode(object):
        return object.co_filename
    raise TypeError('arg is not a module, class, method, '
                    'function, traceback, frame, or code object')
Пример #13
0
def getfile(object):
    """Work out which source or compiled file an object was defined in."""
    if inspect.ismodule(object):
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('arg is a built-in module')
    if inspect.isclass(object):
        object = sys.modules.get(object.__module__)
        if hasattr(object, '__file__'):
            return object.__file__
        raise TypeError('arg is a built-in class')
    if inspect.ismethod(object):
        object = object.__func__
    if inspect.isfunction(object):
        object = sys.get_func_code(object)
    if inspect.istraceback(object):
        object = object.tb_frame
    if inspect.isframe(object):
        object = object.f_code
    if inspect.iscode(object):
        return object.co_filename
    raise TypeError('arg is not a module, class, method, '
                    'function, traceback, frame, or code object')
Пример #14
0
    def __decorator(function):

        if type(function) is not FunctionType:
            raise TypeError("Argument to the guard decorator is not a function.")

        func_args = getargs(sys.get_func_code(function))[0]
        len_args = len(func_args) - 1

        def __func(*args, **kwargs):
            for i, param in enumerate(args):
                req = spec.get(func_args[i], _marker)
                if req is not _marker and type(param) is not req:
                    raise TypeError(
                        "%s has to be %r" % (func_args[i], req)
                        )
            for name, param in kwargs.iteritems():
                if name in spec and type(param) is not spec[name]:
                    raise TypeError("%s has to be %r" % (name, spec[name]))
            return function(*args, **kwargs)

        __func.__name__ = function.__name__
        __func.__doc__ = function.__doc__

        return __func
Пример #15
0
def getfullargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    'kwonlyargs' is a list of keyword-only argument names.
    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
    'annotations' is a dictionary mapping argument names to annotations.

    The first four items in the tuple correspond to getargspec().
    """

    if inspect.ismethod(func):
        func = func.__func__
    if not inspect.isfunction(func):
        raise TypeError('arg is not a Python function')
    args, varargs, kwonlyargs, varkw = inspect._getfullargs(
        sys.get_func_code(func))
    return inspect.FullArgSpec(args, varargs, varkw, func.__defaults__,
                               kwonlyargs, func.__kwdefaults__,
                               func.__annotations__)
Пример #16
0
def _make_constants(
    function, builtins=None, builtin_only=False, stoplist=(), verbose=False
    ):
    """Return the given ``function`` with its constants folded."""

    if settings.debug == 2:
        print "# OPTIMISING : %s.%s" % (function.__module__, function.__name__)

    co = sys.get_func_code(function)
    newcode = map(ord, co.co_code)
    newconsts = list(co.co_consts)
    names = co.co_names
    codelen = len(newcode)

    if builtins:
        env = vars(builtins).copy()
    else:
        env = vars(__builtin__).copy()

    if builtin_only:
        stoplist = dict.fromkeys(stoplist)
        stoplist.update(sys.get_func_globals(function))
    else:
        env.update(sys.get_func_globals(function))

    # first pass converts global lookups into constants

    i = 0

    while i < codelen:
        opcode = newcode[i]
        if opcode in (EXTENDED_ARG, STORE_GLOBAL):
            # for simplicity, only optimise common cases
            return function
        if opcode == LOAD_GLOBAL:
            oparg = newcode[i+1] + (newcode[i+2] << 8)
            name = co.co_names[oparg]
            if name in env and name not in stoplist:
                value = env[name]
                for pos, v in enumerate(newconsts):
                    if v is value:
                        break
                else:
                    pos = len(newconsts)
                    newconsts.append(value)
                newcode[i] = LOAD_CONST
                newcode[i+1] = pos & 0xFF
                newcode[i+2] = pos >> 8
                if verbose or settings.debug:
                    print name, '-->', value
        i += 1
        if opcode >= HAVE_ARGUMENT:
            i += 2

    # second pass folds tuples of constants and constant attribute lookups

    i = 0

    while i < codelen:

        newtuple = []
        while newcode[i] == LOAD_CONST:
            oparg = newcode[i+1] + (newcode[i+2] << 8)
            newtuple.append(newconsts[oparg])
            i += 3

        opcode = newcode[i]
        if not newtuple:
            i += 1
            if opcode >= HAVE_ARGUMENT:
                i += 2
            continue

        if opcode == LOAD_ATTR:
            obj = newtuple[-1]
            oparg = newcode[i+1] + (newcode[i+2] << 8)
            name = names[oparg]
            try:
                value = getattr(obj, name)
            except AttributeError:
                continue
            deletions = 1

        elif opcode == BUILD_TUPLE:
            oparg = newcode[i+1] + (newcode[i+2] << 8)
            if oparg != len(newtuple):
                continue
            deletions = len(newtuple)
            value = tuple(newtuple)

        else:
            continue

        reljump = deletions * 3
        newcode[i-reljump] = JUMP_FORWARD
        newcode[i-reljump+1] = (reljump-3) & 0xFF
        newcode[i-reljump+2] = (reljump-3) >> 8

        n = len(newconsts)
        newconsts.append(value)
        newcode[i] = LOAD_CONST
        newcode[i+1] = n & 0xFF
        newcode[i+2] = n >> 8

        i += 3

        if verbose or settings.debug:
            print "new folded constant:", value

    codestr = ''.join(map(chr, newcode))
    codeobj = CodeType(
        co.co_argcount, co.co_nlocals, co.co_stacksize,
        co.co_flags, codestr, tuple(newconsts), co.co_names,
        co.co_varnames, co.co_filename, co.co_name,
        co.co_firstlineno, co.co_lnotab, co.co_freevars,
        co.co_cellvars
        )

    return FunctionType(
        codeobj, sys.get_func_globals(function), function.func_name,
        function.func_defaults, sys.get_func_closure(function)
        )