Generates random Python functions using Markov chains
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

129 wiersze
4.3 KiB

  1. import opcode
  2. import sys
  3. import func_smash
  4. OP_HASLOAD = {"LOAD_CONST": True, "LOAD_FAST": False, "LOAD_GLOBAL": False}
  5. OP_HASBINARY = {"BINARY_ADD": "+", "BINARY_SUBTRACT": "-",
  6. "BINARY_MULTIPLY": "*", "BINARY_DIVIDE": "/",
  7. "BINARY_POWER": "**", "BINARY_MODULO": "%"}
  8. OP_HASBUILD = {"BUILD_TUPLE": ("(", ")"), "BUILD_LIST": ("[", "]"),
  9. "BUILD_SET": ("{", "}")}
  10. def prettify_function(func, indent=0):
  11. args = _get_func_args(func)
  12. _print(indent, "def {0}({1}):".format(func.func_name, args))
  13. prettify_code(func.__code__, indent=indent+4)
  14. def prettify_code(codeobj, indent=0):
  15. codes = []
  16. codestring = codeobj.co_code
  17. length = len(codestring)
  18. i = 0
  19. while i < length:
  20. code = ord(codestring[i])
  21. i += 1
  22. if code >= opcode.HAVE_ARGUMENT:
  23. arg = func_smash._get_argument(codeobj, codestring, i, code)
  24. i += 2
  25. codes.append((code, arg))
  26. else:
  27. codes.append((code, None))
  28. _print_codestring(codes, indent)
  29. def _print_codestring(codes, indent):
  30. stack = []
  31. print_buffer = []
  32. for instruction in codes:
  33. code, arg = instruction
  34. opname = opcode.opname[code]
  35. _print(indent, opname, arg, "; stack ==", stack, debug=True)
  36. if opname in OP_HASLOAD:
  37. _push(stack, arg, literal=OP_HASLOAD[opname])
  38. elif opname in OP_HASBINARY:
  39. tos, tos1 = _pop(stack), _pop(stack)
  40. _push(stack, " ".join((tos1, OP_HASBINARY[opname], tos)))
  41. elif opname in OP_HASBUILD:
  42. args = []
  43. for i in xrange(arg):
  44. args.append(_pop(stack))
  45. args.reverse()
  46. start, end = OP_HASBUILD[opname]
  47. _push(stack, start + ", ".join(args) + end)
  48. elif opname == "BUILD_MAP":
  49. _push(stack, "{}")
  50. elif opname == "STORE_FAST":
  51. _print(indent, arg, "=", _pop(stack))
  52. elif opname == "STORE_MAP":
  53. pair = ": ".join((_pop(stack), _pop(stack)))
  54. oldmap = _pop(stack)
  55. if oldmap == "{}":
  56. newmap = "{" + pair + "}"
  57. else:
  58. newmap = oldmap[:-1] + ", " + pair + "}"
  59. _push(stack, newmap)
  60. elif opname == "POP_TOP":
  61. _print(indent, _pop(stack))
  62. elif opname == "CALL_FUNCTION":
  63. numargs, numkwargs = arg
  64. args = []
  65. for i in xrange(numkwargs):
  66. value = _pop(stack)
  67. key = _pop(stack, never_literal=True)
  68. args.append("=".join((key, value)))
  69. for i in xrange(numargs):
  70. args.append(_pop(stack))
  71. args.reverse()
  72. funcname = _pop(stack)
  73. _push(stack, "{0}({1})".format(funcname, ", ".join(args)))
  74. elif opname == "PRINT_ITEM":
  75. print_buffer.append(_pop(stack))
  76. elif opname == "PRINT_NEWLINE":
  77. _print(indent, "print", ", ".join(print_buffer))
  78. print_buffer = []
  79. elif opname == "RETURN_VALUE":
  80. _print(indent, "return", _pop(stack))
  81. else:
  82. raise NotImplementedError(opname, arg, stack)
  83. def _get_func_args(func):
  84. codeobj = func.__code__
  85. count = codeobj.co_argcount
  86. if count == 0:
  87. return ""
  88. return ", ".join([arg for arg in codeobj.co_varnames[:count]])
  89. def _push(stack, item, literal=False):
  90. stack.append((item, literal))
  91. def _pop(stack, never_literal=False):
  92. item, literal = stack.pop()
  93. return repr(item) if literal and not never_literal else item
  94. def _print(indentation, *args, **kwargs):
  95. argstring = " ".join([str(arg) for arg in args if str(arg)])
  96. if kwargs.get("debug"):
  97. # Ignore debug messages without -d flag
  98. if len(sys.argv) > 1 and sys.argv[1] == "-d":
  99. print " " * 50 + "#", argstring
  100. return
  101. print " " * indentation + argstring
  102. if __name__ == "__main__":
  103. def f1(a):
  104. b = a + 10 / 7.0
  105. d = long_func(a, b+9, c=42, d="43")
  106. print b, d
  107. ex_tuple = ("Hello", "world!", abcdef)
  108. ex_list = [1, 2, 3] * 3 + [4, 5, 6]
  109. ex_set = {99, 98, 97, 96, 95}
  110. ex_dict = {d: e, f: False, "testing": g}
  111. return ex_dict
  112. def f2():
  113. pass
  114. prettify_function(f1)
  115. print
  116. prettify_function(f2)