def test_whole_cell(self): src = "%%cellm line\nbody\n" sp = self.sp sp.push(src) out = sp.source_reset() ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n" nt.assert_equal(out, py3compat.u_format(ref))
def test_notebook_reformat_py(): with TemporaryDirectory() as td: infile = os.path.join(td, "nb.ipynb") with io.open(infile, 'w', encoding='utf-8') as f: current.write(nb0, f, 'json') _ip.ex(py3compat.u_format("u = {u}'héllo'")) _ip.magic("notebook -f py %s" % infile)
def test_whole_cell(self): src = "%%cellm line\nbody\n" sp = self.sp sp.push(src) nt.assert_equal(sp.cell_magic_parts, ['body\n']) out = sp.source ref = "get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n" nt.assert_equal(out, py3compat.u_format(ref))
def test_whole_cell(self): src = "%%cellm line\nbody\n" sp = self.sp sp.push(src) nt.assert_equal(sp.cell_magic_parts, ['body\n']) out = sp.source ref = u"get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n" nt.assert_equal(out, py3compat.u_format(ref))
def test_notebook_reformat_py(): with TemporaryDirectory() as td: infile = os.path.join(td, "nb.ipynb") with io.open(infile, 'w', encoding='utf-8') as f: current.write(nb0, f, 'json') _ip.ex(py3compat.u_format(u"u = {u}'héllo'")) _ip.magic("notebook -f py %s" % infile)
def test_notebook_reformat_json(): with TemporaryDirectory() as td: infile = os.path.join(td, "nb.py") with io.open(infile, "w", encoding="utf-8") as f: current.write(nb0, f, "py") _ip.ex(py3compat.u_format(u"u = {u}'héllo'")) _ip.magic("notebook -f ipynb %s" % infile) _ip.magic("notebook -f json %s" % infile)
def test_notebook_reformat_py(self): from IPython.nbformat.v3.tests.nbexamples import nb0 from IPython.nbformat import current with TemporaryDirectory() as td: infile = os.path.join(td, "nb.ipynb") with io.open(infile, 'w', encoding='utf-8') as f: current.write(nb0, f, 'json') _ip.ex(py3compat.u_format(u"u = {u}'héllo'")) _ip.magic("notebook -f py %s" % infile)
def test_handlers(): call_idx = CallableIndexable() ip.user_ns["call_idx"] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([ (i, py3compat.u_format(o)) for i, o in [ ('"no change"', '"no change"'), # normal (u"lsmagic", "get_ipython().run_line_magic('lsmagic', '')"), # magic # ("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache ] ]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns["autocallable"] = autocallable # auto ip.magic("autocall 0") # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ("autocallable", "autocallable()"), # Don't add extra brackets (gh-1117) ("autocallable()", "autocallable()"), ]) ip.magic("autocall 1") run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ("len [1,2]", "len([1,2])"), # len doesn't support __getitem__... ("call_idx [1]", "call_idx [1]"), # call_idx *does*.. ("call_idx 1", "call_idx(1)"), ("len", "len"), # only at 2 does it auto-call on single args ]) ip.magic("autocall 2") run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ("len [1,2]", "len([1,2])"), ("call_idx [1]", "call_idx [1]"), ("call_idx 1", "call_idx(1)"), # This is what's different: ("len", "len()"), # only at 2 does it auto-call on single args ]) ip.magic("autocall 1") nt.assert_equal(failures, [])
def test_notebook_reformat_py(self): from IPython.nbformat.v3.tests.nbexamples import nb0 from IPython.nbformat import current with TemporaryDirectory() as td: infile = os.path.join(td, "nb.ipynb") with io.open(infile, "w", encoding="utf-8") as f: current.write(nb0, f, "json") _ip.ex(py3compat.u_format(u"u = {u}'héllo'")) _ip.magic("notebook -f py %s" % infile)
def test_handlers(): call_idx = CallableIndexable() ip.user_ns['call_idx'] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([(i,py3compat.u_format(o)) for i,o in \ [('"no change"', '"no change"'), # normal (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache ]]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns['autocallable'] = autocallable # auto ip.magic('autocall 0') # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ('autocallable', 'autocallable()'), # Don't add extra brackets (gh-1117) ('autocallable()', 'autocallable()'), ]) ip.magic('autocall 1') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. ('call_idx 1', 'call_idx(1)'), ('len', 'len'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 2') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ('len [1,2]', 'len([1,2])'), ('call_idx [1]', 'call_idx [1]'), ('call_idx 1', 'call_idx(1)'), # This is what's different: ('len', 'len()'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 1') nt.assert_equal(failures, [])
def test_tclass(self): mydir = os.path.dirname(__file__) tc = os.path.join(mydir, 'tclass') src = ("%%run '%s' C-first\n" "%%run '%s' C-second\n" "%%run '%s' C-third\n") % (tc, tc, tc) self.mktmp(src, '.ipy') out = """\ ARGV 1-: [{u}'C-first'] ARGV 1-: [{u}'C-second'] tclass.py: deleting object: C-first ARGV 1-: [{u}'C-third'] tclass.py: deleting object: C-second tclass.py: deleting object: C-third """ tt.ipexec_validate(self.fname, py3compat.u_format(out))
def test_handlers(): # alias expansion # We're using 'true' as our syscall of choice because it doesn't # write anything to stdout. # Turn off actual execution of aliases, because it's noisy old_system_cmd = ip.system ip.system = lambda cmd: None ip.alias_manager.alias_table['an_alias'] = (0, 'true') # These are useful for checking a particular recursive alias issue ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') ip.alias_manager.alias_table['d'] = (0, 'true') run([(i,py3compat.u_format(o)) for i,o in \ [("an_alias", "get_ipython().system({u}'true ')"), # alias # Below: recursive aliases should expand whitespace-surrounded # chars, *not* initial chars which happen to be aliases: ("top", "get_ipython().system({u}'d:/cygwin/top ')"), ]]) ip.system = old_system_cmd call_idx = CallableIndexable() ip.user_ns['call_idx'] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([(i,py3compat.u_format(o)) for i,o in \ [('"no change"', '"no change"'), # normal (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache ]]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns['autocallable'] = autocallable # auto ip.magic('autocall 0') # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ('autocallable', 'autocallable()'), # Don't add extra brackets (gh-1117) ('autocallable()', 'autocallable()'), ]) ip.magic('autocall 1') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. ('call_idx 1', 'call_idx(1)'), ('len', 'len'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 2') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ('len [1,2]', 'len([1,2])'), ('call_idx [1]', 'call_idx [1]'), ('call_idx 1', 'call_idx(1)'), # This is what's different: ('len', 'len()'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 1') nt.assert_equal(failures, [])
def test_whole_cell(self): src = "%%cellm line\nbody\n" out = self.sp.transform_cell(src) ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n" nt.assert_equal(out, py3compat.u_format(ref))
if inp is None: out = transformer.reset() else: out = transformer.push(inp) nt.assert_equal(out, tr) finally: transformer.reset() # Data for all the syntax tests in the form of lists of pairs of # raw/transformed input. We store it here as a global dict so that we can use # it both within single-function tests and also to validate the behavior of the # larger objects syntax = \ dict(assign_system = [(i,py3compat.u_format(o)) for i,o in \ [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"), (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"), ('x=1', 'x=1'), # normal input is unmodified (' ',' '), # blank lines are kept intact ]], assign_magic = [(i,py3compat.u_format(o)) for i,o in \ [(u'a =% who', "a = get_ipython().magic({u}'who')"), (u'b = %who', "b = get_ipython().magic({u}'who')"), ('x=1', 'x=1'), # normal input is unmodified (' ',' '), # blank lines are kept intact ]], classic_prompt =
def test_notebook_export_json(self): with TemporaryDirectory() as td: outfile = os.path.join(td, "nb.ipynb") _ip.ex(py3compat.u_format(u"u = {u}'héllo'")) _ip.magic("notebook -e %s" % outfile)
# Transformer tests def transform_checker(tests, func): """Utility to loop over test inputs""" for inp, tr in tests: nt.assert_equal(func(inp), tr) # Data for all the syntax tests in the form of lists of pairs of # raw/transformed input. We store it here as a global dict so that we can use # it both within single-function tests and also to validate the behavior of the # larger objects syntax = dict( assign_system=[ (i, py3compat.u_format(o)) for i, o in [ (u"a =! ls", "a = get_ipython().getoutput({u}'ls')"), (u"b = !ls", "b = get_ipython().getoutput({u}'ls')"), ("x=1", "x=1"), # normal input is unmodified (" ", " "), # blank lines are kept intact ] ], assign_magic=[ (i, py3compat.u_format(o)) for i, o in [ (u"a =% who", "a = get_ipython().magic({u}'who')"), (u"b = %who", "b = get_ipython().magic({u}'who')"), ("x=1", "x=1"), # normal input is unmodified (" ", " "), # blank lines are kept intact ]
out = transformer.reset() else: out = transformer.push(inp) nt.assert_equal(out, tr) finally: transformer.reset() # Data for all the syntax tests in the form of lists of pairs of # raw/transformed input. We store it here as a global dict so that we can use # it both within single-function tests and also to validate the behavior of the # larger objects syntax = dict( assign_system=[ (i, py3compat.u_format(o)) for i, o in [ (u"a =! ls", "a = get_ipython().getoutput('ls')"), (u"b = !ls", "b = get_ipython().getoutput('ls')"), (u"c= !ls", "c = get_ipython().getoutput('ls')"), (u"d == !ls", u"d == !ls"), # Invalid syntax, but we leave == alone. ("x=1", "x=1"), # normal input is unmodified (" ", " "), # blank lines are kept intact # Tuple unpacking ( u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput(\"echo 'a\\\\nb'\")", ), (u"a,= !echo 'a'", u"a, = get_ipython().getoutput(\"echo 'a'\")"), ( u"a, *bc = !echo 'a\\nb\\nc'",
def test_handlers(): # alias expansion # We're using 'true' as our syscall of choice because it doesn't # write anything to stdout. # Turn off actual execution of aliases, because it's noisy old_system_cmd = ip.system ip.system = lambda cmd: None ip.alias_manager.alias_table['an_alias'] = (0, 'true') # These are useful for checking a particular recursive alias issue ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') ip.alias_manager.alias_table['d'] = (0, 'true') run([(i,py3compat.u_format(o)) for i,o in \ [("an_alias", "get_ipython().system({u}'true ')"), # alias # Below: recursive aliases should expand whitespace-surrounded # chars, *not* initial chars which happen to be aliases: ("top", "get_ipython().system({u}'d:/cygwin/top ')"), ]]) ip.system = old_system_cmd call_idx = CallableIndexable() ip.user_ns['call_idx'] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([(i,py3compat.u_format(o)) for i,o in \ [('"no change"', '"no change"'), # normal (u"!true", "get_ipython().system({u}'true')"), # shell_escapes (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache # post-esc-char whitespace goes inside (u"! true", "get_ipython().system({u}' true')"), # handle_help # These are weak tests -- just looking at what the help handlers # logs, which is not how it really does its work. But it still # lets us check the key paths through the handler. ("x=1 # what?", "x=1 # what?"), # no help if valid python ]]) # multi_line_specials ip.prefilter_manager.multi_line_specials = False # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion run([ (u'if 1:\n !true', u'if 1:\n !true'), (u'if 1:\n lsmagic', u'if 1:\n lsmagic'), (u'if 1:\n an_alias', u'if 1:\n an_alias'), ]) ip.prefilter_manager.multi_line_specials = True # initial indents must be preserved. run([(i,py3compat.u_format(o)) for i,o in \ [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"), (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"), (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"), # Weird one (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"), # Even with m_l_s on, autocall is off even with special chars ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'), # What about !! ]]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns['autocallable'] = autocallable # auto ip.magic('autocall 0') # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ('autocallable', 'autocallable()'), # Don't add extra brackets (gh-1117) ('autocallable()', 'autocallable()'), (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ]) ip.magic('autocall 1') run([ (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. ('call_idx 1', 'call_idx(1)'), ('len', 'len'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 2') run([ (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ('len [1,2]', 'len([1,2])'), ('call_idx [1]', 'call_idx [1]'), ('call_idx 1', 'call_idx(1)'), # This is what's different: ('len', 'len()'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 1') nt.assert_equal(failures, [])
def test_handlers(): # alias expansion # We're using 'true' as our syscall of choice because it doesn't # write anything to stdout. # Turn off actual execution of aliases, because it's noisy old_system_cmd = ip.system ip.system = lambda cmd: None ip.alias_manager.alias_table['an_alias'] = (0, 'true') # These are useful for checking a particular recursive alias issue ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') ip.alias_manager.alias_table['d'] = (0, 'true') run([(i,py3compat.u_format(o)) for i,o in \ [("an_alias", "get_ipython().system({u}'true ')"), # alias # Below: recursive aliases should expand whitespace-surrounded # chars, *not* initial chars which happen to be aliases: ("top", "get_ipython().system({u}'d:/cygwin/top ')"), ]]) ip.system = old_system_cmd call_idx = CallableIndexable() ip.user_ns['call_idx'] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([(i,py3compat.u_format(o)) for i,o in \ [('"no change"', '"no change"'), # normal ("lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache ]]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns['autocallable'] = autocallable # auto ip.magic('autocall 0') # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ('autocallable', 'autocallable()'), # Don't add extra brackets (gh-1117) ('autocallable()', 'autocallable()'), ]) ip.magic('autocall 1') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. ('call_idx 1', 'call_idx(1)'), ('len', 'len'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 2') run([ ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ('len [1,2]', 'len([1,2])'), ('call_idx [1]', 'call_idx [1]'), ('call_idx 1', 'call_idx(1)'), # This is what's different: ('len', 'len()'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 1') nt.assert_equal(failures, [])
for inp, tr in tests: if inp is None: out = transformer.reset() else: out = transformer.push(inp) nt.assert_equal(out, tr) finally: transformer.reset() # Data for all the syntax tests in the form of lists of pairs of # raw/transformed input. We store it here as a global dict so that we can use # it both within single-function tests and also to validate the behavior of the # larger objects syntax = \ dict(assign_system=[(i, py3compat.u_format(o)) for i, o in [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"), (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"), (u'c= !ls', "c = get_ipython().getoutput({u}'ls')"), # Invalid syntax, but we leave == alone. (u'd == !ls', u'd == !ls'), ('x=1', 'x=1'), # normal input is unmodified (' ', ' '), # blank lines are kept intact # Tuple unpacking (u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput({u}\"echo 'a\\\\nb'\")"), (u"a,= !echo 'a'", u"a, = get_ipython().getoutput({u}\"echo 'a'\")"), (u"a, *bc = !echo 'a\\nb\\nc'", u"a, *bc = get_ipython().getoutput({u}\"echo 'a\\\\nb\\\\nc'\")"),
def test_handlers(): # alias expansion # We're using 'true' as our syscall of choice because it doesn't # write anything to stdout. # Turn off actual execution of aliases, because it's noisy old_system_cmd = ip.system ip.system = lambda cmd: None ip.alias_manager.alias_table['an_alias'] = (0, 'true') # These are useful for checking a particular recursive alias issue ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top') ip.alias_manager.alias_table['d'] = (0, 'true') run([(i,py3compat.u_format(o)) for i,o in \ [("an_alias", "get_ipython().system({u}'true ')"), # alias # Below: recursive aliases should expand whitespace-surrounded # chars, *not* initial chars which happen to be aliases: ("top", "get_ipython().system({u}'d:/cygwin/top ')"), ]]) ip.system = old_system_cmd call_idx = CallableIndexable() ip.user_ns['call_idx'] = call_idx # For many of the below, we're also checking that leading whitespace # turns off the esc char, which it should unless there is a continuation # line. run([(i,py3compat.u_format(o)) for i,o in \ [('"no change"', '"no change"'), # normal (u"!true", "get_ipython().system({u}'true')"), # shell_escapes (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache # post-esc-char whitespace goes inside (u"! true", "get_ipython().system({u}' true')"), # handle_help # These are weak tests -- just looking at what the help handlers # logs, which is not how it really does its work. But it still # lets us check the key paths through the handler. ("x=1 # what?", "x=1 # what?"), # no help if valid python ]]) # multi_line_specials ip.prefilter_manager.multi_line_specials = False # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion run([ (u'if 1:\n !true', u'if 1:\n !true'), (u'if 1:\n lsmagic', u'if 1:\n lsmagic'), (u'if 1:\n an_alias', u'if 1:\n an_alias'), ]) ip.prefilter_manager.multi_line_specials = True # initial indents must be preserved. run([(i,py3compat.u_format(o)) for i,o in \ [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"), (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"), (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"), # Weird one (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"), # Even with m_l_s on, autocall is off even with special chars ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'), # What about !! ]]) # Objects which are instances of IPyAutocall are *always* autocalled autocallable = Autocallable() ip.user_ns['autocallable'] = autocallable # auto ip.magic('autocall 0') # Only explicit escapes or instances of IPyAutocallable should get # expanded run([ ('len "abc"', 'len "abc"'), ('autocallable', 'autocallable()'), # Don't add extra brackets (gh-1117) ('autocallable()', 'autocallable()'), (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ]) ip.magic('autocall 1') run([ (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens # Autocall is turned off if first arg is [] and the object # is both callable and indexable. Like so: ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__... ('call_idx [1]', 'call_idx [1]'), # call_idx *does*.. ('call_idx 1', 'call_idx(1)'), ('len', 'len'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 2') run([ (",list 1 2 3", 'list("1", "2", "3")'), (";list 1 2 3", 'list("1 2 3")'), ("/len range(1,4)", 'len(range(1,4))'), ('len "abc"', 'len("abc")'), ('len "abc";', 'len("abc");'), ('len [1,2]', 'len([1,2])'), ('call_idx [1]', 'call_idx [1]'), ('call_idx 1', 'call_idx(1)'), # This is what's different: ('len', 'len()'), # only at 2 does it auto-call on single args ]) ip.magic('autocall 1') nt.assert_equals(failures, [])