Example #1
0
def deparse_text(co, name, last_i):
    text = []
    try:
        deparsed = code_deparse(co)
        nodeInfo = deparsed_find((name, last_i), deparsed, co)
        if not nodeInfo:
            # FIXME: change deparse_code_around_offset() so we
            # don't need py_str2float
            from xdis.magics import py_str2float

            float_version = py_str2float()
            deparsed = deparse_code_around_offset(co.co_name, last_i,
                                                  float_version, co)
    except:
        return None
    if not nodeInfo:
        nodeInfo = deparsed_find((name, last_i), deparsed, co)
    if nodeInfo:
        extractInfo = deparsed.extract_node_info(nodeInfo)
        if extractInfo:
            text.append("    instruction: %s" % (nodeInfo.node))
            text.append(extractInfo.selectedLine)
            text.append(extractInfo.markerLine + "\n")
        pass
    return text
Example #2
0
def get_scanner(version, is_pypy=False, show_asm=None):

    # If version is a string, turn that into the corresponding float.
    if isinstance(version, str):
        version = py_str2float(version)

    # Pick up appropriate scanner
    if version in PYTHON_VERSIONS:
        v_str = "%s" % (int(version * 10))
        if PYTHON3:
            import importlib
            if is_pypy:
                scan = importlib.import_module("uncompyle6.scanners.pypy%s" % v_str)
            else:
                scan = importlib.import_module("uncompyle6.scanners.scanner%s" % v_str)
            if False: print(scan)  # Avoid unused scan
        else:
            if is_pypy:
                exec("import uncompyle6.scanners.pypy%s as scan" % v_str)
            else:
                exec("import uncompyle6.scanners.scanner%s as scan" % v_str)
        if is_pypy:
            scanner = eval("scan.ScannerPyPy%s(show_asm=show_asm)" % v_str)
        else:
            scanner = eval("scan.Scanner%s(show_asm=show_asm)" % v_str)
    else:
        raise RuntimeError("Unsupported Python version %s" % version)
    return scanner
Example #3
0
def get_python_parser(
    version, debug_parser=PARSER_DEFAULT_DEBUG, compile_mode="exec", is_pypy=False
):
    """Returns parser object for Python version 3.7, 3.8,
    etc., depending on the parameters passed.  *compile_mode* is either
    "exec", "eval", or "single" or "lambda".

    "lambda" is for the grammar that can appear in lambda statements. "eval"
    is for eval kinds of expressions.

    For the others, see https://docs.python.org/3/library/functions.html#compile for an
    explanation of the different modes.

    """

    # If version is a string, turn that into the corresponding float.
    if isinstance(version, str):
        version = py_str2float(version)

    # FIXME: there has to be a better way...
    # We could do this as a table lookup, but that would force us
    # in import all of the parsers all of the time. Perhaps there is
    # a lazy way of doing the import?

    if version < 3.7:
        raise RuntimeError(f"Unsupported Python version {version}")
    elif version == 3.7:
        import decompyle3.parsers.p37 as parse37

        if compile_mode == "exec":
            p = parse37.Python37Parser(debug_parser)
        elif compile_mode == "lambda":
            p = parse37.Python37LambdaParser(debug_parser, compile_mode=compile_mode)
            ## If the above gives a parse error, use the below to debug what grammar rule(s)
            ## need to get added
            # p = parse37.Python37ParserSingle(debug_parser, compile_mode=compile_mode)
        elif compile_mode == "eval":
            p = parse37.Python37ParserEval(debug_parser, compile_mode="eval_expr")
        else:
            p = parse37.Python37ParserSingle(debug_parser, compile_mode=compile_mode)
    elif version == 3.8:
        import decompyle3.parsers.p38 as parse38

        if compile_mode == "exec":
            p = parse38.Python38Parser(debug_parser)
        elif compile_mode == "lambda":
            p = parse38.Python38LambdaParser(debug_parser, compile_mode=compile_mode)
            ## If the above gives a parse error, use the below to debug what grammar rule(s)
            ## need to get added
            # p = parse38.Python38ParserSingle(debug_parser, compile_mode=compile_mode)
        elif compile_mode == "eval":
            p = parse38.Python38ParserEval(debug_parser, compile_mode="eval_expr")
        else:
            p = parse38.Python38ParserSingle(debug_parser, compile_mode=compile_mode)

    p.version = version
    # p.dump_grammar() # debug
    return p
