##// END OF EJS Templates
test Magic.parse_options with long options
MinRK -
Show More
@@ -1,575 +1,575 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.text import dedent
33 33 from IPython.utils.traitlets import Bool, Dict, Instance
34 34 from IPython.utils.warn import error, warn
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Globals
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # A dict we'll use for each class that has magics, used as temporary storage to
41 41 # pass information between the @line/cell_magic method decorators and the
42 42 # @magics_class class decorator, because the method decorators have no
43 43 # access to the class when they run. See for more details:
44 44 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
45 45
46 46 magics = dict(line={}, cell={})
47 47
48 48 magic_kinds = ('line', 'cell')
49 49 magic_spec = ('line', 'cell', 'line_cell')
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Utility classes and functions
53 53 #-----------------------------------------------------------------------------
54 54
55 55 class Bunch: pass
56 56
57 57
58 58 def on_off(tag):
59 59 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
60 60 return ['OFF','ON'][tag]
61 61
62 62
63 63 def compress_dhist(dh):
64 64 """Compress a directory history into a new one with at most 20 entries.
65 65
66 66 Return a new list made from the first and last 10 elements of dhist after
67 67 removal of duplicates.
68 68 """
69 69 head, tail = dh[:-10], dh[-10:]
70 70
71 71 newhead = []
72 72 done = set()
73 73 for h in head:
74 74 if h in done:
75 75 continue
76 76 newhead.append(h)
77 77 done.add(h)
78 78
79 79 return newhead + tail
80 80
81 81
82 82 def needs_local_scope(func):
83 83 """Decorator to mark magic functions which need to local scope to run."""
84 84 func.needs_local_scope = True
85 85 return func
86 86
87 87 #-----------------------------------------------------------------------------
88 88 # Class and method decorators for registering magics
89 89 #-----------------------------------------------------------------------------
90 90
91 91 def magics_class(cls):
92 92 """Class decorator for all subclasses of the main Magics class.
93 93
94 94 Any class that subclasses Magics *must* also apply this decorator, to
95 95 ensure that all the methods that have been decorated as line/cell magics
96 96 get correctly registered in the class instance. This is necessary because
97 97 when method decorators run, the class does not exist yet, so they
98 98 temporarily store their information into a module global. Application of
99 99 this class decorator copies that global data to the class instance and
100 100 clears the global.
101 101
102 102 Obviously, this mechanism is not thread-safe, which means that the
103 103 *creation* of subclasses of Magic should only be done in a single-thread
104 104 context. Instantiation of the classes has no restrictions. Given that
105 105 these classes are typically created at IPython startup time and before user
106 106 application code becomes active, in practice this should not pose any
107 107 problems.
108 108 """
109 109 cls.registered = True
110 110 cls.magics = dict(line = magics['line'],
111 111 cell = magics['cell'])
112 112 magics['line'] = {}
113 113 magics['cell'] = {}
114 114 return cls
115 115
116 116
117 117 def record_magic(dct, magic_kind, magic_name, func):
118 118 """Utility function to store a function as a magic of a specific kind.
119 119
120 120 Parameters
121 121 ----------
122 122 dct : dict
123 123 A dictionary with 'line' and 'cell' subdicts.
124 124
125 125 magic_kind : str
126 126 Kind of magic to be stored.
127 127
128 128 magic_name : str
129 129 Key to store the magic as.
130 130
131 131 func : function
132 132 Callable object to store.
133 133 """
134 134 if magic_kind == 'line_cell':
135 135 dct['line'][magic_name] = dct['cell'][magic_name] = func
136 136 else:
137 137 dct[magic_kind][magic_name] = func
138 138
139 139
140 140 def validate_type(magic_kind):
141 141 """Ensure that the given magic_kind is valid.
142 142
143 143 Check that the given magic_kind is one of the accepted spec types (stored
144 144 in the global `magic_spec`), raise ValueError otherwise.
145 145 """
146 146 if magic_kind not in magic_spec:
147 147 raise ValueError('magic_kind must be one of %s, %s given' %
148 148 magic_kinds, magic_kind)
149 149
150 150
151 151 # The docstrings for the decorator below will be fairly similar for the two
152 152 # types (method and function), so we generate them here once and reuse the
153 153 # templates below.
154 154 _docstring_template = \
155 155 """Decorate the given {0} as {1} magic.
156 156
157 157 The decorator can be used with or without arguments, as follows.
158 158
159 159 i) without arguments: it will create a {1} magic named as the {0} being
160 160 decorated::
161 161
162 162 @deco
163 163 def foo(...)
164 164
165 165 will create a {1} magic named `foo`.
166 166
167 167 ii) with one string argument: which will be used as the actual name of the
168 168 resulting magic::
169 169
170 170 @deco('bar')
171 171 def foo(...)
172 172
173 173 will create a {1} magic named `bar`.
174 174 """
175 175
176 176 # These two are decorator factories. While they are conceptually very similar,
177 177 # there are enough differences in the details that it's simpler to have them
178 178 # written as completely standalone functions rather than trying to share code
179 179 # and make a single one with convoluted logic.
180 180
181 181 def _method_magic_marker(magic_kind):
182 182 """Decorator factory for methods in Magics subclasses.
183 183 """
184 184
185 185 validate_type(magic_kind)
186 186
187 187 # This is a closure to capture the magic_kind. We could also use a class,
188 188 # but it's overkill for just that one bit of state.
189 189 def magic_deco(arg):
190 190 call = lambda f, *a, **k: f(*a, **k)
191 191
192 192 if callable(arg):
193 193 # "Naked" decorator call (just @foo, no args)
194 194 func = arg
195 195 name = func.func_name
196 196 retval = decorator(call, func)
197 197 record_magic(magics, magic_kind, name, name)
198 198 elif isinstance(arg, basestring):
199 199 # Decorator called with arguments (@foo('bar'))
200 200 name = arg
201 201 def mark(func, *a, **kw):
202 202 record_magic(magics, magic_kind, name, func.func_name)
203 203 return decorator(call, func)
204 204 retval = mark
205 205 else:
206 206 raise ValueError("Decorator can only be called with "
207 207 "string or function")
208 208 return retval
209 209
210 210 # Ensure the resulting decorator has a usable docstring
211 211 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
212 212 return magic_deco
213 213
214 214
215 215 def _function_magic_marker(magic_kind):
216 216 """Decorator factory for standalone functions.
217 217 """
218 218 validate_type(magic_kind)
219 219
220 220 # This is a closure to capture the magic_kind. We could also use a class,
221 221 # but it's overkill for just that one bit of state.
222 222 def magic_deco(arg):
223 223 call = lambda f, *a, **k: f(*a, **k)
224 224
225 225 # Find get_ipython() in the caller's namespace
226 226 caller = sys._getframe(1)
227 227 for ns in ['f_locals', 'f_globals', 'f_builtins']:
228 228 get_ipython = getattr(caller, ns).get('get_ipython')
229 229 if get_ipython is not None:
230 230 break
231 231 else:
232 232 raise('Decorator can only run in context where `get_ipython` exists')
233 233
234 234 ip = get_ipython()
235 235
236 236 if callable(arg):
237 237 # "Naked" decorator call (just @foo, no args)
238 238 func = arg
239 239 name = func.func_name
240 240 ip.register_magic_function(func, magic_kind, name)
241 241 retval = decorator(call, func)
242 242 elif isinstance(arg, basestring):
243 243 # Decorator called with arguments (@foo('bar'))
244 244 name = arg
245 245 def mark(func, *a, **kw):
246 246 ip.register_magic_function(func, magic_kind, name)
247 247 return decorator(call, func)
248 248 retval = mark
249 249 else:
250 250 raise ValueError("Decorator can only be called with "
251 251 "string or function")
252 252 return retval
253 253
254 254 # Ensure the resulting decorator has a usable docstring
255 255 ds = _docstring_template.format('function', magic_kind)
256 256
257 257 ds += dedent("""
258 258 Note: this decorator can only be used in a context where IPython is already
259 259 active, so that the `get_ipython()` call succeeds. You can therefore use
260 260 it in your startup files loaded after IPython initializes, but *not* in the
261 261 IPython configuration file itself, which is executed before IPython is
262 262 fully up and running. Any file located in the `startup` subdirectory of
263 263 your configuration profile will be OK in this sense.
264 264 """)
265 265
266 266 magic_deco.__doc__ = ds
267 267 return magic_deco
268 268
269 269
270 270 # Create the actual decorators for public use
271 271
272 272 # These three are used to decorate methods in class definitions
273 273 line_magic = _method_magic_marker('line')
274 274 cell_magic = _method_magic_marker('cell')
275 275 line_cell_magic = _method_magic_marker('line_cell')
276 276
277 277 # These three decorate standalone functions and perform the decoration
278 278 # immediately. They can only run where get_ipython() works
279 279 register_line_magic = _function_magic_marker('line')
280 280 register_cell_magic = _function_magic_marker('cell')
281 281 register_line_cell_magic = _function_magic_marker('line_cell')
282 282
283 283 #-----------------------------------------------------------------------------
284 284 # Core Magic classes
285 285 #-----------------------------------------------------------------------------
286 286
287 287 class MagicsManager(Configurable):
288 288 """Object that handles all magic-related functionality for IPython.
289 289 """
290 290 # Non-configurable class attributes
291 291
292 292 # A two-level dict, first keyed by magic type, then by magic function, and
293 293 # holding the actual callable object as value. This is the dict used for
294 294 # magic function dispatch
295 295 magics = Dict
296 296
297 297 # A registry of the original objects that we've been given holding magics.
298 298 registry = Dict
299 299
300 300 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
301 301
302 302 auto_magic = Bool(True, config=True, help=
303 303 "Automatically call line magics without requiring explicit % prefix")
304 304
305 305 _auto_status = [
306 306 'Automagic is OFF, % prefix IS needed for line magics.',
307 307 'Automagic is ON, % prefix IS NOT needed for line magics.']
308 308
309 309 user_magics = Instance('IPython.core.magics.UserMagics')
310 310
311 311 def __init__(self, shell=None, config=None, user_magics=None, **traits):
312 312
313 313 super(MagicsManager, self).__init__(shell=shell, config=config,
314 314 user_magics=user_magics, **traits)
315 315 self.magics = dict(line={}, cell={})
316 316 # Let's add the user_magics to the registry for uniformity, so *all*
317 317 # registered magic containers can be found there.
318 318 self.registry[user_magics.__class__.__name__] = user_magics
319 319
320 320 def auto_status(self):
321 321 """Return descriptive string with automagic status."""
322 322 return self._auto_status[self.auto_magic]
323 323
324 324 def lsmagic(self):
325 325 """Return a dict of currently available magic functions.
326 326
327 327 The return dict has the keys 'line' and 'cell', corresponding to the
328 328 two types of magics we support. Each value is a list of names.
329 329 """
330 330 return self.magics
331 331
332 332 def register(self, *magic_objects):
333 333 """Register one or more instances of Magics.
334 334
335 335 Take one or more classes or instances of classes that subclass the main
336 336 `core.Magic` class, and register them with IPython to use the magic
337 337 functions they provide. The registration process will then ensure that
338 338 any methods that have decorated to provide line and/or cell magics will
339 339 be recognized with the `%x`/`%%x` syntax as a line/cell magic
340 340 respectively.
341 341
342 342 If classes are given, they will be instantiated with the default
343 343 constructor. If your classes need a custom constructor, you should
344 344 instanitate them first and pass the instance.
345 345
346 346 The provided arguments can be an arbitrary mix of classes and instances.
347 347
348 348 Parameters
349 349 ----------
350 350 magic_objects : one or more classes or instances
351 351 """
352 352 # Start by validating them to ensure they have all had their magic
353 353 # methods registered at the instance level
354 354 for m in magic_objects:
355 355 if not m.registered:
356 356 raise ValueError("Class of magics %r was constructed without "
357 357 "the @register_macics class decorator")
358 358 if type(m) is type:
359 359 # If we're given an uninstantiated class
360 360 m = m(self.shell)
361 361
362 362 # Now that we have an instance, we can register it and update the
363 363 # table of callables
364 364 self.registry[m.__class__.__name__] = m
365 365 for mtype in magic_kinds:
366 366 self.magics[mtype].update(m.magics[mtype])
367 367
368 368 def register_function(self, func, magic_kind='line', magic_name=None):
369 369 """Expose a standalone function as magic function for IPython.
370 370
371 371 This will create an IPython magic (line, cell or both) from a
372 372 standalone function. The functions should have the following
373 373 signatures:
374 374
375 375 * For line magics: `def f(line)`
376 376 * For cell magics: `def f(line, cell)`
377 377 * For a function that does both: `def f(line, cell=None)`
378 378
379 379 In the latter case, the function will be called with `cell==None` when
380 380 invoked as `%f`, and with cell as a string when invoked as `%%f`.
381 381
382 382 Parameters
383 383 ----------
384 384 func : callable
385 385 Function to be registered as a magic.
386 386
387 387 magic_kind : str
388 388 Kind of magic, one of 'line', 'cell' or 'line_cell'
389 389
390 390 magic_name : optional str
391 391 If given, the name the magic will have in the IPython namespace. By
392 392 default, the name of the function itself is used.
393 393 """
394 394
395 395 # Create the new method in the user_magics and register it in the
396 396 # global table
397 397 validate_type(magic_kind)
398 398 magic_name = func.func_name if magic_name is None else magic_name
399 399 setattr(self.user_magics, magic_name, func)
400 400 record_magic(self.magics, magic_kind, magic_name, func)
401 401
402 402 def define_magic(self, name, func):
403 403 """[Deprecated] Expose own function as magic function for IPython.
404 404
405 405 Example::
406 406
407 407 def foo_impl(self, parameter_s=''):
408 408 'My very own magic!. (Use docstrings, IPython reads them).'
409 409 print 'Magic function. Passed parameter is between < >:'
410 410 print '<%s>' % parameter_s
411 411 print 'The self object is:', self
412 412
413 413 ip.define_magic('foo',foo_impl)
414 414 """
415 415 meth = types.MethodType(func, self.user_magics)
416 416 setattr(self.user_magics, name, meth)
417 417 record_magic(self.magics, 'line', name, meth)
418 418
419 419 # Key base class that provides the central functionality for magics.
420 420
421 421 class Magics(object):
422 422 """Base class for implementing magic functions.
423 423
424 424 Shell functions which can be reached as %function_name. All magic
425 425 functions should accept a string, which they can parse for their own
426 426 needs. This can make some functions easier to type, eg `%cd ../`
427 427 vs. `%cd("../")`
428 428
429 429 Classes providing magic functions need to subclass this class, and they
430 430 MUST:
431 431
432 432 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
433 433 individual methods as magic functions, AND
434 434
435 435 - Use the class decorator `@magics_class` to ensure that the magic
436 436 methods are properly registered at the instance level upon instance
437 437 initialization.
438 438
439 439 See :mod:`magic_functions` for examples of actual implementation classes.
440 440 """
441 441 # Dict holding all command-line options for each magic.
442 442 options_table = None
443 443 # Dict for the mapping of magic names to methods, set by class decorator
444 444 magics = None
445 445 # Flag to check that the class decorator was properly applied
446 446 registered = False
447 447 # Instance of IPython shell
448 448 shell = None
449 449
450 450 def __init__(self, shell):
451 451 if not(self.__class__.registered):
452 452 raise ValueError('Magics subclass without registration - '
453 453 'did you forget to apply @magics_class?')
454 454 self.shell = shell
455 455 self.options_table = {}
456 456 # The method decorators are run when the instance doesn't exist yet, so
457 457 # they can only record the names of the methods they are supposed to
458 458 # grab. Only now, that the instance exists, can we create the proper
459 459 # mapping to bound methods. So we read the info off the original names
460 460 # table and replace each method name by the actual bound method.
461 461 for mtype in magic_kinds:
462 462 tab = self.magics[mtype]
463 463 # must explicitly use keys, as we're mutating this puppy
464 464 for magic_name in tab.keys():
465 465 meth_name = tab[magic_name]
466 466 if isinstance(meth_name, basestring):
467 467 tab[magic_name] = getattr(self, meth_name)
468 468
469 469 def arg_err(self,func):
470 470 """Print docstring if incorrect arguments were passed"""
471 471 print 'Error in arguments:'
472 472 print oinspect.getdoc(func)
473 473
474 474 def format_latex(self, strng):
475 475 """Format a string for latex inclusion."""
476 476
477 477 # Characters that need to be escaped for latex:
478 478 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
479 479 # Magic command names as headers:
480 480 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
481 481 re.MULTILINE)
482 482 # Magic commands
483 483 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
484 484 re.MULTILINE)
485 485 # Paragraph continue
486 486 par_re = re.compile(r'\\$',re.MULTILINE)
487 487
488 488 # The "\n" symbol
489 489 newline_re = re.compile(r'\\n')
490 490
491 491 # Now build the string for output:
492 492 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
493 493 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
494 494 strng)
495 495 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
496 496 strng = par_re.sub(r'\\\\',strng)
497 497 strng = escape_re.sub(r'\\\1',strng)
498 498 strng = newline_re.sub(r'\\textbackslash{}n',strng)
499 499 return strng
500 500
501 501 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
502 502 """Parse options passed to an argument string.
503 503
504 504 The interface is similar to that of getopt(), but it returns back a
505 505 Struct with the options as keys and the stripped argument string still
506 506 as a string.
507 507
508 508 arg_str is quoted as a true sys.argv vector by using shlex.split.
509 509 This allows us to easily expand variables, glob files, quote
510 510 arguments, etc.
511 511
512 512 Options:
513 513 -mode: default 'string'. If given as 'list', the argument string is
514 514 returned as a list (split on whitespace) instead of a string.
515 515
516 516 -list_all: put all option values in lists. Normally only options
517 517 appearing more than once are put in a list.
518 518
519 519 -posix (True): whether to split the input line in POSIX mode or not,
520 520 as per the conventions outlined in the shlex module from the
521 521 standard library."""
522 522
523 523 # inject default options at the beginning of the input line
524 524 caller = sys._getframe(1).f_code.co_name
525 525 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
526 526
527 527 mode = kw.get('mode','string')
528 528 if mode not in ['string','list']:
529 529 raise ValueError,'incorrect mode given: %s' % mode
530 530 # Get options
531 531 list_all = kw.get('list_all',0)
532 532 posix = kw.get('posix', os.name == 'posix')
533 533 strict = kw.get('strict', True)
534 534
535 535 # Check if we have more than one argument to warrant extra processing:
536 536 odict = {} # Dictionary with options
537 537 args = arg_str.split()
538 538 if len(args) >= 1:
539 539 # If the list of inputs only has 0 or 1 thing in it, there's no
540 540 # need to look for options
541 541 argv = arg_split(arg_str, posix, strict)
542 542 # Do regular option processing
543 543 try:
544 opts,args = getopt(argv,opt_str,*long_opts)
544 opts,args = getopt(argv, opt_str, long_opts)
545 545 except GetoptError,e:
546 546 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
547 547 " ".join(long_opts)))
548 548 for o,a in opts:
549 549 if o.startswith('--'):
550 550 o = o[2:]
551 551 else:
552 552 o = o[1:]
553 553 try:
554 554 odict[o].append(a)
555 555 except AttributeError:
556 556 odict[o] = [odict[o],a]
557 557 except KeyError:
558 558 if list_all:
559 559 odict[o] = [a]
560 560 else:
561 561 odict[o] = a
562 562
563 563 # Prepare opts,args for return
564 564 opts = Struct(odict)
565 565 if mode == 'string':
566 566 args = ' '.join(args)
567 567
568 568 return opts,args
569 569
570 570 def default_option(self, fn, optstr):
571 571 """Make an entry in the options_table for fn, with value optstr"""
572 572
573 573 if fn not in self.lsmagic():
574 574 error("%s is not a magic function" % fn)
575 575 self.options_table[fn] = optstr
@@ -1,547 +1,556 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6 from __future__ import absolute_import
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11
12 12 import io
13 13 import os
14 14 import sys
15 15 from StringIO import StringIO
16 16 from unittest import TestCase
17 17
18 18 import nose.tools as nt
19 19
20 20 from IPython.core import magic
21 21 from IPython.core.magic import (Magics, magics_class, line_magic,
22 22 cell_magic, line_cell_magic,
23 23 register_line_magic, register_cell_magic,
24 24 register_line_cell_magic)
25 25 from IPython.core.magics import execution
26 26 from IPython.nbformat.v3.tests.nbexamples import nb0
27 27 from IPython.nbformat import current
28 28 from IPython.testing import decorators as dec
29 29 from IPython.testing import tools as tt
30 30 from IPython.utils import py3compat
31 31 from IPython.utils.tempdir import TemporaryDirectory
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Test functions begin
35 35 #-----------------------------------------------------------------------------
36 36
37 37 @magic.magics_class
38 38 class DummyMagics(magic.Magics): pass
39 39
40 40 def test_rehashx():
41 41 # clear up everything
42 42 _ip = get_ipython()
43 43 _ip.alias_manager.alias_table.clear()
44 44 del _ip.db['syscmdlist']
45 45
46 46 _ip.magic('rehashx')
47 47 # Practically ALL ipython development systems will have more than 10 aliases
48 48
49 49 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
50 50 for key, val in _ip.alias_manager.alias_table.iteritems():
51 51 # we must strip dots from alias names
52 52 nt.assert_true('.' not in key)
53 53
54 54 # rehashx must fill up syscmdlist
55 55 scoms = _ip.db['syscmdlist']
56 56 yield (nt.assert_true, len(scoms) > 10)
57 57
58 58
59 59 def test_magic_parse_options():
60 60 """Test that we don't mangle paths when parsing magic options."""
61 61 ip = get_ipython()
62 62 path = 'c:\\x'
63 63 m = DummyMagics(ip)
64 64 opts = m.parse_options('-f %s' % path,'f:')[0]
65 65 # argv splitting is os-dependent
66 66 if os.name == 'posix':
67 67 expected = 'c:x'
68 68 else:
69 69 expected = path
70 70 nt.assert_equals(opts['f'], expected)
71 71
72 def test_magic_parse_long_options():
73 """Magic.parse_options can handle --foo=bar long options"""
74 ip = get_ipython()
75 m = DummyMagics(ip)
76 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
77 nt.assert_true('foo' in opts)
78 nt.assert_true('bar' in opts)
79 nt.assert_true(opts['bar'], "bubble")
80
72 81
73 82 @dec.skip_without('sqlite3')
74 83 def doctest_hist_f():
75 84 """Test %hist -f with temporary filename.
76 85
77 86 In [9]: import tempfile
78 87
79 88 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
80 89
81 90 In [11]: %hist -nl -f $tfile 3
82 91
83 92 In [13]: import os; os.unlink(tfile)
84 93 """
85 94
86 95
87 96 @dec.skip_without('sqlite3')
88 97 def doctest_hist_r():
89 98 """Test %hist -r
90 99
91 100 XXX - This test is not recording the output correctly. For some reason, in
92 101 testing mode the raw history isn't getting populated. No idea why.
93 102 Disabling the output checking for now, though at least we do run it.
94 103
95 104 In [1]: 'hist' in _ip.lsmagic()
96 105 Out[1]: True
97 106
98 107 In [2]: x=1
99 108
100 109 In [3]: %hist -rl 2
101 110 x=1 # random
102 111 %hist -r 2
103 112 """
104 113
105 114
106 115 @dec.skip_without('sqlite3')
107 116 def doctest_hist_op():
108 117 """Test %hist -op
109 118
110 119 In [1]: class b(float):
111 120 ...: pass
112 121 ...:
113 122
114 123 In [2]: class s(object):
115 124 ...: def __str__(self):
116 125 ...: return 's'
117 126 ...:
118 127
119 128 In [3]:
120 129
121 130 In [4]: class r(b):
122 131 ...: def __repr__(self):
123 132 ...: return 'r'
124 133 ...:
125 134
126 135 In [5]: class sr(s,r): pass
127 136 ...:
128 137
129 138 In [6]:
130 139
131 140 In [7]: bb=b()
132 141
133 142 In [8]: ss=s()
134 143
135 144 In [9]: rr=r()
136 145
137 146 In [10]: ssrr=sr()
138 147
139 148 In [11]: 4.5
140 149 Out[11]: 4.5
141 150
142 151 In [12]: str(ss)
143 152 Out[12]: 's'
144 153
145 154 In [13]:
146 155
147 156 In [14]: %hist -op
148 157 >>> class b:
149 158 ... pass
150 159 ...
151 160 >>> class s(b):
152 161 ... def __str__(self):
153 162 ... return 's'
154 163 ...
155 164 >>>
156 165 >>> class r(b):
157 166 ... def __repr__(self):
158 167 ... return 'r'
159 168 ...
160 169 >>> class sr(s,r): pass
161 170 >>>
162 171 >>> bb=b()
163 172 >>> ss=s()
164 173 >>> rr=r()
165 174 >>> ssrr=sr()
166 175 >>> 4.5
167 176 4.5
168 177 >>> str(ss)
169 178 's'
170 179 >>>
171 180 """
172 181
173 182
174 183 @dec.skip_without('sqlite3')
175 184 def test_macro():
176 185 ip = get_ipython()
177 186 ip.history_manager.reset() # Clear any existing history.
178 187 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
179 188 for i, cmd in enumerate(cmds, start=1):
180 189 ip.history_manager.store_inputs(i, cmd)
181 190 ip.magic("macro test 1-3")
182 191 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
183 192
184 193 # List macros.
185 194 assert "test" in ip.magic("macro")
186 195
187 196
188 197 @dec.skip_without('sqlite3')
189 198 def test_macro_run():
190 199 """Test that we can run a multi-line macro successfully."""
191 200 ip = get_ipython()
192 201 ip.history_manager.reset()
193 202 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
194 203 "%macro test 2-3"]
195 204 for cmd in cmds:
196 205 ip.run_cell(cmd, store_history=True)
197 206 nt.assert_equal(ip.user_ns["test"].value,
198 207 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
199 208 with tt.AssertPrints("12"):
200 209 ip.run_cell("test")
201 210 with tt.AssertPrints("13"):
202 211 ip.run_cell("test")
203 212
204 213
205 214 @dec.skipif_not_numpy
206 215 def test_numpy_reset_array_undec():
207 216 "Test '%reset array' functionality"
208 217 _ip.ex('import numpy as np')
209 218 _ip.ex('a = np.empty(2)')
210 219 yield (nt.assert_true, 'a' in _ip.user_ns)
211 220 _ip.magic('reset -f array')
212 221 yield (nt.assert_false, 'a' in _ip.user_ns)
213 222
214 223 def test_reset_out():
215 224 "Test '%reset out' magic"
216 225 _ip.run_cell("parrot = 'dead'", store_history=True)
217 226 # test '%reset -f out', make an Out prompt
218 227 _ip.run_cell("parrot", store_history=True)
219 228 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
220 229 _ip.magic('reset -f out')
221 230 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
222 231 nt.assert_true(len(_ip.user_ns['Out']) == 0)
223 232
224 233 def test_reset_in():
225 234 "Test '%reset in' magic"
226 235 # test '%reset -f in'
227 236 _ip.run_cell("parrot", store_history=True)
228 237 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
229 238 _ip.magic('%reset -f in')
230 239 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
231 240 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
232 241
233 242 def test_reset_dhist():
234 243 "Test '%reset dhist' magic"
235 244 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
236 245 _ip.magic('cd ' + os.path.dirname(nt.__file__))
237 246 _ip.magic('cd -')
238 247 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
239 248 _ip.magic('reset -f dhist')
240 249 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
241 250 _ip.run_cell("_dh = [d for d in tmp]") #restore
242 251
243 252 def test_reset_in_length():
244 253 "Test that '%reset in' preserves In[] length"
245 254 _ip.run_cell("print 'foo'")
246 255 _ip.run_cell("reset -f in")
247 256 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
248 257
249 258 def test_time():
250 259 _ip.magic('time None')
251 260
252 261 def test_tb_syntaxerror():
253 262 """test %tb after a SyntaxError"""
254 263 ip = get_ipython()
255 264 ip.run_cell("for")
256 265
257 266 # trap and validate stdout
258 267 save_stdout = sys.stdout
259 268 try:
260 269 sys.stdout = StringIO()
261 270 ip.run_cell("%tb")
262 271 out = sys.stdout.getvalue()
263 272 finally:
264 273 sys.stdout = save_stdout
265 274 # trim output, and only check the last line
266 275 last_line = out.rstrip().splitlines()[-1].strip()
267 276 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
268 277
269 278
270 279 @py3compat.doctest_refactor_print
271 280 def doctest_time():
272 281 """
273 282 In [10]: %time None
274 283 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
275 284 Wall time: 0.00 s
276 285
277 286 In [11]: def f(kmjy):
278 287 ....: %time print 2*kmjy
279 288
280 289 In [12]: f(3)
281 290 6
282 291 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
283 292 Wall time: 0.00 s
284 293 """
285 294
286 295
287 296 def test_doctest_mode():
288 297 "Toggle doctest_mode twice, it should be a no-op and run without error"
289 298 _ip.magic('doctest_mode')
290 299 _ip.magic('doctest_mode')
291 300
292 301
293 302 def test_parse_options():
294 303 """Tests for basic options parsing in magics."""
295 304 # These are only the most minimal of tests, more should be added later. At
296 305 # the very least we check that basic text/unicode calls work OK.
297 306 m = DummyMagics(_ip)
298 307 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
299 308 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
300 309
301 310
302 311 def test_dirops():
303 312 """Test various directory handling operations."""
304 313 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
305 314 curpath = os.getcwdu
306 315 startdir = os.getcwdu()
307 316 ipdir = os.path.realpath(_ip.ipython_dir)
308 317 try:
309 318 _ip.magic('cd "%s"' % ipdir)
310 319 nt.assert_equal(curpath(), ipdir)
311 320 _ip.magic('cd -')
312 321 nt.assert_equal(curpath(), startdir)
313 322 _ip.magic('pushd "%s"' % ipdir)
314 323 nt.assert_equal(curpath(), ipdir)
315 324 _ip.magic('popd')
316 325 nt.assert_equal(curpath(), startdir)
317 326 finally:
318 327 os.chdir(startdir)
319 328
320 329
321 330 def test_xmode():
322 331 # Calling xmode three times should be a no-op
323 332 xmode = _ip.InteractiveTB.mode
324 333 for i in range(3):
325 334 _ip.magic("xmode")
326 335 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
327 336
328 337 def test_reset_hard():
329 338 monitor = []
330 339 class A(object):
331 340 def __del__(self):
332 341 monitor.append(1)
333 342 def __repr__(self):
334 343 return "<A instance>"
335 344
336 345 _ip.user_ns["a"] = A()
337 346 _ip.run_cell("a")
338 347
339 348 nt.assert_equal(monitor, [])
340 349 _ip.magic("reset -f")
341 350 nt.assert_equal(monitor, [1])
342 351
343 352 class TestXdel(tt.TempFileMixin):
344 353 def test_xdel(self):
345 354 """Test that references from %run are cleared by xdel."""
346 355 src = ("class A(object):\n"
347 356 " monitor = []\n"
348 357 " def __del__(self):\n"
349 358 " self.monitor.append(1)\n"
350 359 "a = A()\n")
351 360 self.mktmp(src)
352 361 # %run creates some hidden references...
353 362 _ip.magic("run %s" % self.fname)
354 363 # ... as does the displayhook.
355 364 _ip.run_cell("a")
356 365
357 366 monitor = _ip.user_ns["A"].monitor
358 367 nt.assert_equal(monitor, [])
359 368
360 369 _ip.magic("xdel a")
361 370
362 371 # Check that a's __del__ method has been called.
363 372 nt.assert_equal(monitor, [1])
364 373
365 374 def doctest_who():
366 375 """doctest for %who
367 376
368 377 In [1]: %reset -f
369 378
370 379 In [2]: alpha = 123
371 380
372 381 In [3]: beta = 'beta'
373 382
374 383 In [4]: %who int
375 384 alpha
376 385
377 386 In [5]: %who str
378 387 beta
379 388
380 389 In [6]: %whos
381 390 Variable Type Data/Info
382 391 ----------------------------
383 392 alpha int 123
384 393 beta str beta
385 394
386 395 In [7]: %who_ls
387 396 Out[7]: ['alpha', 'beta']
388 397 """
389 398
390 399 def test_whos():
391 400 """Check that whos is protected against objects where repr() fails."""
392 401 class A(object):
393 402 def __repr__(self):
394 403 raise Exception()
395 404 _ip.user_ns['a'] = A()
396 405 _ip.magic("whos")
397 406
398 407 @py3compat.u_format
399 408 def doctest_precision():
400 409 """doctest for %precision
401 410
402 411 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
403 412
404 413 In [2]: %precision 5
405 414 Out[2]: {u}'%.5f'
406 415
407 416 In [3]: f.float_format
408 417 Out[3]: {u}'%.5f'
409 418
410 419 In [4]: %precision %e
411 420 Out[4]: {u}'%e'
412 421
413 422 In [5]: f(3.1415927)
414 423 Out[5]: {u}'3.141593e+00'
415 424 """
416 425
417 426 def test_psearch():
418 427 with tt.AssertPrints("dict.fromkeys"):
419 428 _ip.run_cell("dict.fr*?")
420 429
421 430 def test_timeit_shlex():
422 431 """test shlex issues with timeit (#1109)"""
423 432 _ip.ex("def f(*a,**kw): pass")
424 433 _ip.magic('timeit -n1 "this is a bug".count(" ")')
425 434 _ip.magic('timeit -r1 -n1 f(" ", 1)')
426 435 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
427 436 _ip.magic('timeit -r1 -n1 ("a " + "b")')
428 437 _ip.magic('timeit -r1 -n1 f("a " + "b")')
429 438 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
430 439
431 440
432 441 def test_timeit_arguments():
433 442 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
434 443 _ip.magic("timeit ('#')")
435 444
436 445
437 446 @dec.skipif(execution.profile is None)
438 447 def test_prun_quotes():
439 448 "Test that prun does not clobber string escapes (GH #1302)"
440 449 _ip.magic("prun -q x = '\t'")
441 450 nt.assert_equal(_ip.user_ns['x'], '\t')
442 451
443 452 def test_extension():
444 453 tmpdir = TemporaryDirectory()
445 454 orig_ipython_dir = _ip.ipython_dir
446 455 try:
447 456 _ip.ipython_dir = tmpdir.name
448 457 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
449 458 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
450 459 _ip.magic("install_ext %s" % url)
451 460 _ip.user_ns.pop('arq', None)
452 461 _ip.magic("load_ext daft_extension")
453 462 tt.assert_equal(_ip.user_ns['arq'], 185)
454 463 _ip.magic("unload_ext daft_extension")
455 464 assert 'arq' not in _ip.user_ns
456 465 finally:
457 466 _ip.ipython_dir = orig_ipython_dir
458 467
459 468 def test_notebook_export_json():
460 469 with TemporaryDirectory() as td:
461 470 outfile = os.path.join(td, "nb.ipynb")
462 471 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
463 472 _ip.magic("notebook -e %s" % outfile)
464 473
465 474 def test_notebook_export_py():
466 475 with TemporaryDirectory() as td:
467 476 outfile = os.path.join(td, "nb.py")
468 477 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
469 478 _ip.magic("notebook -e %s" % outfile)
470 479
471 480 def test_notebook_reformat_py():
472 481 with TemporaryDirectory() as td:
473 482 infile = os.path.join(td, "nb.ipynb")
474 483 with io.open(infile, 'w', encoding='utf-8') as f:
475 484 current.write(nb0, f, 'json')
476 485
477 486 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
478 487 _ip.magic("notebook -f py %s" % infile)
479 488
480 489 def test_notebook_reformat_json():
481 490 with TemporaryDirectory() as td:
482 491 infile = os.path.join(td, "nb.py")
483 492 with io.open(infile, 'w', encoding='utf-8') as f:
484 493 current.write(nb0, f, 'py')
485 494
486 495 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
487 496 _ip.magic("notebook -f ipynb %s" % infile)
488 497 _ip.magic("notebook -f json %s" % infile)
489 498
490 499 def test_env():
491 500 env = _ip.magic("env")
492 501 assert isinstance(env, dict), type(env)
493 502
494 503
495 504 class CellMagicTestCase(TestCase):
496 505
497 506 def check_ident(self, magic):
498 507 # Manually called, we get the result
499 508 out = _ip.run_cell_magic(magic, 'a', 'b')
500 509 nt.assert_equals(out, ('a','b'))
501 510 # Via run_cell, it goes into the user's namespace via displayhook
502 511 _ip.run_cell('%%' + magic +' c\nd')
503 512 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
504 513
505 514 def test_cell_magic_func_deco(self):
506 515 "Cell magic using simple decorator"
507 516 @register_cell_magic
508 517 def cellm(line, cell):
509 518 return line, cell
510 519
511 520 self.check_ident('cellm')
512 521
513 522 def test_cell_magic_reg(self):
514 523 "Cell magic manually registered"
515 524 def cellm(line, cell):
516 525 return line, cell
517 526
518 527 _ip.register_magic_function(cellm, 'cell', 'cellm2')
519 528 self.check_ident('cellm2')
520 529
521 530 def test_cell_magic_class(self):
522 531 "Cell magics declared via a class"
523 532 @magics_class
524 533 class MyMagics(Magics):
525 534
526 535 @cell_magic
527 536 def cellm3(self, line, cell):
528 537 return line, cell
529 538
530 539 _ip.register_magics(MyMagics)
531 540 self.check_ident('cellm3')
532 541
533 542 def test_cell_magic_class2(self):
534 543 "Cell magics declared via a class, #2"
535 544 @magics_class
536 545 class MyMagics2(Magics):
537 546
538 547 @cell_magic('cellm4')
539 548 def cellm33(self, line, cell):
540 549 return line, cell
541 550
542 551 _ip.register_magics(MyMagics2)
543 552 self.check_ident('cellm4')
544 553 # Check that nothing is registered as 'cellm33'
545 554 c33 = _ip.find_cell_magic('cellm33')
546 555 nt.assert_equals(c33, None)
547 556
General Comments 0
You need to be logged in to leave comments. Login now