Generates random Python functions using Markov chains
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

129 lignes
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)