##// END OF EJS Templates
Merge pull request #1671 from takluyver/back-to-the-future...
Thomas Kluyver -
r9163:0aacf477 merge
parent child Browse files
Show More
@@ -90,7 +90,7 b' class CachingCompiler(codeop.Compile):'
90 # Now, we must monkeypatch the linecache directly so that parts of the
90 # Now, we must monkeypatch the linecache directly so that parts of the
91 # stdlib that call it outside our control go through our codepath
91 # stdlib that call it outside our control go through our codepath
92 # (otherwise we'd lose our tracebacks).
92 # (otherwise we'd lose our tracebacks).
93 linecache.checkcache = self.check_cache
93 linecache.checkcache = check_linecache_ipython
94
94
95 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
95 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
96 """Parse code to an AST with the current compiler flags active.
96 """Parse code to an AST with the current compiler flags active.
@@ -134,11 +134,11 b' class CachingCompiler(codeop.Compile):'
134 linecache._ipython_cache[name] = entry
134 linecache._ipython_cache[name] = entry
135 return name
135 return name
136
136
137 def check_cache(self, *args):
137 def check_linecache_ipython(*args):
138 """Call linecache.checkcache() safely protecting our cached values.
138 """Call linecache.checkcache() safely protecting our cached values.
139 """
139 """
140 # First call the orignal checkcache as intended
140 # First call the orignal checkcache as intended
141 linecache._checkcache_ori(*args)
141 linecache._checkcache_ori(*args)
142 # Then, update back the cache with our data, so that tracebacks related
142 # Then, update back the cache with our data, so that tracebacks related
143 # to our compiled codes can be produced.
143 # to our compiled codes can be produced.
144 linecache.cache.update(linecache._ipython_cache)
144 linecache.cache.update(linecache._ipython_cache)
@@ -14,7 +14,6 b''
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import with_statement
18 from __future__ import absolute_import
17 from __future__ import absolute_import
19 from __future__ import print_function
18 from __future__ import print_function
20
19
@@ -42,7 +41,7 b' from IPython.core import ultratb'
42 from IPython.core.alias import AliasManager, AliasError
41 from IPython.core.alias import AliasManager, AliasError
43 from IPython.core.autocall import ExitAutocall
42 from IPython.core.autocall import ExitAutocall
44 from IPython.core.builtin_trap import BuiltinTrap
43 from IPython.core.builtin_trap import BuiltinTrap
45 from IPython.core.compilerop import CachingCompiler
44 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
46 from IPython.core.display_trap import DisplayTrap
45 from IPython.core.display_trap import DisplayTrap
47 from IPython.core.displayhook import DisplayHook
46 from IPython.core.displayhook import DisplayHook
48 from IPython.core.displaypub import DisplayPublisher
47 from IPython.core.displaypub import DisplayPublisher
@@ -1533,7 +1532,7 b' class InteractiveShell(SingletonConfigurable):'
1533 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1532 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1534 color_scheme='NoColor',
1533 color_scheme='NoColor',
1535 tb_offset = 1,
1534 tb_offset = 1,
1536 check_cache=self.compile.check_cache)
1535 check_cache=check_linecache_ipython)
1537
1536
1538 # The instance will store a pointer to the system-wide exception hook,
1537 # The instance will store a pointer to the system-wide exception hook,
1539 # so that runtime code (such as magics) can access it. This is because
1538 # so that runtime code (such as magics) can access it. This is because
@@ -2518,7 +2517,7 b' class InteractiveShell(SingletonConfigurable):'
2518 # raised in user code. It would be nice if there were
2517 # raised in user code. It would be nice if there were
2519 # versions of runlines, execfile that did raise, so
2518 # versions of runlines, execfile that did raise, so
2520 # we could catch the errors.
2519 # we could catch the errors.
2521 self.run_cell(thefile.read(), store_history=False)
2520 self.run_cell(thefile.read(), store_history=False, shell_futures=False)
2522 except:
2521 except:
2523 self.showtraceback()
2522 self.showtraceback()
2524 warn('Unknown failure executing file: <%s>' % fname)
2523 warn('Unknown failure executing file: <%s>' % fname)
@@ -2552,7 +2551,7 b' class InteractiveShell(SingletonConfigurable):'
2552 self._current_cell_magic_body = None
2551 self._current_cell_magic_body = None
2553 return self.run_cell_magic(magic_name, line, cell)
2552 return self.run_cell_magic(magic_name, line, cell)
2554
2553
2555 def run_cell(self, raw_cell, store_history=False, silent=False):
2554 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2556 """Run a complete IPython cell.
2555 """Run a complete IPython cell.
2557
2556
2558 Parameters
2557 Parameters
@@ -2566,6 +2565,11 b' class InteractiveShell(SingletonConfigurable):'
2566 silent : bool
2565 silent : bool
2567 If True, avoid side-effects, such as implicit displayhooks and
2566 If True, avoid side-effects, such as implicit displayhooks and
2568 and logging. silent=True forces store_history=False.
2567 and logging. silent=True forces store_history=False.
2568 shell_futures : bool
2569 If True, the code will share future statements with the interactive
2570 shell. It will both be affected by previous __future__ imports, and
2571 any __future__ imports in the code will affect the shell. If False,
2572 __future__ imports are not shared in either direction.
2569 """
2573 """
2570 if (not raw_cell) or raw_cell.isspace():
2574 if (not raw_cell) or raw_cell.isspace():
2571 return
2575 return
@@ -2583,6 +2587,11 b' class InteractiveShell(SingletonConfigurable):'
2583 self._current_cell_magic_body = \
2587 self._current_cell_magic_body = \
2584 ''.join(self.input_splitter.cell_magic_parts)
2588 ''.join(self.input_splitter.cell_magic_parts)
2585 cell = self.input_splitter.source_reset()
2589 cell = self.input_splitter.source_reset()
2590
2591 # Our own compiler remembers the __future__ environment. If we want to
2592 # run code with a separate __future__ environment, use the default
2593 # compiler
2594 compiler = self.compile if shell_futures else CachingCompiler()
2586
2595
2587 with self.builtin_trap:
2596 with self.builtin_trap:
2588 prefilter_failed = False
2597 prefilter_failed = False
@@ -2612,8 +2621,7 b' class InteractiveShell(SingletonConfigurable):'
2612
2621
2613 with self.display_trap:
2622 with self.display_trap:
2614 try:
2623 try:
2615 code_ast = self.compile.ast_parse(cell,
2624 code_ast = compiler.ast_parse(cell, filename=cell_name)
2616 filename=cell_name)
2617 except IndentationError:
2625 except IndentationError:
2618 self.showindentationerror()
2626 self.showindentationerror()
2619 if store_history:
2627 if store_history:
@@ -2630,7 +2638,7 b' class InteractiveShell(SingletonConfigurable):'
2630
2638
2631 interactivity = "none" if silent else self.ast_node_interactivity
2639 interactivity = "none" if silent else self.ast_node_interactivity
2632 self.run_ast_nodes(code_ast.body, cell_name,
2640 self.run_ast_nodes(code_ast.body, cell_name,
2633 interactivity=interactivity)
2641 interactivity=interactivity, compiler=compiler)
2634
2642
2635 # Execute any registered post-execution functions.
2643 # Execute any registered post-execution functions.
2636 # unless we are silent
2644 # unless we are silent
@@ -2686,7 +2694,8 b' class InteractiveShell(SingletonConfigurable):'
2686 return ast.fix_missing_locations(node)
2694 return ast.fix_missing_locations(node)
2687
2695
2688
2696
2689 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2697 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2698 compiler=compile):
2690 """Run a sequence of AST nodes. The execution mode depends on the
2699 """Run a sequence of AST nodes. The execution mode depends on the
2691 interactivity parameter.
2700 interactivity parameter.
2692
2701
@@ -2703,6 +2712,9 b' class InteractiveShell(SingletonConfigurable):'
2703 will run the last node interactively only if it is an expression (i.e.
2712 will run the last node interactively only if it is an expression (i.e.
2704 expressions in loops or other blocks are not displayed. Other values
2713 expressions in loops or other blocks are not displayed. Other values
2705 for this parameter will raise a ValueError.
2714 for this parameter will raise a ValueError.
2715 compiler : callable
2716 A function with the same interface as the built-in compile(), to turn
2717 the AST nodes into code objects. Default is the built-in compile().
2706 """
2718 """
2707 if not nodelist:
2719 if not nodelist:
2708 return
2720 return
@@ -2727,13 +2739,13 b' class InteractiveShell(SingletonConfigurable):'
2727 try:
2739 try:
2728 for i, node in enumerate(to_run_exec):
2740 for i, node in enumerate(to_run_exec):
2729 mod = ast.Module([node])
2741 mod = ast.Module([node])
2730 code = self.compile(mod, cell_name, "exec")
2742 code = compiler(mod, cell_name, "exec")
2731 if self.run_code(code):
2743 if self.run_code(code):
2732 return True
2744 return True
2733
2745
2734 for i, node in enumerate(to_run_interactive):
2746 for i, node in enumerate(to_run_interactive):
2735 mod = ast.Interactive([node])
2747 mod = ast.Interactive([node])
2736 code = self.compile(mod, cell_name, "single")
2748 code = compiler(mod, cell_name, "single")
2737 if self.run_code(code):
2749 if self.run_code(code):
2738 return True
2750 return True
2739
2751
@@ -67,7 +67,7 b' def test_compiler_check_cache():'
67 cp = compilerop.CachingCompiler()
67 cp = compilerop.CachingCompiler()
68 cp.cache('x=1', 99)
68 cp.cache('x=1', 99)
69 # Ensure now that after clearing the cache, our entries survive
69 # Ensure now that after clearing the cache, our entries survive
70 cp.check_cache()
70 linecache.checkcache()
71 for k in linecache.cache:
71 for k in linecache.cache:
72 if k.startswith('<ipython-input-99'):
72 if k.startswith('<ipython-input-99'):
73 break
73 break
@@ -384,6 +384,22 b' class InteractiveShellTestCase(unittest.TestCase):'
384 finally:
384 finally:
385 # Reset the custom exception hook
385 # Reset the custom exception hook
386 ip.set_custom_exc((), None)
386 ip.set_custom_exc((), None)
387
388 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
389 def test_future_environment(self):
390 "Can we run code with & without the shell's __future__ imports?"
391 ip.run_cell("from __future__ import division")
392 ip.run_cell("a = 1/2", shell_futures=True)
393 self.assertEqual(ip.user_ns['a'], 0.5)
394 ip.run_cell("b = 1/2", shell_futures=False)
395 self.assertEqual(ip.user_ns['b'], 0)
396
397 ip.compile.reset_compiler_flags()
398 # This shouldn't leak to the shell's compiler
399 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
400 self.assertEqual(ip.user_ns['c'], 0.5)
401 ip.run_cell("d = 1/2", shell_futures=True)
402 self.assertEqual(ip.user_ns['d'], 0)
387
403
388
404
389 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
405 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
@@ -827,7 +827,7 b' def test_edit_interactive():'
827 except code.InteractivelyDefined as e:
827 except code.InteractivelyDefined as e:
828 nt.assert_equal(e.index, n)
828 nt.assert_equal(e.index, n)
829 else:
829 else:
830 nt.fail("Should have raised InteractivelyDefined")
830 raise AssertionError("Should have raised InteractivelyDefined")
831
831
832
832
833 def test_edit_cell():
833 def test_edit_cell():
General Comments 0
You need to be logged in to leave comments. Login now