Skip to content

Commit c9379aa

Browse files
committed
added IPython extension
1 parent cdf0fb7 commit c9379aa

File tree

2 files changed

+133
-1
lines changed

2 files changed

+133
-1
lines changed

v3/opt.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Online Python Tutor extension for the IPython shell
2+
# http://ipython.org/ipython-doc/stable/config/extensions/index.html
3+
4+
# Tested on IPython 1.0.dev
5+
6+
# pgbovine
7+
import os, sys, urllib2, json
8+
9+
'''
10+
modpath = __file__
11+
# grab the .py file since that's the symlink
12+
if modpath.endswith('.pyc') and os.path.exists(modpath[:-1]):
13+
modpath = modpath[:-1]
14+
sys.path.insert(0, os.path.dirname(os.path.realpath(modpath)))
15+
'''
16+
17+
import pg_logger
18+
19+
import pprint
20+
21+
pp = pprint.PrettyPrinter()
22+
23+
24+
# To make regression tests work consistently across platforms,
25+
# standardize display of floats to 3 significant figures
26+
#
27+
# Trick from:
28+
# http://stackoverflow.com/questions/1447287/format-floats-with-standard-json-module
29+
json.encoder.FLOAT_REPR = lambda f: ('%.3f' % f)
30+
31+
INDENT_LEVEL = 2
32+
#INDENT_LEVEL = None
33+
34+
35+
# TODO: support incremental pushes to the OPT frontend for efficiency
36+
# and better "snappiness"
37+
38+
39+
# TODO: support line number adjustments for function definitions
40+
41+
class OptHistory(object):
42+
def __init__(self):
43+
self.executed_stmts = []
44+
45+
# each element is a LIST containing an OPT trace
46+
self.output_traces = []
47+
48+
# was the last executed stmt an exception?
49+
self.last_exec_is_exception = False
50+
51+
def pop_last(self):
52+
self.executed_stmts.pop()
53+
self.output_traces.pop()
54+
55+
def run_str(self, cmd_string, user_globals):
56+
opt_trace = pg_logger.exec_str_with_user_ns(cmd_string, user_globals, get_trace)
57+
58+
# clobber the last entry
59+
if self.last_exec_is_exception:
60+
self.pop_last()
61+
62+
# did this end in disaster?
63+
last_evt = opt_trace[-1]['event']
64+
if last_evt == 'exception':
65+
self.last_exec_is_exception = True
66+
else:
67+
assert last_evt == 'return'
68+
self.last_exec_is_exception = False
69+
70+
pp.pprint(opt_trace)
71+
72+
73+
74+
def get_trace(input_code, output_trace):
75+
return output_trace
76+
77+
78+
def custom_json_finalizer(input_code, output_trace):
79+
ret = dict(code=input_code, trace=output_trace)
80+
json_output = json.dumps(ret, indent=INDENT_LEVEL)
81+
return json_output
82+
83+
84+
# called right before a statement gets executed
85+
def opt_pre_run_code_hook(self):
86+
filtered_ns = {}
87+
for k, v in self.user_ns.iteritems():
88+
if k[0] == '_':
89+
continue
90+
if k in ('In', 'Out', 'help', 'quit', 'exit', 'get_ipython'):
91+
continue
92+
filtered_ns[k] = v
93+
94+
last_cmd = self.history_manager.input_hist_parsed[-1]
95+
print 'last_cmd:', last_cmd
96+
self.meta.opt_history.run_str(last_cmd, filtered_ns)
97+
#urllib2.urlopen("http://localhost:8888/post", last_cmd)
98+
99+
100+
def load_ipython_extension(ipython):
101+
# The `ipython` argument is the currently active `InteractiveShell`
102+
# instance, which can be used in any way. This allows you to register
103+
# new magics or aliases, for example.
104+
105+
ipython.meta.opt_history = OptHistory()
106+
107+
# NB: spelling might be different in older IPython versions
108+
ipython.set_hook('pre_run_code_hook', opt_pre_run_code_hook)
109+
110+
111+
def unload_ipython_extension(ipython):
112+
# If you want your extension to be unloadable, put that logic here.
113+
pass
114+

v3/pg_logger.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ def create_encoded_stack_entry(cur_frame):
953953
self.forget()
954954

955955

956-
def _runscript(self, script_str):
956+
def _runscript(self, script_str, custom_globals=None):
957957
self.executed_script = script_str
958958
self.executed_script_lines = self.executed_script.splitlines()
959959

@@ -1027,6 +1027,9 @@ def _runscript(self, script_str):
10271027
"__builtins__" : user_builtins,
10281028
"__user_stdout__" : user_stdout}
10291029

1030+
if custom_globals:
1031+
user_globals.update(custom_globals)
1032+
10301033
try:
10311034
# enforce resource limits RIGHT BEFORE running script_str
10321035

@@ -1184,3 +1187,18 @@ def exec_script_str_local(script_str, raw_input_lst_json, cumulative_mode, heap_
11841187
pass
11851188
finally:
11861189
return logger.finalize()
1190+
1191+
1192+
def exec_str_with_user_ns(script_str, user_ns, finalizer_func):
1193+
logger = PGLogger(False, False, False, finalizer_func, disable_security_checks=True)
1194+
1195+
global __html__, __css__, __js__
1196+
__html__, __css__, __js__ = None, None, None
1197+
1198+
try:
1199+
logger._runscript(script_str, user_ns)
1200+
except bdb.BdbQuit:
1201+
pass
1202+
finally:
1203+
return logger.finalize()
1204+

0 commit comments

Comments
 (0)