def main(in_base, out_base, files, codes, outfile=None, showasm=False, showast=False, do_verify=False, showgrammar=False, raise_on_error=False): """ in_base base directory for input files out_base base directory for output files (ignored when files list of filenames to be uncompyled (relative to src_base) outfile write output to this filename (overwrites out_base) For redirecting output to - <filename> outfile=<filename> (out_base is ignored) - files below out_base out_base=... - stdout out_base=None, outfile=None """ def _get_outstream(outfile): dir = os.path.dirname(outfile) failed_file = outfile + '_failed' if os.path.exists(failed_file): os.remove(failed_file) try: os.makedirs(dir) except OSError: pass return open(outfile, 'w') of = outfile tot_files = okay_files = failed_files = verify_failed_files = 0 # for code in codes: # version = sys.version[:3] # "2.5" # with open(code, "r") as f: # co = compile(f.read(), "", "exec") # uncompyle(sys.version[:3], co, sys.stdout, showasm=showasm, showast=showast) for filename in files: infile = os.path.join(in_base, filename) if not os.path.exists(infile): sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile) continue # print (infile, file=sys.stderr) if of: # outfile was given as parameter outstream = _get_outstream(outfile) elif out_base is None: outstream = sys.stdout else: outfile = os.path.join(out_base, filename) + '_dis' outstream = _get_outstream(outfile) # print(outfile, file=sys.stderr) # Try to uncompile the input file try: uncompyle_file(infile, outstream, showasm, showast, showgrammar) tot_files += 1 except (ValueError, SyntaxError, ParserError) as e: sys.stderr.write("\n# file %s\n# %s" % (infile, e)) failed_files += 1 except KeyboardInterrupt: if outfile: outstream.close() os.remove(outfile) sys.stderr.write("\nLast file: %s " % (infile)) raise # except: # failed_files += 1 # if outfile: # outstream.close() # os.rename(outfile, outfile + '_failed') # else: # sys.stderr.write("\n# %s" % sys.exc_info()[1]) # sys.stderr.write("\n# Can't uncompile %s\n" % infile) else: # uncompile successful if outfile: outstream.close() if do_verify: try: msg = verify.compare_code_with_srcfile(infile, outfile) if not outfile: if not msg: print('\n# okay decompiling %s' % infile) okay_files += 1 else: print('\n# %s\n\t%s', infile, msg) except verify.VerifyCmpError as e: print(e) verify_failed_files += 1 os.rename(outfile, outfile + '_unverified') if not outfile: print("### Error Verifiying %s" % filename, file=sys.stderr) print(e, file=sys.stderr) if raise_on_error: raise pass pass pass elif do_verify: print("\n### uncompile successful, but no file to compare against", file=sys.stderr) pass else: okay_files += 1 if not outfile: mess = '\n# okay decompiling' # mem_usage = __memUsage() print(mess, infile) if outfile: sys.stdout.write("%s\r" % status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() if outfile: sys.stdout.write("\n") sys.stdout.flush() return (tot_files, okay_files, failed_files, verify_failed_files)
def main( in_base, out_base, compiled_files, source_files, outfile=None, showasm=None, showast=False, do_verify=False, showgrammar=False, source_encoding=None, raise_on_error=False, do_linemaps=False, do_fragments=False, ): """ in_base base directory for input files out_base base directory for output files (ignored when files list of filenames to be uncompyled (relative to in_base) outfile write output to this filename (overwrites out_base) For redirecting output to - <filename> outfile=<filename> (out_base is ignored) - files below out_base out_base=... - stdout out_base=None, outfile=None """ tot_files = okay_files = failed_files = verify_failed_files = 0 current_outfile = outfile linemap_stream = None for source_path in source_files: compiled_files.append(compile_file(source_path)) for filename in compiled_files: infile = os.path.join(in_base, filename) # print("XXX", infile) if not os.path.exists(infile): sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile) continue if do_linemaps: linemap_stream = infile + ".pymap" pass # print (infile, file=sys.stderr) if outfile: # outfile was given as parameter outstream = _get_outstream(outfile) elif out_base is None: outstream = sys.stdout if do_linemaps: linemap_stream = sys.stdout if do_verify: prefix = os.path.basename(filename) + "-" if prefix.endswith(".py"): prefix = prefix[:-len(".py")] # Unbuffer output if possible buffering = -1 if sys.stdout.isatty() else 0 if PYTHON_VERSION >= 3.5: t = tempfile.NamedTemporaryFile(mode="w+b", buffering=buffering, suffix=".py", prefix=prefix) else: t = tempfile.NamedTemporaryFile(mode="w+b", suffix=".py", prefix=prefix) current_outfile = t.name sys.stdout = os.fdopen(sys.stdout.fileno(), "w", buffering) tee = subprocess.Popen(["tee", current_outfile], stdin=subprocess.PIPE) os.dup2(tee.stdin.fileno(), sys.stdout.fileno()) os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) else: if filename.endswith(".pyc"): current_outfile = os.path.join(out_base, filename[0:-1]) else: current_outfile = os.path.join(out_base, filename) + "_dis" pass pass outstream = _get_outstream(current_outfile) # print(current_outfile, file=sys.stderr) # Try to uncompile the input file try: deparsed = decompile_file( infile, outstream, showasm, showast, showgrammar, source_encoding, linemap_stream, do_fragments, ) if do_fragments: for d in deparsed: last_mod = None offsets = d.offsets for e in sorted( [k for k in offsets.keys() if isinstance(k[1], int)]): if e[0] != last_mod: line = "=" * len(e[0]) outstream.write("%s\n%s\n%s\n" % (line, e[0], line)) last_mod = e[0] info = offsets[e] extractInfo = d.extract_node_info(info) outstream.write("%s" % info.node.format().strip() + "\n") outstream.write(extractInfo.selectedLine + "\n") outstream.write(extractInfo.markerLine + "\n\n") pass pass tot_files += 1 except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e: sys.stdout.write("\n") sys.stderr.write("\n# file %s\n# %s\n" % (infile, e)) failed_files += 1 tot_files += 1 except KeyboardInterrupt: if outfile: outstream.close() os.remove(outfile) sys.stdout.write("\n") sys.stderr.write("\nLast file: %s " % (infile)) raise except RuntimeError as e: sys.stdout.write("\n%s\n" % str(e)) if str(e).startswith("Unsupported Python"): sys.stdout.write("\n") sys.stderr.write( "\n# Unsupported bytecode in file %s\n# %s\n" % (infile, e)) else: if outfile: outstream.close() os.remove(outfile) sys.stdout.write("\n") sys.stderr.write("\nLast file: %s " % (infile)) raise # except: # failed_files += 1 # if current_outfile: # outstream.close() # os.rename(current_outfile, current_outfile + "_failed") # else: # sys.stderr.write("\n# %s" % sys.exc_info()[1]) # sys.stderr.write("\n# Can't uncompile %s\n" % infile) else: # uncompile successful if current_outfile: outstream.close() if do_verify: try: msg = verify.compare_code_with_srcfile( infile, current_outfile, do_verify) if not current_outfile: if not msg: print("\n# okay decompiling %s" % infile) okay_files += 1 else: verify_failed_files += 1 print("\n# %s\n\t%s", infile, msg) pass else: okay_files += 1 pass except verify.VerifyCmpError as e: print(e) verify_failed_files += 1 os.rename(current_outfile, current_outfile + "_unverified") sys.stderr.write("### Error Verifying %s\n" % filename) sys.stderr.write(str(e) + "\n") if not outfile: if raise_on_error: raise pass pass pass else: okay_files += 1 pass elif do_verify: sys.stderr.write( "\n### uncompile successful, but no file to compare against\n" ) pass else: okay_files += 1 if not current_outfile: mess = "\n# okay decompiling" # mem_usage = __memUsage() print(mess, infile) if current_outfile: sys.stdout.write("%s -- %s\r" % ( infile, status_msg( do_verify, tot_files, okay_files, failed_files, verify_failed_files, do_verify, ), )) try: # FIXME: Something is weird with Pypy here sys.stdout.flush() except: pass if current_outfile: sys.stdout.write("\n") try: # FIXME: Something is weird with Pypy here sys.stdout.flush() except: pass pass return (tot_files, okay_files, failed_files, verify_failed_files)
def main(in_base, out_base, files, codes, outfile=None, showasm=None, showast=False, do_verify=False, showgrammar=False, raise_on_error=False, do_linemaps=False): """ in_base base directory for input files out_base base directory for output files (ignored when files list of filenames to be uncompyled (relative to src_base) outfile write output to this filename (overwrites out_base) For redirecting output to - <filename> outfile=<filename> (out_base is ignored) - files below out_base out_base=... - stdout out_base=None, outfile=None """ def _get_outstream(outfile): dir = os.path.dirname(outfile) failed_file = outfile + '_failed' if os.path.exists(failed_file): os.remove(failed_file) try: os.makedirs(dir) except OSError: pass return open(outfile, 'w') tot_files = okay_files = failed_files = verify_failed_files = 0 for filename in files: infile = os.path.join(in_base, filename) if not os.path.exists(infile): sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile) continue # print (infile, file=sys.stderr) if outfile: # outfile was given as parameter outstream = _get_outstream(outfile) elif out_base is None: outstream = sys.stdout if do_linemaps or do_verify: prefix = os.path.basename(filename) if prefix.endswith('.py'): prefix = prefix[:-len('.py')] junk, outfile = tempfile.mkstemp(suffix=".py", prefix=prefix) # Unbuffer output if possible buffering = -1 if sys.stdout.isatty() else 0 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', buffering) tee = subprocess.Popen(["tee", outfile], stdin=subprocess.PIPE) os.dup2(tee.stdin.fileno(), sys.stdout.fileno()) os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) else: if filename.endswith('.pyc'): outfile = os.path.join(out_base, filename[0:-1]) else: outfile = os.path.join(out_base, filename) + '_dis' outstream = _get_outstream(outfile) # print(outfile, file=sys.stderr) # Try to uncompile the input file try: decompile_file(infile, outstream, showasm, showast, showgrammar) tot_files += 1 except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e: sys.stdout.write("\n") sys.stderr.write("\n# file %s\n# %s\n" % (infile, e)) failed_files += 1 except KeyboardInterrupt: if outfile: outstream.close() os.remove(outfile) sys.stdout.write("\n") sys.stderr.write("\nLast file: %s " % (infile)) raise # except: # failed_files += 1 # if outfile: # outstream.close() # os.rename(outfile, outfile + '_failed') # else: # sys.stderr.write("\n# %s" % sys.exc_info()[1]) # sys.stderr.write("\n# Can't uncompile %s\n" % infile) else: # uncompile successful if outfile: if do_linemaps: mapping = line_number_mapping(infile, outfile) outstream.write("\n\n## Line number correspondences\n") import pprint s = pprint.pformat(mapping, indent=2, width=80) s2 = '##' + '\n##'.join(s.split("\n")) + "\n" outstream.write(s2) outstream.close() if do_verify: weak_verify = do_verify == 'weak' try: msg = verify.compare_code_with_srcfile(infile, outfile, weak_verify=weak_verify) if not outfile: if not msg: print('\n# okay decompiling %s' % infile) okay_files += 1 else: print('\n# %s\n\t%s', infile, msg) except verify.VerifyCmpError as e: print(e) verify_failed_files += 1 os.rename(outfile, outfile + '_unverified') sys.stderr.write("### Error Verifying %s\n" % filename) sys.stderr.write(str(e) + "\n") if not outfile: if raise_on_error: raise pass pass pass elif do_verify: sys.stderr.write("\n### uncompile successful, but no file to compare against\n") pass else: okay_files += 1 if not outfile: mess = '\n# okay decompiling' # mem_usage = __memUsage() print(mess, infile) if outfile: sys.stdout.write("%s\r" % status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() if outfile: sys.stdout.write("\n") sys.stdout.flush() return (tot_files, okay_files, failed_files, verify_failed_files)
def main(in_base, out_base, files, codes, outfile=None, showasm=None, showast=False, do_verify=False, showgrammar=False, raise_on_error=False, do_linemaps=False): """ in_base base directory for input files out_base base directory for output files (ignored when files list of filenames to be uncompyled (relative to src_base) outfile write output to this filename (overwrites out_base) For redirecting output to - <filename> outfile=<filename> (out_base is ignored) - files below out_base out_base=... - stdout out_base=None, outfile=None """ def _get_outstream(outfile): dir = os.path.dirname(outfile) failed_file = outfile + '_failed' if os.path.exists(failed_file): os.remove(failed_file) try: os.makedirs(dir) except OSError: pass return open(outfile, 'w') tot_files = okay_files = failed_files = verify_failed_files = 0 # for code in codes: # version = sys.version[:3] # "2.5" # with open(code, "r") as f: # co = compile(f.read(), "", "exec") # uncompyle(sys.version[:3], co, sys.stdout, showasm=showasm, showast=showast) for filename in files: infile = os.path.join(in_base, filename) if not os.path.exists(infile): sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile) continue # print (infile, file=sys.stderr) if outfile: # outfile was given as parameter outstream = _get_outstream(outfile) elif out_base is None: outstream = sys.stdout if do_linemaps or do_verify: prefix = os.path.basename(filename) if prefix.endswith('.py'): prefix = prefix[:-len('.py')] junk, outfile = tempfile.mkstemp(suffix=".py", prefix=prefix) # Unbuffer output sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) tee = subprocess.Popen(["tee", outfile], stdin=subprocess.PIPE) os.dup2(tee.stdin.fileno(), sys.stdout.fileno()) os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) else: if filename.endswith('.pyc'): outfile = os.path.join(out_base, filename[0:-1]) else: outfile = os.path.join(out_base, filename) + '_dis' outstream = _get_outstream(outfile) # print(outfile, file=sys.stderr) # Try to uncompile the input file try: uncompyle_file(infile, outstream, showasm, showast, showgrammar) tot_files += 1 except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e: sys.stdout.write("\n") sys.stderr.write("\n# file %s\n# %s\n" % (infile, e)) failed_files += 1 except KeyboardInterrupt: if outfile: outstream.close() os.remove(outfile) sys.stdout.write("\n") sys.stderr.write("\nLast file: %s " % (infile)) raise # except: # failed_files += 1 # if outfile: # outstream.close() # os.rename(outfile, outfile + '_failed') # else: # sys.stderr.write("\n# %s" % sys.exc_info()[1]) # sys.stderr.write("\n# Can't uncompile %s\n" % infile) else: # uncompile successful if outfile: if do_linemaps: mapping = line_number_mapping(infile, outfile) outstream.write("\n\n## Line number correspondences\n") import pprint s = pprint.pformat(mapping, indent=2, width=80) s2 = '##' + '\n##'.join(s.split("\n")) + "\n" outstream.write(s2) outstream.close() if do_verify: weak_verify = do_verify == 'weak' try: msg = verify.compare_code_with_srcfile( infile, outfile, weak_verify=weak_verify) if not outfile: if not msg: print('\n# okay decompiling %s' % infile) okay_files += 1 else: print('\n# %s\n\t%s', infile, msg) except verify.VerifyCmpError as e: print(e) verify_failed_files += 1 os.rename(outfile, outfile + '_unverified') sys.stderr.write("### Error Verifying %s\n" % filename) sys.stderr.write(str(e) + "\n") if not outfile: if raise_on_error: raise pass pass pass elif do_verify: sys.stderr.write( "\n### uncompile successful, but no file to compare against\n" ) pass else: okay_files += 1 if not outfile: mess = '\n# okay decompiling' # mem_usage = __memUsage() print(mess, infile) if outfile: sys.stdout.write("%s\r" % status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() if outfile: sys.stdout.write("\n") sys.stdout.flush() return (tot_files, okay_files, failed_files, verify_failed_files)