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 = |
|
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 |
|
|
137 | def check_linecache_ipython(*args): | |
138 |
|
|
138 | """Call linecache.checkcache() safely protecting our cached values. | |
139 |
|
|
139 | """ | |
140 |
|
|
140 | # First call the orignal checkcache as intended | |
141 |
|
|
141 | linecache._checkcache_ori(*args) | |
142 |
|
|
142 | # Then, update back the cache with our data, so that tracebacks related | |
143 |
|
|
143 | # to our compiled codes can be produced. | |
144 |
|
|
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= |
|
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 = |
|
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 = |
|
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 = |
|
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 |
|
|
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 |
|
|
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