From 4f3b0574b572b51422aab6e9ed3d89fec31eaeab 2019-04-23 00:00:50 From: Matthias Bussonnier Date: 2019-04-23 00:00:50 Subject: [PATCH] Fix applying @needs_global_scope to cell magics. There was some side effect in some magic to allow passing needs_local_scope. We know pass the global_scope to cell magice when using @needs_local_scope, but at the same time this means that we can't rely on the existance of local_ns from within the magic to know wheter we are cell-called or line called. Fixes #11659 --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index ef57255..ce8ceb1 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2345,7 +2345,7 @@ class InteractiveShell(SingletonConfigurable): magic_arg_s = self.var_expand(line, stack_depth) kwargs = {} if getattr(fn, "needs_local_scope", False): - kwargs['local_ns'] = sys._getframe(stack_depth).f_locals + kwargs['local_ns'] = self.user_ns with self.builtin_trap: args = (magic_arg_s, cell) diff --git a/IPython/core/magics/execution.py b/IPython/core/magics/execution.py index d58fa3c..510750e 100644 --- a/IPython/core/magics/execution.py +++ b/IPython/core/magics/execution.py @@ -1127,8 +1127,8 @@ python-profiler package from non-free.""") ns = {} glob = self.shell.user_ns # handles global vars with same name as local vars. We store them in conflict_globs. - if local_ns is not None: - conflict_globs = {} + conflict_globs = {} + if local_ns and cell is None: for var_name, var_val in glob.items(): if var_name in local_ns: conflict_globs[var_name] = var_val @@ -1154,9 +1154,8 @@ python-profiler package from non-free.""") timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision) # Restore global vars from conflict_globs - if local_ns is not None: - if len(conflict_globs) > 0: - glob.update(conflict_globs) + if conflict_globs: + glob.update(conflict_globs) if not quiet : # Check best timing is greater than zero to avoid a diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index 7914d48..f8ce238 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -419,6 +419,16 @@ def test_time3(): "run = 0\n" "run += 1") +def test_time_local_ns(): + """ + Test that local_ns is actually global_ns when running a cell magic + """ + ip = get_ipython() + ip.run_cell("%%time\n" + "myvar = 1") + nt.assert_equal(ip.user_ns['myvar'], 1) + del ip.user_ns['myvar'] + def test_doctest_mode(): "Toggle doctest_mode twice, it should be a no-op and run without error" _ip.magic('doctest_mode')