Show More
@@ -2276,6 +2276,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2276 | 2276 | |
|
2277 | 2277 | # Determine stack_depth depending on where run_line_magic() has been called |
|
2278 | 2278 | stack_depth = _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: | |
|
2279 | 2283 | magic_arg_s = self.var_expand(line, stack_depth) |
|
2280 | 2284 | # Put magic args in a list so we can call with f(*a) syntax |
|
2281 | 2285 | args = [magic_arg_s] |
@@ -2318,6 +2322,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2318 | 2322 | # This will need to be updated if the internal calling logic gets |
|
2319 | 2323 | # refactored, or else we'll be expanding the wrong variables. |
|
2320 | 2324 | stack_depth = 2 |
|
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: | |
|
2321 | 2329 | magic_arg_s = self.var_expand(line, stack_depth) |
|
2322 | 2330 | with self.builtin_trap: |
|
2323 | 2331 | result = fn(magic_arg_s, cell) |
@@ -265,6 +265,25 b' def _function_magic_marker(magic_kind):' | |||
|
265 | 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 | 287 | # Create the actual decorators for public use |
|
269 | 288 | |
|
270 | 289 | # These three are used to decorate methods in class definitions |
@@ -36,7 +36,8 b' from IPython.core import page' | |||
|
36 | 36 | from IPython.core.error import UsageError |
|
37 | 37 | from IPython.core.macro import Macro |
|
38 | 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 | 41 | from IPython.testing.skipdoctest import skip_doctest |
|
41 | 42 | from IPython.utils.contexts import preserve_keys |
|
42 | 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 | 185 | python-profiler package from non-free.""") |
|
185 | 186 | |
|
186 | 187 | @skip_doctest |
|
188 | @no_var_expand | |
|
187 | 189 | @line_cell_magic |
|
188 | 190 | def prun(self, parameter_s='', cell=None): |
|
189 | 191 | |
@@ -293,6 +295,11 b' python-profiler package from non-free.""")' | |||
|
293 | 295 | You can read the complete documentation for the profile module with:: |
|
294 | 296 | |
|
295 | 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 | 304 | opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q', |
|
298 | 305 | list_all=True, posix=False) |
@@ -422,6 +429,7 b' python-profiler package from non-free.""")' | |||
|
422 | 429 | You can omit this in cell magic mode. |
|
423 | 430 | """ |
|
424 | 431 | ) |
|
432 | @no_var_expand | |
|
425 | 433 | @line_cell_magic |
|
426 | 434 | def debug(self, line='', cell=None): |
|
427 | 435 | """Activate the interactive debugger. |
@@ -442,6 +450,11 b' python-profiler package from non-free.""")' | |||
|
442 | 450 | |
|
443 | 451 | If you want IPython to automatically do this on every exception, see |
|
444 | 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 | 459 | args = magic_arguments.parse_argstring(self.debug, line) |
|
447 | 460 | |
@@ -972,6 +985,7 b' python-profiler package from non-free.""")' | |||
|
972 | 985 | print("Wall time: %10.2f s." % (twall1 - twall0)) |
|
973 | 986 | |
|
974 | 987 | @skip_doctest |
|
988 | @no_var_expand | |
|
975 | 989 | @line_cell_magic |
|
976 | 990 | @needs_local_scope |
|
977 | 991 | def timeit(self, line='', cell=None, local_ns=None): |
@@ -1017,6 +1031,9 b' python-profiler package from non-free.""")' | |||
|
1017 | 1031 | -o: return a TimeitResult that can be stored in a variable to inspect |
|
1018 | 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 | 1038 | Examples |
|
1022 | 1039 | -------- |
@@ -1161,6 +1178,7 b' python-profiler package from non-free.""")' | |||
|
1161 | 1178 | return timeit_result |
|
1162 | 1179 | |
|
1163 | 1180 | @skip_doctest |
|
1181 | @no_var_expand | |
|
1164 | 1182 | @needs_local_scope |
|
1165 | 1183 | @line_cell_magic |
|
1166 | 1184 | def time(self,line='', cell=None, local_ns=None): |
@@ -1181,6 +1199,10 b' python-profiler package from non-free.""")' | |||
|
1181 | 1199 |
This function provides very basic timing functionality. Use the timeit |
|
1182 | 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 | 1206 | Examples |
|
1185 | 1207 | -------- |
|
1186 | 1208 | :: |
@@ -1088,6 +1088,7 b' def test_logging_magic_quiet_from_config():' | |||
|
1088 | 1088 | finally: |
|
1089 | 1089 | _ip.logger.logstop() |
|
1090 | 1090 | |
|
1091 | ||
|
1091 | 1092 | def test_logging_magic_not_quiet(): |
|
1092 | 1093 | _ip.config.LoggingMagics.quiet = False |
|
1093 | 1094 | lm = logging.LoggingMagics(shell=_ip) |
@@ -1098,9 +1099,15 b' def test_logging_magic_not_quiet():' | |||
|
1098 | 1099 | finally: |
|
1099 | 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 | 1110 | # this is slow, put at the end for local testing. |
|
1103 | ## | |
|
1104 | 1111 | def test_timeit_arguments(): |
|
1105 | 1112 | "Test valid timeit arguments, should not cause SyntaxError (GH #1269)" |
|
1106 | 1113 | if sys.version_info < (3,7): |
General Comments 0
You need to be logged in to leave comments.
Login now