##// END OF EJS Templates
Preserve function/method identity in magic decorators...
Nikita Kniazev -
Show More
@@ -20,7 +20,6 b' from traitlets.config.configurable import Configurable'
20 from . import oinspect
20 from . import oinspect
21 from .error import UsageError
21 from .error import UsageError
22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
23 from decorator import decorator
24 from ..utils.ipstruct import Struct
23 from ..utils.ipstruct import Struct
25 from ..utils.process import arg_split
24 from ..utils.process import arg_split
26 from ..utils.text import dedent
25 from ..utils.text import dedent
@@ -184,20 +183,18 b' def _method_magic_marker(magic_kind):'
184 # This is a closure to capture the magic_kind. We could also use a class,
183 # This is a closure to capture the magic_kind. We could also use a class,
185 # but it's overkill for just that one bit of state.
184 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
185 def magic_deco(arg):
187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):
186 if callable(arg):
190 # "Naked" decorator call (just @foo, no args)
187 # "Naked" decorator call (just @foo, no args)
191 func = arg
188 func = arg
192 name = func.__name__
189 name = func.__name__
193 retval = decorator(call, func)
190 retval = arg
194 record_magic(magics, magic_kind, name, name)
191 record_magic(magics, magic_kind, name, name)
195 elif isinstance(arg, str):
192 elif isinstance(arg, str):
196 # Decorator called with arguments (@foo('bar'))
193 # Decorator called with arguments (@foo('bar'))
197 name = arg
194 name = arg
198 def mark(func, *a, **kw):
195 def mark(func, *a, **kw):
199 record_magic(magics, magic_kind, name, func.__name__)
196 record_magic(magics, magic_kind, name, func.__name__)
200 return decorator(call, func)
197 return func
201 retval = mark
198 retval = mark
202 else:
199 else:
203 raise TypeError("Decorator can only be called with "
200 raise TypeError("Decorator can only be called with "
@@ -217,8 +214,6 b' def _function_magic_marker(magic_kind):'
217 # This is a closure to capture the magic_kind. We could also use a class,
214 # This is a closure to capture the magic_kind. We could also use a class,
218 # but it's overkill for just that one bit of state.
215 # but it's overkill for just that one bit of state.
219 def magic_deco(arg):
216 def magic_deco(arg):
220 call = lambda f, *a, **k: f(*a, **k)
221
222 # Find get_ipython() in the caller's namespace
217 # Find get_ipython() in the caller's namespace
223 caller = sys._getframe(1)
218 caller = sys._getframe(1)
224 for ns in ['f_locals', 'f_globals', 'f_builtins']:
219 for ns in ['f_locals', 'f_globals', 'f_builtins']:
@@ -236,13 +231,13 b' def _function_magic_marker(magic_kind):'
236 func = arg
231 func = arg
237 name = func.__name__
232 name = func.__name__
238 ip.register_magic_function(func, magic_kind, name)
233 ip.register_magic_function(func, magic_kind, name)
239 retval = decorator(call, func)
234 retval = arg
240 elif isinstance(arg, str):
235 elif isinstance(arg, str):
241 # Decorator called with arguments (@foo('bar'))
236 # Decorator called with arguments (@foo('bar'))
242 name = arg
237 name = arg
243 def mark(func, *a, **kw):
238 def mark(func, *a, **kw):
244 ip.register_magic_function(func, magic_kind, name)
239 ip.register_magic_function(func, magic_kind, name)
245 return decorator(call, func)
240 return func
246 retval = mark
241 retval = mark
247 else:
242 else:
248 raise TypeError("Decorator can only be called with "
243 raise TypeError("Decorator can only be called with "
@@ -74,6 +74,7 b' class BasicMagics(Magics):'
74 These are various magics that don't fit into specific categories but that
74 These are various magics that don't fit into specific categories but that
75 are all part of the base 'IPython experience'."""
75 are all part of the base 'IPython experience'."""
76
76
77 @skip_doctest
77 @magic_arguments.magic_arguments()
78 @magic_arguments.magic_arguments()
78 @magic_arguments.argument(
79 @magic_arguments.argument(
79 '-l', '--line', action='store_true',
80 '-l', '--line', action='store_true',
@@ -54,44 +54,73 b' class ConfigMagics(Magics):'
54
54
55 In [1]: %config
55 In [1]: %config
56 Available objects for config:
56 Available objects for config:
57 TerminalInteractiveShell
58 HistoryManager
59 PrefilterManager
60 AliasManager
57 AliasManager
61 IPCompleter
62 DisplayFormatter
58 DisplayFormatter
59 HistoryManager
60 IPCompleter
61 LoggingMagics
62 MagicsManager
63 OSMagics
64 PrefilterManager
65 ScriptMagics
66 TerminalInteractiveShell
63
67
64 To view what is configurable on a given class, just pass the class
68 To view what is configurable on a given class, just pass the class
65 name::
69 name::
66
70
67 In [2]: %config IPCompleter
71 In [2]: %config IPCompleter
68 IPCompleter options
72 IPCompleter(Completer) options
69 -----------------
73 ----------------------------
70 IPCompleter.omit__names=<Enum>
74 IPCompleter.backslash_combining_completions=<Bool>
71 Current: 2
75 Enable unicode completions, e.g. \\alpha<tab> . Includes completion of latex
72 Choices: (0, 1, 2)
76 commands, unicode names, and expanding unicode characters back to latex
73 Instruct the completer to omit private method names
77 commands.
74 Specifically, when completing on ``object.<tab>``.
75 When 2 [default]: all names that start with '_' will be excluded.
76 When 1: all 'magic' names (``__foo__``) will be excluded.
77 When 0: nothing will be excluded.
78 IPCompleter.merge_completions=<CBool>
79 Current: True
78 Current: True
80 Whether to merge completion results into a single list
79 IPCompleter.debug=<Bool>
81 If False, only the completion results from the first non-empty
80 Enable debug for the Completer. Mostly print extra information for
82 completer will be returned.
81 experimental jedi integration.
83 IPCompleter.limit_to__all__=<CBool>
82 Current: False
83 IPCompleter.greedy=<Bool>
84 Activate greedy completion
85 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
86 This will enable completion on elements of lists, results of function calls, etc.,
87 but can be unsafe because the code is actually evaluated on TAB.
84 Current: False
88 Current: False
89 IPCompleter.jedi_compute_type_timeout=<Int>
90 Experimental: restrict time (in milliseconds) during which Jedi can compute types.
91 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
92 performance by preventing jedi to build its cache.
93 Current: 400
94 IPCompleter.limit_to__all__=<Bool>
95 DEPRECATED as of version 5.0.
85 Instruct the completer to use __all__ for the completion
96 Instruct the completer to use __all__ for the completion
86 Specifically, when completing on ``object.<tab>``.
97 Specifically, when completing on ``object.<tab>``.
87 When True: only those names in obj.__all__ will be included.
98 When True: only those names in obj.__all__ will be included.
88 When False [default]: the __all__ attribute is ignored
99 When False [default]: the __all__ attribute is ignored
89 IPCompleter.greedy=<CBool>
90 Current: False
100 Current: False
91 Activate greedy completion
101 IPCompleter.merge_completions=<Bool>
92 This will enable completion on elements of lists, results of
102 Whether to merge completion results into a single list
93 function calls, etc., but can be unsafe because the code is
103 If False, only the completion results from the first non-empty
94 actually evaluated on TAB.
104 completer will be returned.
105 Current: True
106 IPCompleter.omit__names=<Enum>
107 Instruct the completer to omit private method names
108 Specifically, when completing on ``object.<tab>``.
109 When 2 [default]: all names that start with '_' will be excluded.
110 When 1: all 'magic' names (``__foo__``) will be excluded.
111 When 0: nothing will be excluded.
112 Choices: any of [0, 1, 2]
113 Current: 2
114 IPCompleter.profile_completions=<Bool>
115 If True, emit profiling data for completion subsystem using cProfile.
116 Current: False
117 IPCompleter.profiler_output_dir=<Unicode>
118 Template for path at which to output profile data for completions.
119 Current: '.completion_profiles'
120 IPCompleter.use_jedi=<Bool>
121 Experimental: Use Jedi to generate autocompletions. Default to True if jedi
122 is installed.
123 Current: True
95
124
96 but the real use is in setting values::
125 but the real use is in setting values::
97
126
@@ -118,7 +147,7 b' class ConfigMagics(Magics):'
118 # print available configurable names
147 # print available configurable names
119 print("Available objects for config:")
148 print("Available objects for config:")
120 for name in classnames:
149 for name in classnames:
121 print(" ", name)
150 print(" ", name)
122 return
151 return
123 elif line in classnames:
152 elif line in classnames:
124 # `%config TerminalInteractiveShell` will print trait info for
153 # `%config TerminalInteractiveShell` will print trait info for
@@ -304,6 +304,8 b' class ScriptMagics(Magics):'
304 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
304 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
305 rc = p.returncode or -9
305 rc = p.returncode or -9
306 raise CalledProcessError(rc, cell)
306 raise CalledProcessError(rc, cell)
307
308 shebang.__skip_doctest__ = os.name != "posix"
307
309
308 def _run_script(self, p, cell, to_close):
310 def _run_script(self, p, cell, to_close):
309 """callback for running the script in the background"""
311 """callback for running the script in the background"""
@@ -346,10 +346,15 b' class InteractiveShellTestCase(unittest.TestCase):'
346 "A line magic"
346 "A line magic"
347
347
348 # Get info on line magic
348 # Get info on line magic
349 lfind = ip._ofind('lmagic')
349 lfind = ip._ofind("lmagic")
350 info = dict(found=True, isalias=False, ismagic=True,
350 info = dict(
351 namespace = 'IPython internal', obj= lmagic.__wrapped__,
351 found=True,
352 parent = None)
352 isalias=False,
353 ismagic=True,
354 namespace="IPython internal",
355 obj=lmagic,
356 parent=None,
357 )
353 self.assertEqual(lfind, info)
358 self.assertEqual(lfind, info)
354
359
355 def test_ofind_cell_magic(self):
360 def test_ofind_cell_magic(self):
@@ -360,10 +365,15 b' class InteractiveShellTestCase(unittest.TestCase):'
360 "A cell magic"
365 "A cell magic"
361
366
362 # Get info on cell magic
367 # Get info on cell magic
363 find = ip._ofind('cmagic')
368 find = ip._ofind("cmagic")
364 info = dict(found=True, isalias=False, ismagic=True,
369 info = dict(
365 namespace = 'IPython internal', obj= cmagic.__wrapped__,
370 found=True,
366 parent = None)
371 isalias=False,
372 ismagic=True,
373 namespace="IPython internal",
374 obj=cmagic,
375 parent=None,
376 )
367 self.assertEqual(find, info)
377 self.assertEqual(find, info)
368
378
369 def test_ofind_property_with_error(self):
379 def test_ofind_property_with_error(self):
@@ -17,6 +17,7 b' import inspect, os, sys, textwrap'
17
17
18 from IPython.core.error import UsageError
18 from IPython.core.error import UsageError
19 from IPython.core.magic import Magics, magics_class, line_magic
19 from IPython.core.magic import Magics, magics_class, line_magic
20 from IPython.testing.skipdoctest import skip_doctest
20 from traitlets import Bool
21 from traitlets import Bool
21
22
22
23
@@ -74,6 +75,7 b' class StoreMagics(Magics):'
74 if self.autorestore:
75 if self.autorestore:
75 restore_data(self.shell)
76 restore_data(self.shell)
76
77
78 @skip_doctest
77 @line_magic
79 @line_magic
78 def store(self, parameter_s=''):
80 def store(self, parameter_s=''):
79 """Lightweight persistence for python variables.
81 """Lightweight persistence for python variables.
@@ -82,6 +84,7 b' class StoreMagics(Magics):'
82
84
83 In [1]: l = ['hello',10,'world']
85 In [1]: l = ['hello',10,'world']
84 In [2]: %store l
86 In [2]: %store l
87 Stored 'l' (list)
85 In [3]: exit
88 In [3]: exit
86
89
87 (IPython session is closed and started again...)
90 (IPython session is closed and started again...)
@@ -11,6 +11,7 b' import sys'
11 from IPython.core.error import TryNext, UsageError
11 from IPython.core.error import TryNext, UsageError
12 from IPython.core.magic import Magics, magics_class, line_magic
12 from IPython.core.magic import Magics, magics_class, line_magic
13 from IPython.lib.clipboard import ClipboardEmpty
13 from IPython.lib.clipboard import ClipboardEmpty
14 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.utils.text import SList, strip_email_quotes
15 from IPython.utils.text import SList, strip_email_quotes
15 from IPython.utils import py3compat
16 from IPython.utils import py3compat
16
17
@@ -83,6 +84,7 b' class TerminalMagics(Magics):'
83 self.shell.set_autoindent()
84 self.shell.set_autoindent()
84 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
85 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
85
86
87 @skip_doctest
86 @line_magic
88 @line_magic
87 def cpaste(self, parameter_s=''):
89 def cpaste(self, parameter_s=''):
88 """Paste & execute a pre-formatted code block from clipboard.
90 """Paste & execute a pre-formatted code block from clipboard.
General Comments 0
You need to be logged in to leave comments. Login now