Example #4
0
def get_python_parser(version,
                      debug_parser=PARSER_DEFAULT_DEBUG,
                      compile_mode="exec",
                      is_pypy=False):
    """Returns parser object for Python version 3.7, 3.8,
    etc., depending on the parameters passed.  *compile_mode* is either
    'exec', 'eval', or 'single'. See
    https://docs.python.org/3.6/library/functions.html#compile for an
    explanation of the different modes.
    """

    # If version is a string, turn that into the corresponding float.
    if isinstance(version, str):
        version = py_str2float(version)

    # FIXME: there has to be a better way...
    # We could do this as a table lookup, but that would force us
    # in import all of the parsers all of the time. Perhaps there is
    # a lazy way of doing the import?

    if version < 3.7:
        raise RuntimeError(f"Unsupported Python version {version}")
    elif version == 3.7:
        import decompyle3.parsers.parse37 as parse37

        if compile_mode == "exec":
            p = parse37.Python37Parser(debug_parser)
        else:
            p = parse37.Python37ParserSingle(debug_parser)
    elif version == 3.8:
        import decompyle3.parsers.parse38 as parse38

        if compile_mode == "exec":
            p = parse38.Python38Parser(debug_parser)
        else:
            p = parse38.Python38ParserSingle(debug_parser)

    p.version = version
    # p.dump_grammar() # debug
    return p
