~ubuntu-branches/ubuntu/raring/ipython/raring

« back to all changes in this revision

Viewing changes to IPython/core/tests/test_magic.py

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2012-06-30 15:05:32 UTC
  • mfrom: (1.2.18) (6.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120630150532-c95s7y8qek15kdbo
Tags: 0.13-1
* New upstream release
  No repackging necessary anymore, js sources available in external
  minified variants are not installed
* refresh patches, drop upstream applied full-qt-imports 
* add except-shadows-builtin-fix.patch
* drop libjs-jquery-ui dependency, use the embedded development branch
* don't compress the examples
* remove executable permissions on embedded codemirror files
* build with LC_ALL=C.UTF-8 to avoid a unicode issue in setupbase.py
* remove generated doc images in clean
* update copyright with new and removed files
* remove unreachable Stephan Peijnik from uploaders
  thank you for your work

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
1
2
"""Tests for various magic functions.
2
3
 
3
4
Needs to be run by nose (to make ipython session available).
8
9
# Imports
9
10
#-----------------------------------------------------------------------------
10
11
 
 
12
import io
11
13
import os
 
14
import sys
 
15
from StringIO import StringIO
 
16
from unittest import TestCase
 
17
 
 
18
try:
 
19
    from importlib import invalidate_caches   # Required from Python 3.3
 
20
except ImportError:
 
21
    def invalidate_caches():
 
22
        pass
12
23
 
13
24
import nose.tools as nt
14
25
 
 
26
from IPython.core import magic
 
27
from IPython.core.magic import (Magics, magics_class, line_magic,
 
28
                                cell_magic, line_cell_magic,
 
29
                                register_line_magic, register_cell_magic,
 
30
                                register_line_cell_magic)
 
31
from IPython.core.magics import execution, script
 
32
from IPython.nbformat.v3.tests.nbexamples import nb0
 
33
from IPython.nbformat import current
15
34
from IPython.testing import decorators as dec
16
35
from IPython.testing import tools as tt
17
36
from IPython.utils import py3compat
 
37
from IPython.utils.tempdir import TemporaryDirectory
 
38
from IPython.utils.process import find_cmd
18
39
 
19
40
#-----------------------------------------------------------------------------
20
41
# Test functions begin
21
42
#-----------------------------------------------------------------------------
22
43
 
 
44
@magic.magics_class
 
45
class DummyMagics(magic.Magics): pass
 
46
 
23
47
def test_rehashx():
24
48
    # clear up everything
25
49
    _ip = get_ipython()
43
67
    """Test that we don't mangle paths when parsing magic options."""
44
68
    ip = get_ipython()
45
69
    path = 'c:\\x'
46
 
    opts = ip.parse_options('-f %s' % path,'f:')[0]
 
70
    m = DummyMagics(ip)
 
71
    opts = m.parse_options('-f %s' % path,'f:')[0]
47
72
    # argv splitting is os-dependent
48
73
    if os.name == 'posix':
49
74
        expected = 'c:x'
51
76
        expected = path
52
77
    nt.assert_equals(opts['f'], expected)
53
78
 
 
79
def test_magic_parse_long_options():
 
80
    """Magic.parse_options can handle --foo=bar long options"""
 
81
    ip = get_ipython()
 
82
    m = DummyMagics(ip)
 
83
    opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
 
84
    nt.assert_true('foo' in opts)
 
85
    nt.assert_true('bar' in opts)
 
86
    nt.assert_true(opts['bar'], "bubble")
 
87
 
54
88
 
55
89
@dec.skip_without('sqlite3')
56
90
def doctest_hist_f():
183
217
    with tt.AssertPrints("13"):
184
218
        ip.run_cell("test")
185
219
 
186
 
    
187
 
# XXX failing for now, until we get clearcmd out of quarantine.  But we should
188
 
# fix this and revert the skip to happen only if numpy is not around.
189
 
#@dec.skipif_not_numpy
190
 
@dec.skip_known_failure
191
 
def test_numpy_clear_array_undec():
192
 
    from IPython.extensions import clearcmd
193
220
 
 
221
@dec.skipif_not_numpy
 
222
def test_numpy_reset_array_undec():
 
223
    "Test '%reset array' functionality"
194
224
    _ip.ex('import numpy as np')
195
225
    _ip.ex('a = np.empty(2)')
196
226
    yield (nt.assert_true, 'a' in _ip.user_ns)
197
 
    _ip.magic('clear array')
 
227
    _ip.magic('reset -f array')
198
228
    yield (nt.assert_false, 'a' in _ip.user_ns)
199
 
    
 
229
 
 
230
def test_reset_out():
 
231
    "Test '%reset out' magic"
 
232
    _ip.run_cell("parrot = 'dead'", store_history=True)
 
233
    # test '%reset -f out', make an Out prompt
 
234
    _ip.run_cell("parrot", store_history=True)
 
235
    nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
 
236
    _ip.magic('reset -f out')
 
237
    nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
 
238
    nt.assert_true(len(_ip.user_ns['Out']) == 0)
 
239
 
 
240
def test_reset_in():
 
241
    "Test '%reset in' magic"
 
242
    # test '%reset -f in'
 
243
    _ip.run_cell("parrot", store_history=True)
 
244
    nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
 
245
    _ip.magic('%reset -f in')
 
246
    nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
 
247
    nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
 
248
 
 
249
def test_reset_dhist():
 
250
    "Test '%reset dhist' magic"
 
251
    _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
 
252
    _ip.magic('cd ' + os.path.dirname(nt.__file__))
 
253
    _ip.magic('cd -')
 
254
    nt.assert_true(len(_ip.user_ns['_dh']) > 0)
 
255
    _ip.magic('reset -f dhist')
 
256
    nt.assert_true(len(_ip.user_ns['_dh']) == 0)
 
257
    _ip.run_cell("_dh = [d for d in tmp]") #restore
 
258
 
 
259
def test_reset_in_length():
 
260
    "Test that '%reset in' preserves In[] length"
 
261
    _ip.run_cell("print 'foo'")
 
262
    _ip.run_cell("reset -f in")
 
263
    nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
200
264
 
201
265
def test_time():
202
266
    _ip.magic('time None')
203
267
 
 
268
def test_tb_syntaxerror():
 
269
    """test %tb after a SyntaxError"""
 
270
    ip = get_ipython()
 
271
    ip.run_cell("for")
 
272
    
 
273
    # trap and validate stdout
 
274
    save_stdout = sys.stdout
 
275
    try:
 
276
        sys.stdout = StringIO()
 
277
        ip.run_cell("%tb")
 
278
        out = sys.stdout.getvalue()
 
279
    finally:
 
280
        sys.stdout = save_stdout
 
281
    # trim output, and only check the last line
 
282
    last_line = out.rstrip().splitlines()[-1].strip()
 
283
    nt.assert_equals(last_line, "SyntaxError: invalid syntax")
 
284
 
204
285
 
205
286
@py3compat.doctest_refactor_print
206
287
def doctest_time():
229
310
    """Tests for basic options parsing in magics."""
230
311
    # These are only the most minimal of tests, more should be added later.  At
231
312
    # the very least we check that basic text/unicode calls work OK.
232
 
    nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
233
 
    nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
 
313
    m = DummyMagics(_ip)
 
314
    nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
 
315
    nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
234
316
 
235
317
    
236
318
def test_dirops():
271
353
    _ip.run_cell("a")
272
354
    
273
355
    nt.assert_equal(monitor, [])
274
 
    _ip.magic_reset("-f")
 
356
    _ip.magic("reset -f")
275
357
    nt.assert_equal(monitor, [1])
276
358
    
277
359
class TestXdel(tt.TempFileMixin):
321
403
    Out[7]: ['alpha', 'beta']
322
404
    """
323
405
 
 
406
def test_whos():
 
407
    """Check that whos is protected against objects where repr() fails."""
 
408
    class A(object):
 
409
        def __repr__(self):
 
410
            raise Exception()
 
411
    _ip.user_ns['a'] = A()
 
412
    _ip.magic("whos")
 
413
 
324
414
@py3compat.u_format
325
415
def doctest_precision():
326
416
    """doctest for %precision
327
417
    
328
 
    In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
 
418
    In [1]: f = get_ipython().display_formatter.formatters['text/plain']
329
419
    
330
420
    In [2]: %precision 5
331
421
    Out[2]: {u}'%.5f'
359
449
    "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
360
450
    _ip.magic("timeit ('#')")
361
451
 
362
 
@dec.skipif(_ip.magic_prun == _ip.profile_missing_notice)
 
452
 
 
453
def test_timeit_special_syntax():
 
454
    "Test %%timeit with IPython special syntax"
 
455
    from IPython.core.magic import register_line_magic
 
456
 
 
457
    @register_line_magic
 
458
    def lmagic(line):
 
459
        ip = get_ipython()
 
460
        ip.user_ns['lmagic_out'] = line
 
461
 
 
462
    # line mode test
 
463
    _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
 
464
    nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
 
465
    # cell mode test
 
466
    _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
 
467
    nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
 
468
    
 
469
 
 
470
@dec.skipif(execution.profile is None)
363
471
def test_prun_quotes():
364
472
    "Test that prun does not clobber string escapes (GH #1302)"
365
473
    _ip.magic(r"prun -q x = '\t'")
366
474
    nt.assert_equal(_ip.user_ns['x'], '\t')
 
475
 
 
476
def test_extension():
 
477
    tmpdir = TemporaryDirectory()
 
478
    orig_ipython_dir = _ip.ipython_dir
 
479
    try:
 
480
        _ip.ipython_dir = tmpdir.name
 
481
        nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
 
482
        url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
 
483
        _ip.magic("install_ext %s" % url)
 
484
        _ip.user_ns.pop('arq', None)
 
485
        invalidate_caches()   # Clear import caches
 
486
        _ip.magic("load_ext daft_extension")
 
487
        tt.assert_equal(_ip.user_ns['arq'], 185)
 
488
        _ip.magic("unload_ext daft_extension")
 
489
        assert 'arq' not in _ip.user_ns
 
490
    finally:
 
491
        _ip.ipython_dir = orig_ipython_dir
 
492
        
 
493
def test_notebook_export_json():
 
494
    with TemporaryDirectory() as td:
 
495
        outfile = os.path.join(td, "nb.ipynb")
 
496
        _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
 
497
        _ip.magic("notebook -e %s" % outfile)
 
498
 
 
499
def test_notebook_export_py():
 
500
    with TemporaryDirectory() as td:
 
501
        outfile = os.path.join(td, "nb.py")
 
502
        _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
 
503
        _ip.magic("notebook -e %s" % outfile)
 
504
 
 
505
def test_notebook_reformat_py():
 
506
    with TemporaryDirectory() as td:
 
507
        infile = os.path.join(td, "nb.ipynb")
 
508
        with io.open(infile, 'w', encoding='utf-8') as f:
 
509
            current.write(nb0, f, 'json')
 
510
            
 
511
        _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
 
512
        _ip.magic("notebook -f py %s" % infile)
 
513
 
 
514
def test_notebook_reformat_json():
 
515
    with TemporaryDirectory() as td:
 
516
        infile = os.path.join(td, "nb.py")
 
517
        with io.open(infile, 'w', encoding='utf-8') as f:
 
518
            current.write(nb0, f, 'py')
 
519
            
 
520
        _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
 
521
        _ip.magic("notebook -f ipynb %s" % infile)
 
522
        _ip.magic("notebook -f json %s" % infile)
 
523
 
 
524
def test_env():
 
525
    env = _ip.magic("env")
 
526
    assert isinstance(env, dict), type(env)
 
527
 
 
528
 
 
529
class CellMagicTestCase(TestCase):
 
530
 
 
531
    def check_ident(self, magic):
 
532
        # Manually called, we get the result
 
533
        out = _ip.run_cell_magic(magic, 'a', 'b')
 
534
        nt.assert_equals(out, ('a','b'))
 
535
        # Via run_cell, it goes into the user's namespace via displayhook
 
536
        _ip.run_cell('%%' + magic +' c\nd')
 
537
        nt.assert_equals(_ip.user_ns['_'], ('c','d'))
 
538
 
 
539
    def test_cell_magic_func_deco(self):
 
540
        "Cell magic using simple decorator"
 
541
        @register_cell_magic
 
542
        def cellm(line, cell):
 
543
            return line, cell
 
544
 
 
545
        self.check_ident('cellm')
 
546
 
 
547
    def test_cell_magic_reg(self):
 
548
        "Cell magic manually registered"
 
549
        def cellm(line, cell):
 
550
            return line, cell
 
551
 
 
552
        _ip.register_magic_function(cellm, 'cell', 'cellm2')
 
553
        self.check_ident('cellm2')
 
554
 
 
555
    def test_cell_magic_class(self):
 
556
        "Cell magics declared via a class"
 
557
        @magics_class
 
558
        class MyMagics(Magics):
 
559
 
 
560
            @cell_magic
 
561
            def cellm3(self, line, cell):
 
562
                return line, cell
 
563
 
 
564
        _ip.register_magics(MyMagics)
 
565
        self.check_ident('cellm3')
 
566
 
 
567
    def test_cell_magic_class2(self):
 
568
        "Cell magics declared via a class, #2"
 
569
        @magics_class
 
570
        class MyMagics2(Magics):
 
571
 
 
572
            @cell_magic('cellm4')
 
573
            def cellm33(self, line, cell):
 
574
                return line, cell
 
575
            
 
576
        _ip.register_magics(MyMagics2)
 
577
        self.check_ident('cellm4')
 
578
        # Check that nothing is registered as 'cellm33'
 
579
        c33 = _ip.find_cell_magic('cellm33')
 
580
        nt.assert_equals(c33, None)
 
581
 
 
582
def test_file():
 
583
    """Basic %%file"""
 
584
    ip = get_ipython()
 
585
    with TemporaryDirectory() as td:
 
586
        fname = os.path.join(td, 'file1')
 
587
        ip.run_cell_magic("file", fname, u'\n'.join([
 
588
            'line1',
 
589
            'line2',
 
590
        ]))
 
591
        with open(fname) as f:
 
592
            s = f.read()
 
593
        nt.assert_in('line1\n', s)
 
594
        nt.assert_in('line2', s)
 
595
 
 
596
def test_file_unicode():
 
597
    """%%file with unicode cell"""
 
598
    ip = get_ipython()
 
599
    with TemporaryDirectory() as td:
 
600
        fname = os.path.join(td, 'file1')
 
601
        ip.run_cell_magic("file", fname, u'\n'.join([
 
602
            u'liné1',
 
603
            u'liné2',
 
604
        ]))
 
605
        with io.open(fname, encoding='utf-8') as f:
 
606
            s = f.read()
 
607
        nt.assert_in(u'liné1\n', s)
 
608
        nt.assert_in(u'liné2', s)
 
609
 
 
610
def test_file_amend():
 
611
    """%%file -a amends files"""
 
612
    ip = get_ipython()
 
613
    with TemporaryDirectory() as td:
 
614
        fname = os.path.join(td, 'file2')
 
615
        ip.run_cell_magic("file", fname, u'\n'.join([
 
616
            'line1',
 
617
            'line2',
 
618
        ]))
 
619
        ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
 
620
            'line3',
 
621
            'line4',
 
622
        ]))
 
