astoptimizer / demo.py

#!/usr/bin/env python
import ast
import dis
import sys
import types
from astoptimizer import Config, parse_ast, optimize_ast, compile_ast
from optparse import OptionParser

def dump_bytecode(code):
    dis.dis(code)
    for const in code.co_consts:
        if not isinstance(const, types.CodeType):
            continue
        print("")
        print("%s:" % const)
        dump_bytecode(const)

def main():
    parser = OptionParser(usage="%prog [options] code [line2 line3 ...]")
    parser.add_option("-k",
        help="Don't remove dead code",
        action="store_true", default=False)
    parser.add_option("-x",
        help="Enable experimental variables feature",
        action="store_true", default=False)
    parser.add_option("-n",
        help='Disable all configuration features',
        action="store_true", default=False)
    parser.add_option("-f", "--features",
        help='Enable configuration features FEATURES (default: builtin_funcs and pythonbin)',
        action="store", type="str", default="builtin_funcs,pythonbin")
    parser.add_option("-a", "--all",
        help="Enable all optimizations",
        action="store_true", default=False)
    parser.add_option("--str-limit",
        help="Maximum length of strings in bytes or characters",
        action="store", type="int", default=None)
    parser.add_option("--tuple-limit",
        help="Maximum length of frozenset, set and tuple",
        action="store", type="int", default=None)
    options, args = parser.parse_args()
    if not args:
        parser.print_help()
        exit(1)

    if args == ['-']:
        code_str = sys.stdin.read()
    else:
        code_str = '\n'.join(args)

    config = Config()
    if not options.n:
        for feature in options.features.split(','):
            config.enable(feature) #'builtin_funcs', 'pythonenv')
    if options.x:
        config.use_experimental_vars = True
    if options.k:
        config.remove_dead_code = False
    if options.str_limit is not None:
        config.max_string_length = options.str_limit
    if options.tuple_limit is not None:
        config.max_tuple_length = options.tuple_limit
    print("Features: %s" % ', '.join(sorted(config.features)))
    print("Experimental varaibles? %s" % config.use_experimental_vars)
    print("Remove code? %s" % config.remove_dead_code)
    print("Limits: string=%s, tuple=%s" % (config.max_string_length, config.max_tuple_length))
    print("")

    tree = parse_ast(code_str)
    print("Original AST:")
    print(ast.dump(tree))
    print("")

    print("Original bytecode:")
    try:
        code = compile(code_str, "<string>", "exec")
    except SyntaxError:
        print("*** SYNTAX ERROR ***")
    else:
        dump_bytecode(code)
    print("")

    tree = optimize_ast(tree, config)
    print("Optimised AST:")
    print(ast.dump(tree))
    print("")

    print("Optimized bytecode:")
    try:
        code = compile_ast(tree)
    except SyntaxError:
        print("*** SYNTAX ERROR ***")
    else:
        dump_bytecode(code)
        print("")

        print("Execute code:")
        exec(code)

if __name__ == "__main__":
    main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.