Example #5
0
def get_python_parser(
        version, debug_parser=PARSER_DEFAULT_DEBUG, compile_mode='exec',
        is_pypy = False):
    """Returns parser object for Python version 2 or 3, 3.2, 3.5on,
    etc., depending on the parameters passed.  *compile_mode* is either
    'exec', 'eval', or 'single'. See
    https://docs.python.org/3.6/library/functions.html#compile for an
    explanation of the different modes.
    """

    # If version is a string, turn that into the corresponding float.
    if isinstance(version, str):
        version = py_str2float(version)

    # FIXME: there has to be a better way...
    # We could do this as a table lookup, but that would force us
    # in import all of the parsers all of the time. Perhaps there is
    # a lazy way of doing the import?

    if version < 3.0:
        if version < 2.2:
            if version == 1.0:
                import uncompyle6.parsers.parse10 as parse10
                if compile_mode == 'exec':
                    p = parse10.Python10Parser(debug_parser)
                else:
                    p = parse10.Python01ParserSingle(debug_parser)
            elif version == 1.1:
                import uncompyle6.parsers.parse11 as parse11
                if compile_mode == 'exec':
                    p = parse11.Python11Parser(debug_parser)
                else:
                    p = parse11.Python11ParserSingle(debug_parser)
            if version == 1.2:
                import uncompyle6.parsers.parse12 as parse12
                if compile_mode == 'exec':
                    p = parse12.Python12Parser(debug_parser)
                else:
                    p = parse12.Python12ParserSingle(debug_parser)
            if version == 1.3:
                import uncompyle6.parsers.parse13 as parse13
                if compile_mode == 'exec':
                    p = parse13.Python13Parser(debug_parser)
                else:
                    p = parse13.Python13ParserSingle(debug_parser)
            elif version == 1.4:
                import uncompyle6.parsers.parse14 as parse14
                if compile_mode == 'exec':
                    p = parse14.Python14Parser(debug_parser)
                else:
                    p = parse14.Python14ParserSingle(debug_parser)
            elif version == 1.5:
                import uncompyle6.parsers.parse15 as parse15
                if compile_mode == 'exec':
                    p = parse15.Python15Parser(debug_parser)
                else:
                    p = parse15.Python15ParserSingle(debug_parser)
            elif version == 1.6:
                import uncompyle6.parsers.parse16 as parse16
                if compile_mode == 'exec':
                    p = parse16.Python16Parser(debug_parser)
                else:
                    p = parse16.Python16ParserSingle(debug_parser)
            elif version == 2.1:
                import uncompyle6.parsers.parse21 as parse21
                if compile_mode == 'exec':
                    p = parse21.Python21Parser(debug_parser)
                else:
                    p = parse21.Python21ParserSingle(debug_parser)
        elif version == 2.2:
            import uncompyle6.parsers.parse22 as parse22
            if compile_mode == 'exec':
                p = parse22.Python22Parser(debug_parser)
            else:
                p = parse22.Python22ParserSingle(debug_parser)
        elif version == 2.3:
            import uncompyle6.parsers.parse23 as parse23
            if compile_mode == 'exec':
                p = parse23.Python23Parser(debug_parser)
            else:
                p = parse23.Python23ParserSingle(debug_parser)
        elif version == 2.4:
            import uncompyle6.parsers.parse24 as parse24
            if compile_mode == 'exec':
                p = parse24.Python24Parser(debug_parser)
            else:
                p = parse24.Python24ParserSingle(debug_parser)
        elif version == 2.5:
            import uncompyle6.parsers.parse25 as parse25
            if compile_mode == 'exec':
                p = parse25.Python25Parser(debug_parser)
            else:
                p = parse25.Python25ParserSingle(debug_parser)
        elif version == 2.6:
            import uncompyle6.parsers.parse26 as parse26
            if compile_mode == 'exec':
                p = parse26.Python26Parser(debug_parser)
            else:
                p = parse26.Python26ParserSingle(debug_parser)
        elif version == 2.7:
            import uncompyle6.parsers.parse27 as parse27
            if compile_mode == 'exec':
                p = parse27.Python27Parser(debug_parser)
            else:
                p = parse27.Python27ParserSingle(debug_parser)
        else:
            import uncompyle6.parsers.parse2 as parse2
            if compile_mode == 'exec':
                p = parse2.Python2Parser(debug_parser)
            else:
                p = parse2.Python2ParserSingle(debug_parser)
                pass
            pass
        pass
    else:
        import uncompyle6.parsers.parse3 as parse3
        if version == 3.0:
            import uncompyle6.parsers.parse30 as parse30
            if compile_mode == 'exec':
                p = parse30.Python30Parser(debug_parser)
            else:
                p = parse30.Python30ParserSingle(debug_parser)
        elif version == 3.1:
            import uncompyle6.parsers.parse31 as parse31
            if compile_mode == 'exec':
                p = parse31.Python31Parser(debug_parser)
            else:
                p = parse31.Python31ParserSingle(debug_parser)
        elif version == 3.2:
            import uncompyle6.parsers.parse32 as parse32
            if compile_mode == 'exec':
                p = parse32.Python32Parser(debug_parser)
            else:
                p = parse32.Python32ParserSingle(debug_parser)
        elif version == 3.3:
            import uncompyle6.parsers.parse33 as parse33
            if compile_mode == 'exec':
                p = parse33.Python33Parser(debug_parser)
            else:
                p = parse33.Python33ParserSingle(debug_parser)
        elif version == 3.4:
            import uncompyle6.parsers.parse34 as parse34
            if compile_mode == 'exec':
                p = parse34.Python34Parser(debug_parser)
            else:
                p = parse34.Python34ParserSingle(debug_parser)
        elif version == 3.5:
            import uncompyle6.parsers.parse35 as parse35
            if compile_mode == 'exec':
                p = parse35.Python35Parser(debug_parser)
            else:
                p = parse35.Python35ParserSingle(debug_parser)
        elif version == 3.6:
            import uncompyle6.parsers.parse36 as parse36
            if compile_mode == 'exec':
                p = parse36.Python36Parser(debug_parser)
            else:
                p = parse36.Python36ParserSingle(debug_parser)
        elif version == 3.7:
            import uncompyle6.parsers.parse37 as parse37
            if compile_mode == 'exec':
                p = parse37.Python37Parser(debug_parser)
            else:
                p = parse37.Python37ParserSingle(debug_parser)
        elif version == 3.8:
            import uncompyle6.parsers.parse38 as parse38
            if compile_mode == 'exec':
                p = parse38.Python38Parser(debug_parser)
            else:
                p = parse38.Python38ParserSingle(debug_parser)
        else:
            if compile_mode == 'exec':
                p = parse3.Python3Parser(debug_parser)
            else:
                p = parse3.Python3ParserSingle(debug_parser)
    p.version = version
    # p.dump_grammar() # debug
    return p
    def walk(
        self
    ) -> Iterator[AbstractInjectionWalker]:
        try:
            co_argcount_inj_walker = self._read_co_argcount()
            yield co_argcount_inj_walker

            co_kwonlyargcount_inj_walker = self._read_co_kwonlyargcount()
            yield co_kwonlyargcount_inj_walker

            co_nlocals_inj_walker = self._read_co_nlocals()
            yield co_nlocals_inj_walker

            co_stacksize_inj_walker = self._read_co_stacksize()
            yield co_stacksize_inj_walker

            co_flags_inj_walker = self._read_co_flags()
            yield co_flags_inj_walker

            co_code_inj_walker = self._read_co_code()
            yield co_code_inj_walker

            co_consts_inj_walker: AbstractInjectionWalker
            for walker in self._read_co_consts():
                yield walker
                co_consts_inj_walker = walker
            if not isinstance(co_consts_inj_walker,
                              CodeObjectFieldInjectionWalker):
                yield FailedInjectionWalker.msg(
                    f'Received unexpected type {type(co_consts_inj_walker)} '
                    'when expecting a field injection walker')
                return

            co_names_inj_walker = self._read_co_names()
            yield co_names_inj_walker

            co_varnames_inj_walker = self._read_co_varnames()
            yield co_varnames_inj_walker

            co_filename_inj_walker = self._read_co_filename()
            yield co_filename_inj_walker

            co_name_inj_walker = self._read_co_name()
            yield co_name_inj_walker

            co_firstlineno_inj_walker = self._read_co_firstlineno()
            yield co_firstlineno_inj_walker

            co_lnotab_inj_walker = self._read_co_lnotab()
            yield co_lnotab_inj_walker

            co_freevars_inj_walker = self._read_co_freevars()
            yield co_freevars_inj_walker

            co_cellvars_inj_walker = self._read_co_cellvars()
            yield co_cellvars_inj_walker
        except ValueError as e:
            yield FailedInjectionWalker.msg(str(e))
            return

        self._code_obj = CodeType(
            co_argcount_inj_walker.value,
            co_kwonlyargcount_inj_walker.value,
            co_nlocals_inj_walker.value,
            co_stacksize_inj_walker.value,
            co_flags_inj_walker.value,
            co_code_inj_walker.value,
            co_consts_inj_walker.value,
            co_names_inj_walker.value,
            co_varnames_inj_walker.value,
            co_filename_inj_walker.value,
            co_name_inj_walker.value,
            co_firstlineno_inj_walker.value,
            co_lnotab_inj_walker.value,
            co_freevars_inj_walker.value,
            co_cellvars_inj_walker.value)

        bytecode_version_float = py_str2float(self._bytecode_version)
        with StringIO() as f:
            decompile(bytecode_version_float, self._code_obj, out=f)
            raw_decompiled_src_body = f.getvalue()

        decompiled_src_body = raw_decompiled_src_body.replace(
            '\n\n\n', '\n\n')
        lines = [
            line for line in decompiled_src_body.splitlines()
            if not line.lstrip().startswith('# ')]
        self._src_code = '\n'.join(lines)

        yield self