623
        with open(fname) as f:
 
624
            s = f.read()
 
625
        nt.assert_in('line1\n', s)
 
626
        nt.assert_in('line3\n', s)
 
627
        
 
628
    
 
629
def test_script_config():
 
630
    ip = get_ipython()
 
631
    ip.config.ScriptMagics.script_magics = ['whoda']
 
632
    sm = script.ScriptMagics(shell=ip)
 
633
    nt.assert_in('whoda', sm.magics['cell'])
 
634
 
 
635
@dec.skip_win32
 
636
def test_script_out():
 
637
    ip = get_ipython()
 
638
    ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
 
639
    nt.assert_equals(ip.user_ns['output'], 'hi\n')
 
640
 
 
641
@dec.skip_win32
 
642
def test_script_err():
 
643
    ip = get_ipython()
 
644
    ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
 
645
    nt.assert_equals(ip.user_ns['error'], 'hello\n')
 
646
 
 
647
@dec.skip_win32
 
648
def test_script_out_err():
 
649
    ip = get_ipython()
 
650
    ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
 
651
    nt.assert_equals(ip.user_ns['output'], 'hi\n')
 
652
    nt.assert_equals(ip.user_ns['error'], 'hello\n')
 
653
 
 
654
@dec.skip_win32
 
655
def test_script_bg_out():
 
