##// END OF EJS Templates
Create decorators for standalone magic functions, as per review.x
Fernando Perez -
Show More
@@ -1,387 +1,437 b''
1 1 # encoding: utf-8
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 8 # Copyright (C) 2008 The IPython Development Team
9 9
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 # Stdlib
18 18 import os
19 19 import re
20 20 import sys
21 21 import types
22 22 from getopt import getopt, GetoptError
23 23
24 24 # Our own
25 25 from IPython.config.configurable import Configurable
26 26 from IPython.core import oinspect
27 27 from IPython.core.error import UsageError
28 28 from IPython.core.prefilter import ESC_MAGIC
29 29 from IPython.external.decorator import decorator
30 30 from IPython.utils.ipstruct import Struct
31 31 from IPython.utils.process import arg_split
32 32 from IPython.utils.traitlets import Bool, Dict, Instance
33 33 from IPython.utils.warn import error, warn
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Globals
37 37 #-----------------------------------------------------------------------------
38 38
39 39 # A dict we'll use for each class that has magics, used as temporary storage to
40 40 # pass information between the @line/cell_magic method decorators and the
41 41 # @register_magics class decorator, because the method decorators have no
42 42 # access to the class when they run. See for more details:
43 43 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
44 44
45 45 magics = dict(line={}, cell={})
46 46
47 47 magic_types = ('line', 'cell')
48 48 magic_spec = ('line', 'cell', 'line_cell')
49 49
50 50 #-----------------------------------------------------------------------------
51 51 # Utility classes and functions
52 52 #-----------------------------------------------------------------------------
53 53
54 54 class Bunch: pass
55 55
56 56
57 57 def on_off(tag):
58 58 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
59 59 return ['OFF','ON'][tag]
60 60
61 61
62 62 def compress_dhist(dh):
63 63 head, tail = dh[:-10], dh[-10:]
64 64
65 65 newhead = []
66 66 done = set()
67 67 for h in head:
68 68 if h in done:
69 69 continue
70 70 newhead.append(h)
71 71 done.add(h)
72 72
73 73 return newhead + tail
74 74
75 75
76 76 def needs_local_scope(func):
77 77 """Decorator to mark magic functions which need to local scope to run."""
78 78 func.needs_local_scope = True
79 79 return func
80 80
81 81 #-----------------------------------------------------------------------------
82 82 # Class and method decorators for registering magics
83 83 #-----------------------------------------------------------------------------
84 84
85 85 def register_magics(cls):
86 86 cls.registered = True
87 87 cls.magics = dict(line = magics['line'],
88 88 cell = magics['cell'])
89 89 magics['line'] = {}
90 90 magics['cell'] = {}
91 91 return cls
92 92
93 93
94 94 def record_magic(dct, mtype, mname, func):
95 95 if mtype == 'line_cell':
96 96 dct['line'][mname] = dct['cell'][mname] = func
97 97 else:
98 98 dct[mtype][mname] = func
99 99
100 100
101 101 def validate_type(magic_type):
102 102 if magic_type not in magic_spec:
103 103 raise ValueError('magic_type must be one of %s, %s given' %
104 104 magic_types, magic_type)
105 105
106 106
107 107 def _magic_marker(magic_type):
108 108 validate_type(magic_type)
109 109
110 110 # This is a closure to capture the magic_type. We could also use a class,
111 111 # but it's overkill for just that one bit of state.
112 112 def magic_deco(arg):
113 113 call = lambda f, *a, **k: f(*a, **k)
114 114
115 115 if callable(arg):
116 116 # "Naked" decorator call (just @foo, no args)
117 117 func = arg
118 118 name = func.func_name
119 119 func.magic_name = name
120 120 retval = decorator(call, func)
121 121 record_magic(magics, magic_type, name, name)
122 122 elif isinstance(arg, basestring):
123 123 # Decorator called with arguments (@foo('bar'))
124 124 name = arg
125 125 def mark(func, *a, **kw):
126 126 func.magic_name = name
127 127 record_magic(magics, magic_type, name, func.func_name)
128 128 return decorator(call, func)
129 129 retval = mark
130 130 else:
131 131 raise ValueError("Decorator can only be called with "
132 132 "string or function")
133 return retval
134
135 return magic_deco
136
133 137
138 def _function_magic_marker(magic_type):
139 validate_type(magic_type)
140
141 # This is a closure to capture the magic_type. We could also use a class,
142 # but it's overkill for just that one bit of state.
143 def magic_deco(arg):
144 call = lambda f, *a, **k: f(*a, **k)
145
146 # Find get_ipython() in the caller's namespace
147 caller = sys._getframe(1)
148 for ns in ['f_locals', 'f_globals', 'f_builtins']:
149 get_ipython = getattr(caller, ns).get('get_ipython')
150 if get_ipython is not None:
151 break
152 else:
153 raise('Decorator can only run in context where `get_ipython` exists')
154
155 ip = get_ipython()
156
157 if callable(arg):
158 # "Naked" decorator call (just @foo, no args)
159 func = arg
160 #name = func.func_name
161 #func.magic_name = name
162 ip.register_magic_function(func)
163 retval = decorator(call, func)
164 elif isinstance(arg, basestring):
165 # Decorator called with arguments (@foo('bar'))
166 name = arg
167 def mark(func, *a, **kw):
168 #func.magic_name = name
169 ip.register_magic_function(func)
170 return decorator(call, func)
171 retval = mark
172 else:
173 raise ValueError("Decorator can only be called with "
174 "string or function")
134 175 return retval
135 176
136 177 return magic_deco
137 178
138 179
180 # Create the actual decorators for public use
181
182 # These three are used to decorate methods in class definitions
139 183 line_magic = _magic_marker('line')
140 184 cell_magic = _magic_marker('cell')
141 185 line_cell_magic = _magic_marker('line_cell')
142 186
187 # These three decorate standalone functions and perform the decoration
188 # immediately. They can only run where get_ipython() works
189 register_line_magic = _function_magic_marker('line')
190 register_cell_magic = _function_magic_marker('cell')
191 register_line_cell_magic = _function_magic_marker('line_cell')
192
143 193 #-----------------------------------------------------------------------------
144 194 # Core Magic classes
145 195 #-----------------------------------------------------------------------------
146 196
147 197 class MagicsManager(Configurable):
148 198 """Object that handles all magic-related functionality for IPython.
149 199 """
150 200 # Non-configurable class attributes
151 201
152 202 # A two-level dict, first keyed by magic type, then by magic function, and
153 203 # holding the actual callable object as value. This is the dict used for
154 204 # magic function dispatch
155 205 magics = Dict
156 206
157 207 # A registry of the original objects that we've been given holding magics.
158 208 registry = Dict
159 209
160 210 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
161 211
162 212 auto_magic = Bool
163 213
164 214 _auto_status = [
165 215 'Automagic is OFF, % prefix IS needed for magic functions.',
166 216 'Automagic is ON, % prefix IS NOT needed for magic functions.']
167 217
168 218 user_magics = Instance('IPython.core.magics.UserMagics')
169 219
170 220 def __init__(self, shell=None, config=None, user_magics=None, **traits):
171 221
172 222 super(MagicsManager, self).__init__(shell=shell, config=config,
173 223 user_magics=user_magics, **traits)
174 224 self.magics = dict(line={}, cell={})
175 225 # Let's add the user_magics to the registry for uniformity, so *all*
176 226 # registered magic containers can be found there.
177 227 self.registry[user_magics.__class__.__name__] = user_magics
178 228
179 229 def auto_status(self):
180 230 """Return descriptive string with automagic status."""
181 231 return self._auto_status[self.auto_magic]
182 232
183 233 def lsmagic(self):
184 234 """Return a dict of currently available magic functions.
185 235
186 236 The return dict has the keys 'line' and 'cell', corresponding to the
187 237 two types of magics we support. Each value is a list of names.
188 238 """
189 239 return self.magics
190 240
191 241 def register(self, *magic_objects):
192 242 """Register one or more instances of Magics.
193 243 """
194 244 # Start by validating them to ensure they have all had their magic
195 245 # methods registered at the instance level
196 246 for m in magic_objects:
197 247 if not m.registered:
198 248 raise ValueError("Class of magics %r was constructed without "
199 249 "the @register_macics class decorator")
200 250 if type(m) is type:
201 251 # If we're given an uninstantiated class
202 252 m = m(self.shell)
203 253
204 254 # Now that we have an instance, we can register it and update the
205 255 # table of callables
206 256 self.registry[m.__class__.__name__] = m
207 257 for mtype in magic_types:
208 258 self.magics[mtype].update(m.magics[mtype])
209 259
210 260 def register_function(self, func, magic_type='line', magic_name=None):
211 261 """Expose a standalone function as magic function for ipython.
212 262 """
213 263
214 264 # Create the new method in the user_magics and register it in the
215 265 # global table
216 266 validate_type(magic_type)
217 267 magic_name = func.func_name if magic_name is None else magic_name
218 268 setattr(self.user_magics, magic_name, func)
219 269 record_magic(self.magics, magic_type, magic_name, func)
220 270
221 271 def define_magic(self, name, func):
222 272 """Support for deprecated API.
223 273
224 274 This method exists only to support the old-style definition of magics.
225 275 It will eventually be removed. Deliberately not documented further.
226 276 """
227 277 meth = types.MethodType(func, self.user_magics)
228 278 setattr(self.user_magics, name, meth)
229 279 record_magic(self.magics, 'line', name, meth)
230 280
231 281 # Key base class that provides the central functionality for magics.
232 282
233 283 class Magics(object):
234 284 """Base class for implementing magic functions.
235 285
236 286 Shell functions which can be reached as %function_name. All magic
237 287 functions should accept a string, which they can parse for their own
238 288 needs. This can make some functions easier to type, eg `%cd ../`
239 289 vs. `%cd("../")`
240 290
241 291 Classes providing magic functions need to subclass this class, and they
242 292 MUST:
243 293
244 294 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
245 295 individual methods as magic functions, AND
246 296
247 297 - Use the class decorator `@register_magics` to ensure that the magic
248 298 methods are properly registered at the instance level upon instance
249 299 initialization.
250 300
251 301 See :mod:`magic_functions` for examples of actual implementation classes.
252 302 """
253 303 # Dict holding all command-line options for each magic.
254 304 options_table = None
255 305 # Dict for the mapping of magic names to methods, set by class decorator
256 306 magics = None
257 307 # Flag to check that the class decorator was properly applied
258 308 registered = False
259 309 # Instance of IPython shell
260 310 shell = None
261 311
262 312 def __init__(self, shell):
263 313 if not(self.__class__.registered):
264 314 raise ValueError('Magics subclass without registration - '
265 315 'did you forget to apply @register_magics?')
266 316 self.shell = shell
267 317 self.options_table = {}
268 318 # The method decorators are run when the instance doesn't exist yet, so
269 319 # they can only record the names of the methods they are supposed to
270 320 # grab. Only now, that the instance exists, can we create the proper
271 321 # mapping to bound methods. So we read the info off the original names
272 322 # table and replace each method name by the actual bound method.
273 323 for mtype in magic_types:
274 324 tab = self.magics[mtype]
275 325 # must explicitly use keys, as we're mutating this puppy
276 326 for magic_name in tab.keys():
277 327 meth_name = tab[magic_name]
278 328 if isinstance(meth_name, basestring):
279 329 tab[magic_name] = getattr(self, meth_name)
280 330
281 331 def arg_err(self,func):
282 332 """Print docstring if incorrect arguments were passed"""
283 333 print 'Error in arguments:'
284 334 print oinspect.getdoc(func)
285 335
286 336 def format_latex(self, strng):
287 337 """Format a string for latex inclusion."""
288 338
289 339 # Characters that need to be escaped for latex:
290 340 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
291 341 # Magic command names as headers:
292 342 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
293 343 re.MULTILINE)
294 344 # Magic commands
295 345 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
296 346 re.MULTILINE)
297 347 # Paragraph continue
298 348 par_re = re.compile(r'\\$',re.MULTILINE)
299 349
300 350 # The "\n" symbol
301 351 newline_re = re.compile(r'\\n')
302 352
303 353 # Now build the string for output:
304 354 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
305 355 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
306 356 strng)
307 357 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
308 358 strng = par_re.sub(r'\\\\',strng)
309 359 strng = escape_re.sub(r'\\\1',strng)
310 360 strng = newline_re.sub(r'\\textbackslash{}n',strng)
311 361 return strng
312 362
313 363 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
314 364 """Parse options passed to an argument string.
315 365
316 366 The interface is similar to that of getopt(), but it returns back a
317 367 Struct with the options as keys and the stripped argument string still
318 368 as a string.
319 369
320 370 arg_str is quoted as a true sys.argv vector by using shlex.split.
321 371 This allows us to easily expand variables, glob files, quote
322 372 arguments, etc.
323 373
324 374 Options:
325 375 -mode: default 'string'. If given as 'list', the argument string is
326 376 returned as a list (split on whitespace) instead of a string.
327 377
328 378 -list_all: put all option values in lists. Normally only options
329 379 appearing more than once are put in a list.
330 380
331 381 -posix (True): whether to split the input line in POSIX mode or not,
332 382 as per the conventions outlined in the shlex module from the
333 383 standard library."""
334 384
335 385 # inject default options at the beginning of the input line
336 386 caller = sys._getframe(1).f_code.co_name
337 387 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
338 388
339 389 mode = kw.get('mode','string')
340 390 if mode not in ['string','list']:
341 391 raise ValueError,'incorrect mode given: %s' % mode
342 392 # Get options
343 393 list_all = kw.get('list_all',0)
344 394 posix = kw.get('posix', os.name == 'posix')
345 395 strict = kw.get('strict', True)
346 396
347 397 # Check if we have more than one argument to warrant extra processing:
348 398 odict = {} # Dictionary with options
349 399 args = arg_str.split()
350 400 if len(args) >= 1:
351 401 # If the list of inputs only has 0 or 1 thing in it, there's no
352 402 # need to look for options
353 403 argv = arg_split(arg_str, posix, strict)
354 404 # Do regular option processing
355 405 try:
356 406 opts,args = getopt(argv,opt_str,*long_opts)
357 407 except GetoptError,e:
358 408 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
359 409 " ".join(long_opts)))
360 410 for o,a in opts:
361 411 if o.startswith('--'):
362 412 o = o[2:]
363 413 else:
364 414 o = o[1:]
365 415 try:
366 416 odict[o].append(a)
367 417 except AttributeError:
368 418 odict[o] = [odict[o],a]
369 419 except KeyError:
370 420 if list_all:
371 421 odict[o] = [a]
372 422 else:
373 423 odict[o] = a
374 424
375 425 # Prepare opts,args for return
376 426 opts = Struct(odict)
377 427 if mode == 'string':
378 428 args = ' '.join(args)
379 429
380 430 return opts,args
381 431
382 432 def default_option(self, fn, optstr):
383 433 """Make an entry in the options_table for fn, with value optstr"""
384 434
385 435 if fn not in self.lsmagic():
386 436 error("%s is not a magic function" % fn)
387 437 self.options_table[fn] = optstr
@@ -1,40 +1,40 b''
1 1 """Implementation of all the magic functions built into IPython.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012, IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 from ..magic import Magics, register_magics
16 16 from .auto import AutoMagics
17 17 from .basic import BasicMagics
18 18 from .code import CodeMagics, MacroToEdit
19 19 from .config import ConfigMagics
20 20 from .deprecated import DeprecatedMagics
21 21 from .execution import ExecutionMagics
22 22 from .extension import ExtensionMagics
23 23 from .history import HistoryMagics
24 24 from .logging import LoggingMagics
25 25 from .namespace import NamespaceMagics
26 26 from .osm import OSMagics
27 27 from .pylab import PylabMagics
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Magic implementation classes
31 31 #-----------------------------------------------------------------------------
32 32
33 33 @register_magics
34 34 class UserMagics(Magics):
35 35 """Placeholder for user-defined magics to be added at runtime.
36 36
37 37 All magics are eventually merged into a single namespace at runtime, but we
38 38 use this class to isolate the magics defined dynamically by the user into
39 39 their own class.
40 40 """
General Comments 0
You need to be logged in to leave comments. Login now