##// END OF EJS Templates
Don't expand user variables in execution magics...
Min RK -
Show More
@@ -2273,10 +2273,14 b' class InteractiveShell(SingletonConfigurable):'
2273 # Note: this is the distance in the stack to the user's frame.
2273 # Note: this is the distance in the stack to the user's frame.
2274 # This will need to be updated if the internal calling logic gets
2274 # This will need to be updated if the internal calling logic gets
2275 # refactored, or else we'll be expanding the wrong variables.
2275 # refactored, or else we'll be expanding the wrong variables.
2276
2276
2277 # Determine stack_depth depending on where run_line_magic() has been called
2277 # Determine stack_depth depending on where run_line_magic() has been called
2278 stack_depth = _stack_depth
2278 stack_depth = _stack_depth
2279 magic_arg_s = self.var_expand(line, stack_depth)
2279 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2280 # magic has opted out of var_expand
2281 magic_arg_s = line
2282 else:
2283 magic_arg_s = self.var_expand(line, stack_depth)
2280 # Put magic args in a list so we can call with f(*a) syntax
2284 # Put magic args in a list so we can call with f(*a) syntax
2281 args = [magic_arg_s]
2285 args = [magic_arg_s]
2282 kwargs = {}
2286 kwargs = {}
@@ -2284,12 +2288,12 b' class InteractiveShell(SingletonConfigurable):'
2284 if getattr(fn, "needs_local_scope", False):
2288 if getattr(fn, "needs_local_scope", False):
2285 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2289 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2286 with self.builtin_trap:
2290 with self.builtin_trap:
2287 result = fn(*args,**kwargs)
2291 result = fn(*args, **kwargs)
2288 return result
2292 return result
2289
2293
2290 def run_cell_magic(self, magic_name, line, cell):
2294 def run_cell_magic(self, magic_name, line, cell):
2291 """Execute the given cell magic.
2295 """Execute the given cell magic.
2292
2296
2293 Parameters
2297 Parameters
2294 ----------
2298 ----------
2295 magic_name : str
2299 magic_name : str
@@ -2318,7 +2322,11 b' class InteractiveShell(SingletonConfigurable):'
2318 # This will need to be updated if the internal calling logic gets
2322 # This will need to be updated if the internal calling logic gets
2319 # refactored, or else we'll be expanding the wrong variables.
2323 # refactored, or else we'll be expanding the wrong variables.
2320 stack_depth = 2
2324 stack_depth = 2
2321 magic_arg_s = self.var_expand(line, stack_depth)
2325 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2326 # magic has opted out of var_expand
2327 magic_arg_s = line
2328 else:
2329 magic_arg_s = self.var_expand(line, stack_depth)
2322 with self.builtin_trap:
2330 with self.builtin_trap:
2323 result = fn(magic_arg_s, cell)
2331 result = fn(magic_arg_s, cell)
2324 return result
2332 return result
@@ -265,6 +265,25 b' def _function_magic_marker(magic_kind):'
265 return magic_deco
265 return magic_deco
266
266
267
267
268 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
269
270
271 def no_var_expand(magic_func):
272 """Mark a magic function as not needing variable expansion
273
274 By default, IPython interprets `{a}` or `$a` in the line passed to magics
275 as variables that should be interpolated from the interactive namespace
276 before passing the line to the magic function.
277 This is not always desirable, e.g. when the magic executes Python code
278 (%timeit, %time, etc.).
279 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
280
281 .. versionadded:: 7.2
282 """
283 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
284 return magic_func
285
286
268 # Create the actual decorators for public use
287 # Create the actual decorators for public use
269
288
270 # These three are used to decorate methods in class definitions
289 # These three are used to decorate methods in class definitions
@@ -36,7 +36,8 b' from IPython.core import page'
36 from IPython.core.error import UsageError
36 from IPython.core.error import UsageError
37 from IPython.core.macro import Macro
37 from IPython.core.macro import Macro
38 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
38 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
39 line_cell_magic, on_off, needs_local_scope)
39 line_cell_magic, on_off, needs_local_scope,
40 no_var_expand)
40 from IPython.testing.skipdoctest import skip_doctest
41 from IPython.testing.skipdoctest import skip_doctest
41 from IPython.utils.contexts import preserve_keys
42 from IPython.utils.contexts import preserve_keys
42 from IPython.utils.capture import capture_output
43 from IPython.utils.capture import capture_output
@@ -184,6 +185,7 b' python packages because of its non-free license. To use profiling, install the'
184 python-profiler package from non-free.""")
185 python-profiler package from non-free.""")
185
186
186 @skip_doctest
187 @skip_doctest
188 @no_var_expand
187 @line_cell_magic
189 @line_cell_magic
188 def prun(self, parameter_s='', cell=None):
190 def prun(self, parameter_s='', cell=None):
189
191
@@ -293,6 +295,11 b' python-profiler package from non-free.""")'
293 You can read the complete documentation for the profile module with::
295 You can read the complete documentation for the profile module with::
294
296
295 In [1]: import profile; profile.help()
297 In [1]: import profile; profile.help()
298
299 .. versionchanged:: 7.2
300 User variables are no longer expanded,
301 the magic line is always left unmodified.
302
296 """
303 """
297 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
304 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
298 list_all=True, posix=False)
305 list_all=True, posix=False)
@@ -422,6 +429,7 b' python-profiler package from non-free.""")'
422 You can omit this in cell magic mode.
429 You can omit this in cell magic mode.
423 """
430 """
424 )
431 )
432 @no_var_expand
425 @line_cell_magic
433 @line_cell_magic
426 def debug(self, line='', cell=None):
434 def debug(self, line='', cell=None):
427 """Activate the interactive debugger.
435 """Activate the interactive debugger.
@@ -442,6 +450,11 b' python-profiler package from non-free.""")'
442
450
443 If you want IPython to automatically do this on every exception, see
451 If you want IPython to automatically do this on every exception, see
444 the %pdb magic for more details.
452 the %pdb magic for more details.
453
454 .. versionchanged:: 7.2
455 When running code, user variables are no longer expanded,
456 the magic line is always left unmodified.
457
445 """
458 """
446 args = magic_arguments.parse_argstring(self.debug, line)
459 args = magic_arguments.parse_argstring(self.debug, line)
447
460
@@ -972,6 +985,7 b' python-profiler package from non-free.""")'
972 print("Wall time: %10.2f s." % (twall1 - twall0))
985 print("Wall time: %10.2f s." % (twall1 - twall0))
973
986
974 @skip_doctest
987 @skip_doctest
988 @no_var_expand
975 @line_cell_magic
989 @line_cell_magic
976 @needs_local_scope
990 @needs_local_scope
977 def timeit(self, line='', cell=None, local_ns=None):
991 def timeit(self, line='', cell=None, local_ns=None):
@@ -1017,6 +1031,9 b' python-profiler package from non-free.""")'
1017 -o: return a TimeitResult that can be stored in a variable to inspect
1031 -o: return a TimeitResult that can be stored in a variable to inspect
1018 the result in more details.
1032 the result in more details.
1019
1033
1034 .. versionchanged:: 7.2
1035 User variables are no longer expanded,
1036 the magic line is always left unmodified.
1020
1037
1021 Examples
1038 Examples
1022 --------
1039 --------
@@ -1161,6 +1178,7 b' python-profiler package from non-free.""")'
1161 return timeit_result
1178 return timeit_result
1162
1179
1163 @skip_doctest
1180 @skip_doctest
1181 @no_var_expand
1164 @needs_local_scope
1182 @needs_local_scope
1165 @line_cell_magic
1183 @line_cell_magic
1166 def time(self,line='', cell=None, local_ns=None):
1184 def time(self,line='', cell=None, local_ns=None):
@@ -1175,12 +1193,16 b' python-profiler package from non-free.""")'
1175 - In line mode you can time a single-line statement (though multiple
1193 - In line mode you can time a single-line statement (though multiple
1176 ones can be chained with using semicolons).
1194 ones can be chained with using semicolons).
1177
1195
1178 - In cell mode, you can time the cell body (a directly
1196 - In cell mode, you can time the cell body (a directly
1179 following statement raises an error).
1197 following statement raises an error).
1180
1198
1181 This function provides very basic timing functionality. Use the timeit
1199 This function provides very basic timing functionality. Use the timeit
1182 magic for more control over the measurement.
1200 magic for more control over the measurement.
1183
1201
1202 .. versionchanged:: 7.2
1203 User variables are no longer expanded,
1204 the magic line is always left unmodified.
1205
1184 Examples
1206 Examples
1185 --------
1207 --------
1186 ::
1208 ::
@@ -1087,7 +1087,8 b' def test_logging_magic_quiet_from_config():'
1087 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1087 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1088 finally:
1088 finally:
1089 _ip.logger.logstop()
1089 _ip.logger.logstop()
1090
1090
1091
1091 def test_logging_magic_not_quiet():
1092 def test_logging_magic_not_quiet():
1092 _ip.config.LoggingMagics.quiet = False
1093 _ip.config.LoggingMagics.quiet = False
1093 lm = logging.LoggingMagics(shell=_ip)
1094 lm = logging.LoggingMagics(shell=_ip)
@@ -1098,9 +1099,15 b' def test_logging_magic_not_quiet():'
1098 finally:
1099 finally:
1099 _ip.logger.logstop()
1100 _ip.logger.logstop()
1100
1101
1101 ##
1102
1103 def test_time_no_var_expand():
1104 _ip.user_ns['a'] = 5
1105 _ip.user_ns['b'] = []
1106 _ip.magic('time b.append("{a}")')
1107 assert _ip.user_ns['b'] == ['{a}']
1108
1109
1102 # this is slow, put at the end for local testing.
1110 # this is slow, put at the end for local testing.
1103 ##
1104 def test_timeit_arguments():
1111 def test_timeit_arguments():
1105 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1112 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1106 if sys.version_info < (3,7):
1113 if sys.version_info < (3,7):
General Comments 0
You need to be logged in to leave comments. Login now