##// END OF EJS Templates
Replace run_cell method, and fix up caching compiler so we can cache a string, then compile AST nodes.
Thomas Kluyver -
Show More
@@ -51,12 +51,12 b' def code_name(code, number=0):'
51 # Classes and functions
51 # Classes and functions
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53
53
54 class CachingCompiler(object):
54 class CachingCompiler(codeop.Compile):
55 """A compiler that caches code compiled from interactive statements.
55 """A compiler that caches code compiled from interactive statements.
56 """
56 """
57
57
58 def __init__(self):
58 def __init__(self):
59 self._compiler = codeop.CommandCompiler()
59 codeop.Compile.__init__(self)
60
60
61 # This is ugly, but it must be done this way to allow multiple
61 # This is ugly, but it must be done this way to allow multiple
62 # simultaneous ipython instances to coexist. Since Python itself
62 # simultaneous ipython instances to coexist. Since Python itself
@@ -81,35 +81,30 b' class CachingCompiler(object):'
81 def compiler_flags(self):
81 def compiler_flags(self):
82 """Flags currently active in the compilation process.
82 """Flags currently active in the compilation process.
83 """
83 """
84 return self._compiler.compiler.flags
84 return self.flags
85
86 def cache(self, code, number=0):
87 """Make a name for a block of code, and cache the code.
85
88
86 def __call__(self, code, symbol, number=0):
87 """Compile some code while caching its contents such that the inspect
88 module can find it later.
89
90 Parameters
89 Parameters
91 ----------
90 ----------
92 code : str
91 code : str
93 Source code to be compiled, one or more lines.
92 The Python source code to cache.
94
93 number : int
95 symbol : str
94 A number which forms part of the code's name. Used for the execution
96 One of 'single', 'exec' or 'eval' (see the builtin ``compile``
95 counter.
97 documentation for further details on these fields).
96
98
97 Returns
99 number : int, optional
98 -------
100 An integer argument identifying the code, useful for informational
99 The name of the cached code (as a string). Pass this as the filename
101 purposes in tracebacks (typically it will be the IPython prompt
100 argument to compilation, so that tracebacks are correctly hooked up.
102 number).
103 """
101 """
104 name = code_name(code, number)
102 name = code_name(code, number)
105 code_obj = self._compiler(code, name, symbol)
106 entry = (len(code), time.time(),
103 entry = (len(code), time.time(),
107 [line+'\n' for line in code.splitlines()], name)
104 [line+'\n' for line in code.splitlines()], name)
108 # Cache the info both in the linecache (a global cache used internally
109 # by most of Python's inspect/traceback machinery), and in our cache
110 linecache.cache[name] = entry
105 linecache.cache[name] = entry
111 linecache._ipython_cache[name] = entry
106 linecache._ipython_cache[name] = entry
112 return code_obj
107 return name
113
108
114 def check_cache(self, *args):
109 def check_cache(self, *args):
115 """Call linecache.checkcache() safely protecting our cached values.
110 """Call linecache.checkcache() safely protecting our cached values.
@@ -2100,7 +2100,7 b' class InteractiveShell(Configurable, Magic):'
2100 self.showtraceback()
2100 self.showtraceback()
2101 warn('Unknown failure executing file: <%s>' % fname)
2101 warn('Unknown failure executing file: <%s>' % fname)
2102
2102
2103 def run_cell_NODE(self, cell, store_history=True):
2103 def run_cell(self, cell, store_history=True):
2104 """Run a complete IPython cell.
2104 """Run a complete IPython cell.
2105
2105
2106 Parameters
2106 Parameters
@@ -2123,19 +2123,22 b' class InteractiveShell(Configurable, Magic):'
2123
2123
2124 self.logger.log(cell, raw_cell)
2124 self.logger.log(cell, raw_cell)
2125
2125
2126 cell_name = self.compile.cache(cell, self.execution_count)
2127
2126 with self.display_trap:
2128 with self.display_trap:
2127 try:
2129 try:
2128 code_ast = ast.parse(cell)
2130 code_ast = ast.parse(cell)
2129 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2131 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2130 # Case 1
2132 # Case 1
2131 self.showsyntaxerror(filename)
2133 self.showsyntaxerror()
2134 self.execution_count += 1
2132 return None
2135 return None
2133
2136
2134 interactivity = 1 # Last node to be run interactive
2137 interactivity = 1 # Last node to be run interactive
2135 if len(cell.splitlines()) == 1:
2138 if len(cell.splitlines()) == 1:
2136 interactivity = 2 # Single line; run fully interactive
2139 interactivity = 2 # Single line; run fully interactive
2137
2140
2138 self.run_ast_nodes(code_ast.body, interactivity)
2141 self.run_ast_nodes(code_ast.body, cell_name, interactivity)
2139
2142
2140 if store_history:
2143 if store_history:
2141 # Write output to the database. Does nothing unless
2144 # Write output to the database. Does nothing unless
@@ -2144,7 +2147,7 b' class InteractiveShell(Configurable, Magic):'
2144 # Each cell is a *single* input, regardless of how many lines it has
2147 # Each cell is a *single* input, regardless of how many lines it has
2145 self.execution_count += 1
2148 self.execution_count += 1
2146
2149
2147 def run_ast_nodes(self, nodelist, interactivity=1):
2150 def run_ast_nodes(self, nodelist, cell_name, interactivity=1):
2148 """Run a sequence of AST nodes. The execution mode depends on the
2151 """Run a sequence of AST nodes. The execution mode depends on the
2149 interactivity parameter.
2152 interactivity parameter.
2150
2153
@@ -2167,128 +2170,19 b' class InteractiveShell(Configurable, Magic):'
2167 else:
2170 else:
2168 to_run_exec, to_run_interactive = [], nodelist
2171 to_run_exec, to_run_interactive = [], nodelist
2169
2172
2173 exec_count = self.execution_count
2170 if to_run_exec:
2174 if to_run_exec:
2171 mod = ast.Module(to_run_exec)
2175 mod = ast.Module(to_run_exec)
2172 name = "<ipython-prompt-%d-exec>" % self.execution_count
2176 self.code_to_run = code = self.compile(mod, cell_name, "exec")
2173 self.code_to_run = code = compile(mod, name, "exec")
2174 if self.run_code(code) == 1:
2177 if self.run_code(code) == 1:
2175 return
2178 return
2176
2179
2177 if to_run_interactive:
2180 if to_run_interactive:
2178 mod = ast.Interactive(to_run_interactive)
2181 mod = ast.Interactive(to_run_interactive)
2179 name = "<ipython-prompt-%d-interactive>" % self.execution_count
2182 self.code_to_run = code = self.compile(mod, cell_name, "single")
2180 self.code_to_run = code = compile(mod, name, "single")
2181 return self.run_code(code)
2183 return self.run_code(code)
2182
2184
2183
2185
2184 def run_cell(self, cell, store_history=True):
2185 """Run the contents of an entire multiline 'cell' of code, and store it
2186 in the history.
2187
2188 The cell is split into separate blocks which can be executed
2189 individually. Then, based on how many blocks there are, they are
2190 executed as follows:
2191
2192 - A single block: 'single' mode. If it is also a single line, dynamic
2193 transformations, including automagic and macros, will be applied.
2194
2195 If there's more than one block, it depends:
2196
2197 - if the last one is no more than two lines long, run all but the last
2198 in 'exec' mode and the very last one in 'single' mode. This makes it
2199 easy to type simple expressions at the end to see computed values. -
2200 otherwise (last one is also multiline), run all in 'exec' mode
2201
2202 When code is executed in 'single' mode, :func:`sys.displayhook` fires,
2203 results are displayed and output prompts are computed. In 'exec' mode,
2204 no results are displayed unless :func:`print` is called explicitly;
2205 this mode is more akin to running a script.
2206
2207 Parameters
2208 ----------
2209 cell : str
2210 A single or multiline string.
2211 """
2212 # Store the untransformed code
2213 raw_cell = cell
2214
2215 # Code transformation and execution must take place with our
2216 # modifications to builtins.
2217 with self.builtin_trap:
2218
2219 # We need to break up the input into executable blocks that can
2220 # be runin 'single' mode, to provide comfortable user behavior.
2221 blocks = self.input_splitter.split_blocks(cell)
2222
2223 if not blocks: # Blank cell
2224 return
2225
2226 # We only do dynamic transforms on a single line. But a macro
2227 # can be expanded to several lines, so we need to split it
2228 # into input blocks again.
2229 if len(cell.splitlines()) <= 1:
2230 cell = self.prefilter_manager.prefilter_line(blocks[0])
2231 blocks = self.input_splitter.split_blocks(cell)
2232
2233 # Store the 'ipython' version of the cell as well, since
2234 # that's what needs to go into the translated history and get
2235 # executed (the original cell may contain non-python syntax).
2236 cell = ''.join(blocks)
2237
2238 # Store raw and processed history
2239 if store_history:
2240 self.history_manager.store_inputs(self.execution_count,
2241 cell, raw_cell)
2242
2243 self.logger.log(cell, raw_cell)
2244
2245 # All user code execution should take place with our
2246 # modified displayhook.
2247 with self.display_trap:
2248 # Single-block input should behave like an interactive prompt
2249 if len(blocks) == 1:
2250 out = self.run_source(blocks[0])
2251 # Write output to the database. Does nothing unless
2252 # history output logging is enabled.
2253 if store_history:
2254 self.history_manager.store_output(self.execution_count)
2255 # Since we return here, we need to update the
2256 # execution count
2257 self.execution_count += 1
2258 return out
2259
2260 # In multi-block input, if the last block is a simple (one-two
2261 # lines) expression, run it in single mode so it produces output.
2262 # Otherwise just run it all in 'exec' mode. This seems like a
2263 # reasonable usability design.
2264 last = blocks[-1]
2265 last_nlines = len(last.splitlines())
2266
2267 if last_nlines < 2:
2268 # Here we consider the cell split between 'body' and 'last',
2269 # store all history and execute 'body', and if successful, then
2270 # proceed to execute 'last'.
2271
2272 # Get the main body to run as a cell
2273 ipy_body = ''.join(blocks[:-1])
2274 retcode = self.run_source(ipy_body, symbol='exec',
2275 post_execute=False)
2276 if retcode==0:
2277 # Last expression compiled as 'single' so it
2278 # produces output
2279 self.run_source(last)
2280 else:
2281 # Run the whole cell as one entity, storing both raw and
2282 # processed input in history
2283 self.run_source(cell, symbol='exec')
2284
2285 # Write output to the database. Does nothing unless
2286 # history output logging is enabled.
2287 if store_history:
2288 self.history_manager.store_output(self.execution_count)
2289 # Each cell is a *single* input, regardless of how many lines it has
2290 self.execution_count += 1
2291
2292 # PENDING REMOVAL: this method is slated for deletion, once our new
2186 # PENDING REMOVAL: this method is slated for deletion, once our new
2293 # input logic has been 100% moved to frontends and is stable.
2187 # input logic has been 100% moved to frontends and is stable.
2294 def runlines(self, lines, clean=False):
2188 def runlines(self, lines, clean=False):
@@ -2378,7 +2272,8 b' class InteractiveShell(Configurable, Magic):'
2378 print 'encoding', self.stdin_encoding # dbg
2272 print 'encoding', self.stdin_encoding # dbg
2379
2273
2380 try:
2274 try:
2381 code = self.compile(usource, symbol, self.execution_count)
2275 code_name = self.compile.cache(usource, self.execution_count)
2276 code = self.compile(usource, code_name, symbol)
2382 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2277 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2383 # Case 1
2278 # Case 1
2384 self.showsyntaxerror(filename)
2279 self.showsyntaxerror(filename)
General Comments 0
You need to be logged in to leave comments. Login now