656
    ip = get_ipython()
 
657
    ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
 
658
    nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
 
659
 
 
660
@dec.skip_win32
 
661
def test_script_bg_err():
 
662
    ip = get_ipython()
 
663
    ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
 
664
    nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
 
665
 
 
666
@dec.skip_win32
 
667
def test_script_bg_out_err():
 
668
    ip = get_ipython()
 
669
    ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
 
670
    nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
 
671
    nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
 
672
 
 
673
def test_script_defaults():
 
674
    ip = get_ipython()
 
675
    for cmd in ['sh', 'bash', 'perl', 'ruby']:
 
676
        try:
 
677
            find_cmd(cmd)
 
678
        except Exception:
 
679
            pass
 
680
        else:
 
681
            nt.assert_in(cmd, ip.magics_manager.magics['cell'])
 
682
 
 
683
 
 
684
@magics_class
 
685
class FooFoo(Magics):
 
686
    """class with both %foo and %%foo magics"""
 
687
    @line_magic('foo')
 
688
    def line_foo(self, line):
 
689
        "I am line foo"
 
690
        pass
 
691
 
 
692
    @cell_magic("foo")
 
693
    def cell_foo(self, line, cell):
 
694
        "I am cell foo, not line foo"
 
695
        pass
 
696
 
 
697
def test_line_cell_info():
 
