forked from hcientist/OnlinePythonTutor
-
Notifications
You must be signed in to change notification settings - Fork 2
/
generate_json_trace.py
77 lines (67 loc) · 3.52 KB
/
generate_json_trace.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Generates a JSON trace that is compatible with the js/pytutor.ts frontend
import sys, pg_logger, json
from optparse import OptionParser
# To make regression tests work consistently across platforms,
# standardize display of floats to 3 significant figures
#
# Trick from:
# http://stackoverflow.com/questions/1447287/format-floats-with-standard-json-module
json.encoder.FLOAT_REPR = lambda f: ('%.3f' % f)
def json_finalizer(input_code, output_trace):
ret = dict(code=input_code, trace=output_trace)
# sort_keys=True leads to printing in DETERMINISTIC order, but might
# screw up some old tests ... however, there is STILL non-determinism
# in Python 3.3 tests, ugh!
#
# TODO: for Python 3.6, think about reinstating sort_keys=True as a
# command-line option for tests only? maybe don't activate it for reals
# since that might falsely give users the impression that object/dict keys
# are always sorted
json_output = json.dumps(ret, indent=INDENT_LEVEL)
return json_output
def js_var_finalizer(input_code, output_trace):
global JS_VARNAME
ret = dict(code=input_code, trace=output_trace)
json_output = json.dumps(ret, indent=None)
return "var %s = %s;" % (JS_VARNAME, json_output)
parser = OptionParser(usage="Generate JSON trace for pytutor")
parser.add_option('-c', '--cumulative', default=False, action='store_true',
help='output cumulative trace.')
parser.add_option('-p', '--heapPrimitives', default=False, action='store_true',
help='render primitives as heap objects.')
parser.add_option('-o', '--compact', default=False, action='store_true',
help='output compact trace.')
parser.add_option('--allmodules', default=False, action='store_true',
help='allow importing of all installed Python modules.')
parser.add_option('-i', '--input', default=False, action='store',
help='JSON list of strings for simulated raw_input.', dest='raw_input_lst_json')
parser.add_option("--create_jsvar", dest="js_varname", default=None,
help="Create a JavaScript variable out of the trace")
parser.add_option("--code", dest="usercode", default=None,
help="Load user code from a string instead of a file and output compact JSON")
parser.add_option("--probe-exprs", dest="probe_exprs_json", default=None,
help="A JSON list of strings representing expressions whose values to probe at each step (advanced)")
(options, args) = parser.parse_args()
INDENT_LEVEL = None if options.compact else 2
if options.usercode:
INDENT_LEVEL = None
probe_exprs = None
if options.probe_exprs_json:
probe_exprs = json.loads(options.probe_exprs_json)
allow_all_modules = False
if options.allmodules:
allow_all_modules = True
print(pg_logger.exec_script_str_local(options.usercode,
options.raw_input_lst_json,
options.cumulative,
options.heapPrimitives,
json_finalizer,
probe_exprs=probe_exprs,
allow_all_modules=allow_all_modules))
else:
fin = sys.stdin if args[0] == "-" else open(args[0])
if options.js_varname:
JS_VARNAME = options.js_varname
print(pg_logger.exec_script_str_local(fin.read(), options.raw_input_lst_json, options.cumulative, options.heapPrimitives, js_var_finalizer))
else:
print(pg_logger.exec_script_str_local(fin.read(), options.raw_input_lst_json, options.cumulative, options.heapPrimitives, json_finalizer))