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