698
    """%%foo and %foo magics are distinguishable to inspect"""
 
699
    ip = get_ipython()
 
700
    ip.magics_manager.register(FooFoo)
 
701
    oinfo = ip.object_inspect('foo')
 
702
    nt.assert_true(oinfo['found'])
 
703
    nt.assert_true(oinfo['ismagic'])
 
704
    
 
705
    oinfo = ip.object_inspect('%%foo')
 
706
    nt.assert_true(oinfo['found'])
 
707
    nt.assert_true(oinfo['ismagic'])
 
708
    nt.assert_equals(oinfo['docstring'], FooFoo.cell_foo.__doc__)
 
709
 
 
710
    oinfo = ip.object_inspect('%foo')
 
711
    nt.assert_true(oinfo['found'])
 
712
    nt.assert_true(oinfo['ismagic'])
 
713
    nt.assert_equals(oinfo['docstring'], FooFoo.line_foo.__doc__)
 
714
 
 
715
def test_multiple_magics():
 
716
    ip = get_ipython()
 
717
    foo1 = FooFoo(ip)
 
718
    foo2 = FooFoo(ip)
 
719
    mm = ip.magics_manager
 
720
    mm.register(foo1)
 
721
    nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
 
722
    mm.register(foo2)
 
723
    nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
 
724
 
 
725
def test_alias_magic():
 
726
    """Test %alias_magic."""
 
727
    ip = get_ipython()
 
728
    mm = ip.magics_manager
 
729
 
 
730
    # Basic operation: both cell and line magics are created, if possible.
 
731
    ip.run_line_magic('alias_magic', 'timeit_alias timeit')
 
732
    nt.assert_true('timeit_alias' in mm.magics['line'])
 
733
    nt.assert_true('timeit_alias' in mm.magics['cell'])
 
734
 
 
735
    # --cell is specified, line magic not created.
 
736
    ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
 
737
    nt.assert_false('timeit_cell_alias' in mm.magics['line'])
 
738
    nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
 
739
 
 
740
    # Test that line alias is created successfully.
 
741
    ip.run_line_magic('alias_magic', '--line env_alias env')
 
742
    nt.assert_equal(ip.run_line_magic('env', ''),
 
743
                    ip.run_line_magic('env_alias', ''))