##// END OF EJS Templates
Change directory to simplify test_globlist...
Change directory to simplify test_globlist as @bfroehle suggested

File last commit:

r7826:91f6c75d
r7945:a5138a32
Show More
test_inputsplitter.py
845 lines | 29.0 KiB | text/x-python | PythonLexer
/ IPython / core / tests / test_inputsplitter.py
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 # -*- coding: utf-8 -*-
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 """Tests for the inputsplitter module.
Fernando Perez
Improve docs and comments of some internal tools, and of testing code
r3297
Authors
-------
* Fernando Perez
* Robert Kern
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 """
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2010-2011 The IPython Development Team
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# stdlib
import unittest
Fernando Perez
Add test for missing input encoding. Back to 100% coverage.
r2718 import sys
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
# Third party
import nose.tools as nt
# Our own
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 from IPython.core import inputsplitter as isp
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 from IPython.testing import tools as tt
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 from IPython.utils import py3compat
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663
#-----------------------------------------------------------------------------
# Semi-complete examples (also used as tests)
#-----------------------------------------------------------------------------
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
# Note: at the bottom, there's a slightly more complete version of this that
# can be useful during development of code here.
Thomas Kluyver
Rename misleading use of raw_input so it's not automatically converted to input by 2to3.
r3119 def mini_interactive_loop(input_func):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 """Minimal example of the logic of an interactive interpreter loop.
This serves as an example, and it is used by the test system with a fake
raw_input that simulates interactive input."""
from IPython.core.inputsplitter import InputSplitter
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = InputSplitter()
# In practice, this input loop would be wrapped in an outside loop to read
# input indefinitely, until some exit/quit command was issued. Here we
# only illustrate the basic inner loop.
while isp.push_accepts_more():
indent = ' '*isp.indent_spaces
prompt = '>>> ' + indent
Thomas Kluyver
Rename misleading use of raw_input so it's not automatically converted to input by 2to3.
r3119 line = indent + input_func(prompt)
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push(line)
# Here we just return input so we can use it in a test suite, but a real
# interpreter would instead send it for execution somewhere.
src = isp.source_reset()
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 #print 'Input source was:\n', src # dbg
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 return src
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
#-----------------------------------------------------------------------------
Fernando Perez
Completed full block splitting for block-based frontends.
r2645 # Test utilities, just for local use
#-----------------------------------------------------------------------------
def assemble(block):
"""Assemble a block into multi-line sub-blocks."""
return ['\n'.join(sub_block)+'\n' for sub_block in block]
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663
def pseudo_input(lines):
"""Return a function that acts like raw_input but feeds the input list."""
ilines = iter(lines)
def raw_in(prompt):
try:
return next(ilines)
except StopIteration:
return ''
return raw_in
Fernando Perez
Completed full block splitting for block-based frontends.
r2645 #-----------------------------------------------------------------------------
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 # Tests
#-----------------------------------------------------------------------------
def test_spaces():
tests = [('', 0),
(' ', 1),
('\n', 0),
(' \n', 1),
('x', 0),
(' x', 1),
(' x',2),
(' x',4),
# Note: tabs are counted as a single whitespace!
('\tx', 1),
('\t x', 2),
]
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.num_ini_spaces, tests)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
def test_remove_comments():
tests = [('text', 'text'),
('text # comment', 'text '),
('text # comment\n', 'text \n'),
('text # comment \n', 'text \n'),
('line # c \nline\n','line \nline\n'),
('line # c \nline#c2 \nline\nline #c\n\n',
'line \nline\nline\nline \n\n'),
]
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.remove_comments, tests)
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 def test_has_comment():
tests = [('text', False),
('text #comment', True),
('text #comment\n', True),
('#comment', True),
('#comment\n', True),
('a = "#string"', False),
('a = "#string" # comment', True),
('a #comment not "string"', True),
]
tt.check_pairs(isp.has_comment, tests)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
def test_get_input_encoding():
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 encoding = isp.get_input_encoding()
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 nt.assert_true(isinstance(encoding, basestring))
# simple-minded check that at least encoding a simple string works with the
# encoding we got.
Thomas Kluyver
Start using py3compat module.
r4731 nt.assert_equal(u'test'.encode(encoding), b'test')
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
Fernando Perez
Add test for missing input encoding. Back to 100% coverage.
r2718 class NoInputEncodingTestCase(unittest.TestCase):
def setUp(self):
self.old_stdin = sys.stdin
class X: pass
fake_stdin = X()
sys.stdin = fake_stdin
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add test for missing input encoding. Back to 100% coverage.
r2718 def test(self):
# Verify that if sys.stdin has no 'encoding' attribute we do the right
# thing
enc = isp.get_input_encoding()
self.assertEqual(enc, 'ascii')
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add test for missing input encoding. Back to 100% coverage.
r2718 def tearDown(self):
sys.stdin = self.old_stdin
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 class InputSplitterTestCase(unittest.TestCase):
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 def setUp(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.isp = isp.InputSplitter()
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
def test_reset(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
isp.push('x=1')
isp.reset()
self.assertEqual(isp._buffer, [])
self.assertEqual(isp.indent_spaces, 0)
self.assertEqual(isp.source, '')
self.assertEqual(isp.code, None)
self.assertEqual(isp._is_complete, False)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
def test_source(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.isp._store('1')
self.isp._store('2')
self.assertEqual(self.isp.source, '1\n2\n')
self.assertTrue(len(self.isp._buffer)>0)
self.assertEqual(self.isp.source_reset(), '1\n2\n')
self.assertEqual(self.isp._buffer, [])
self.assertEqual(self.isp.source, '')
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 def test_indent(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp # shorthand
isp.push('x=1')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n x=1')
self.assertEqual(isp.indent_spaces, 4)
isp.push('y=2\n')
self.assertEqual(isp.indent_spaces, 0)
Fernando Perez
Continue refactoring input handling across clients....
r3085
def test_indent2(self):
# In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
isp = self.isp
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push('if 1:')
self.assertEqual(isp.indent_spaces, 4)
isp.push(' x=1')
self.assertEqual(isp.indent_spaces, 4)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 # Blank lines shouldn't change the indent level
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push(' '*2)
self.assertEqual(isp.indent_spaces, 4)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
Fernando Perez
Continue refactoring input handling across clients....
r3085 def test_indent3(self):
# In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 # When a multiline statement contains parens or multiline strings, we
# shouldn't get confused.
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push("if 1:")
isp.push(" x = (1+\n 2)")
self.assertEqual(isp.indent_spaces, 4)
Bernardo B. Marques
remove all trailling spaces
r4872
Paul Ivanov
fix trailing whitespace from reseting indentation
r4204 def test_indent4(self):
# In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
isp = self.isp
# whitespace after ':' should not screw up indent level
isp.push('if 1: \n x=1')
self.assertEqual(isp.indent_spaces, 4)
isp.push('y=2\n')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\t\n x=1')
self.assertEqual(isp.indent_spaces, 4)
isp.push('y=2\n')
self.assertEqual(isp.indent_spaces, 0)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
David Warde-Farley
New tests related to issue #142.
r3693 def test_dedent_pass(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp # shorthand
David Warde-Farley
New tests related to issue #142.
r3693 # should NOT cause dedent
isp.push('if 1:\n passes = 5')
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.assertEqual(isp.indent_spaces, 4)
David Warde-Farley
New tests related to issue #142.
r3693 isp.push('if 1:\n pass')
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.assertEqual(isp.indent_spaces, 0)
David Warde-Farley
New tests related to issue #142.
r3693 isp.push('if 1:\n pass ')
self.assertEqual(isp.indent_spaces, 0)
Aaron Meurer
`yield`, `break`, and `continue` automatically dedent...
r7824 def test_dedent_break(self):
isp = self.isp # shorthand
# should NOT cause dedent
isp.push('while 1:\n breaks = 5')
self.assertEqual(isp.indent_spaces, 4)
isp.push('while 1:\n break')
self.assertEqual(isp.indent_spaces, 0)
isp.push('while 1:\n break ')
self.assertEqual(isp.indent_spaces, 0)
def test_dedent_continue(self):
isp = self.isp # shorthand
# should NOT cause dedent
isp.push('while 1:\n continues = 5')
self.assertEqual(isp.indent_spaces, 4)
isp.push('while 1:\n continue')
self.assertEqual(isp.indent_spaces, 0)
isp.push('while 1:\n continue ')
self.assertEqual(isp.indent_spaces, 0)
David Warde-Farley
New tests related to issue #142.
r3693 def test_dedent_raise(self):
isp = self.isp # shorthand
# should NOT cause dedent
isp.push('if 1:\n raised = 4')
self.assertEqual(isp.indent_spaces, 4)
isp.push('if 1:\n raise TypeError()')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n raise')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n raise ')
self.assertEqual(isp.indent_spaces, 0)
def test_dedent_return(self):
isp = self.isp # shorthand
# should NOT cause dedent
isp.push('if 1:\n returning = 4')
self.assertEqual(isp.indent_spaces, 4)
isp.push('if 1:\n return 5 + 493')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n return')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n return ')
self.assertEqual(isp.indent_spaces, 0)
isp.push('if 1:\n return(0)')
self.assertEqual(isp.indent_spaces, 0)
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 def test_push(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
self.assertTrue(isp.push('x=1'))
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
def test_push2(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
self.assertFalse(isp.push('if 1:'))
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 for line in [' x=1', '# a comment', ' y=2']:
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.assertTrue(isp.push(line))
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add test for inputsplitter bug.
r3747 def test_push3(self):
isp = self.isp
isp.push('if True:')
isp.push(' a = 1')
self.assertFalse(isp.push('b = [1,'))
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add support for append/replace mode after discussion with Evan....
r2634 def test_replace_mode(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
Fernando Perez
Implement support for 'cell' mode with Ctrl-Enter....
r3004 isp.input_mode = 'cell'
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push('x=1')
self.assertEqual(isp.source, 'x=1\n')
isp.push('x=2')
self.assertEqual(isp.source, 'x=2\n')
def test_push_accepts_more(self):
isp = self.isp
isp.push('x=1')
self.assertFalse(isp.push_accepts_more())
def test_push_accepts_more2(self):
Fernando Perez
Continue refactoring input handling across clients....
r3085 # In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
isp.push('if 1:')
self.assertTrue(isp.push_accepts_more())
isp.push(' x=1')
self.assertTrue(isp.push_accepts_more())
isp.push('')
self.assertFalse(isp.push_accepts_more())
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 def test_push_accepts_more3(self):
isp = self.isp
isp.push("x = (2+\n3)")
self.assertFalse(isp.push_accepts_more())
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 def test_push_accepts_more4(self):
Fernando Perez
Continue refactoring input handling across clients....
r3085 # In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
Fernando Perez
Split blockbreaker tests into a separate file and clean up api....
r2633 # When a multiline statement contains parens or multiline strings, we
# shouldn't get confused.
# FIXME: we should be able to better handle de-dents in statements like
# multiline strings and multiline expressions (continued with \ or
# parens). Right now we aren't handling the indentation tracking quite
# correctly with this, though in practice it may not be too much of a
# problem. We'll need to see.
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push("if 1:")
isp.push(" x = (2+")
isp.push(" 3)")
self.assertTrue(isp.push_accepts_more())
isp.push(" y = 3")
self.assertTrue(isp.push_accepts_more())
isp.push('')
self.assertFalse(isp.push_accepts_more())
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Require blank line to end input cell immediately after dedenting....
r3461 def test_push_accepts_more5(self):
# In cell mode, inputs must be fed in whole blocks, so skip this test
if self.isp.input_mode == 'cell': return
isp = self.isp
isp.push('try:')
isp.push(' a = 5')
isp.push('except:')
isp.push(' raise')
self.assertTrue(isp.push_accepts_more())
Fernando Perez
Fix bug with lines ending in continuation markers (\)....
r3013
def test_continuation(self):
isp = self.isp
isp.push("import os, \\")
self.assertTrue(isp.push_accepts_more())
isp.push("sys")
self.assertFalse(isp.push_accepts_more())
Fernando Perez
push() now swallows syntax errors and immediately produces a 'ready'...
r2635
def test_syntax_error(self):
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp = self.isp
Fernando Perez
push() now swallows syntax errors and immediately produces a 'ready'...
r2635 # Syntax errors immediately produce a 'ready' block, so the invalid
# Python can be sent to the kernel for evaluation with possible ipython
# special-syntax conversion.
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 isp.push('run foo')
self.assertFalse(isp.push_accepts_more())
Fernando Perez
Completed full block splitting for block-based frontends.
r2645
Fernando Perez
Stop-gap fix for crash with unicode input....
r3126 def test_unicode(self):
self.isp.push(u"Pérez")
self.isp.push(u'\xc3\xa9')
Thomas Kluyver
Further fixes and tweaks for inputsplitter.
r3455 self.isp.push(u"u'\xc3\xa9'")
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663
Aaron Meurer
Line continuations now terminate after one blank line (#2108)...
r7823 def test_line_continuation(self):
""" Test issue #2108."""
isp = self.isp
# A blank line after a line continuation should not accept more
isp.push("1 \\\n\n")
self.assertFalse(isp.push_accepts_more())
# Whitespace after a \ is a SyntaxError. The only way to test that
# here is to test that push doesn't accept more (as with
# test_syntax_error() above).
isp.push(r"1 \ ")
self.assertFalse(isp.push_accepts_more())
# Even if the line is continuable (c.f. the regular Python
# interpreter)
isp.push(r"(1 \ ")
self.assertFalse(isp.push_accepts_more())
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 class InteractiveLoopTestCase(unittest.TestCase):
"""Tests for an interactive loop like a python shell.
"""
def check_ns(self, lines, ns):
"""Validate that the given input lines produce the resulting namespace.
Note: the input lines are given exactly as they would be typed in an
auto-indenting environment, as mini_interactive_loop above already does
auto-indenting and prepends spaces to the input.
"""
src = mini_interactive_loop(pseudo_input(lines))
test_ns = {}
exec src in test_ns
# We can't check that the provided ns is identical to the test_ns,
# because Python fills test_ns with extra keys (copyright, etc). But
# we can check that the given dict is *contained* in test_ns
Thomas Kluyver
Replacing some .items() calls with .iteritems() for cleaner conversion with 2to3.
r3114 for k,v in ns.iteritems():
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 self.assertEqual(test_ns[k], v)
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 def test_simple(self):
self.check_ns(['x=1'], dict(x=1))
def test_simple2(self):
self.check_ns(['if 1:', 'x=2'], dict(x=2))
def test_xy(self):
self.check_ns(['x=1; y=2'], dict(x=1, y=2))
def test_abc(self):
self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Renamed to inputsplitter, added more tests and examples....
r2663 def test_multi(self):
self.check_ns(['x =(1+','1+','2)'], dict(x=4))
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
First pass of input syntax transformation support
r2719
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 def test_LineInfo():
"""Simple test for LineInfo construction and str()"""
linfo = isp.LineInfo(' %cd /home')
nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
Fernando Perez
First pass of input syntax transformation support
r2719 # Transformer tests
def transform_checker(tests, func):
"""Utility to loop over test inputs"""
for inp, tr in tests:
nt.assert_equals(func(inp), tr)
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
# 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 =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
(u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 ('x=1', 'x=1'), # normal input is unmodified
(' ',' '), # blank lines are kept intact
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
assign_magic =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
(u'b = %who', "b = get_ipython().magic({u}'who')"),
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 ('x=1', 'x=1'), # normal input is unmodified
(' ',' '), # blank lines are kept intact
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
classic_prompt =
[('>>> x=1', 'x=1'),
('x=1', 'x=1'), # normal input is unmodified
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 (' ', ' '), # blank lines are kept intact
('... ', ''), # continuation prompts
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 ],
ipy_prompt =
[('In [1]: x=1', 'x=1'),
('x=1', 'x=1'), # normal input is unmodified
(' ',' '), # blank lines are kept intact
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 (' ....: ', ''), # continuation prompts
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 ],
# Tests for the escape transformer to leave normal code alone
escaped_noesc =
[ (' ', ' '),
('x=1', 'x=1'),
],
# System calls
escaped_shell =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [ (u'!ls', "get_ipython().system({u}'ls')"),
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 # Double-escape shell, this means to capture the output of the
# subprocess and return it
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
# Help/object info
escaped_help =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [ (u'?', 'get_ipython().show_usage()'),
(u'?x1', "get_ipython().magic({u}'pinfo x1')"),
(u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
(u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
Fernando Perez
Fix handling of lines like '%%foo?' in cell magic logic.
r6999 (u'?%hist1', "get_ipython().magic({u}'pinfo %hist1')"),
(u'?%%hist2', "get_ipython().magic({u}'pinfo %%hist2')"),
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Allow getting help mid-way through a command (e.g. a = abc.def?).
r4076 end_help =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
(u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
Fernando Perez
Fix handling of lines like '%%foo?' in cell magic logic.
r6999 (u'%hist1?', "get_ipython().magic({u}'pinfo %hist1')"),
(u'%hist2??', "get_ipython().magic({u}'pinfo2 %hist2')"),
(u'%%hist3?', "get_ipython().magic({u}'pinfo %%hist3')"),
(u'%%hist4??', "get_ipython().magic({u}'pinfo2 %%hist4')"),
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
(u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
Fernando Perez
Remove next_input nonsense in magic calls (but keep functionality).
r6974 (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
"get_ipython().magic({u}'pinfo abc')"),
(u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
"get_ipython().magic({u}'pinfo2 abc.qe')"),
(u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
"get_ipython().magic({u}'psearch *.items')"),
(u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
"get_ipython().magic({u}'pinfo a')"),
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 (u'a*2 #comment?', 'a*2 #comment?'),
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
# Explicit magic calls
escaped_magic =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [ (u'%cd', "get_ipython().magic({u}'cd')"),
(u'%cd /home', "get_ipython().magic({u}'cd /home')"),
# Backslashes need to be escaped.
(u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
(u' %magic', " get_ipython().magic({u}'magic')"),
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 # Quoting with separate arguments
escaped_quote =
[ (',f', 'f("")'),
(',f x', 'f("x")'),
(' ,f y', ' f("y")'),
(',f a b', 'f("a", "b")'),
],
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 # Quoting with single argument
Bernardo B. Marques
remove all trailling spaces
r4872 escaped_quote2 =
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 [ (';f', 'f("")'),
(';f x', 'f("x")'),
(' ;f y', ' f("y")'),
(';f a b', 'f("a b")'),
],
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 # Simply apply parens
Bernardo B. Marques
remove all trailling spaces
r4872 escaped_paren =
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 [ ('/f', 'f()'),
('/f x', 'f(x)'),
(' /f y', ' f(y)'),
('/f a b', 'f(a, b)'),
],
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Reorder inputsplitter transformers so that prompts pasted into the input are removed before other transforms are applied.
r4078 # Check that we transform prompts before other transforms
mixed =
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 [(i,py3compat.u_format(o)) for i,o in \
Thomas Kluyver
Use standard repr() instead of our own make_quoted_expr().
r5350 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
(u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
(u'In [2]: !ls', "get_ipython().system({u}'ls')"),
(u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
(u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
Thomas Kluyver
Fix various tests in IPython.core for Python 3.
r4895 ]],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 )
# multiline syntax examples. Each of these should be a list of lists, with
# each entry itself having pairs of raw/transformed input. The union (with
# '\n'.join() of the transformed inputs is what the splitter should produce
# when fed the raw lines one at a time via push.
syntax_ml = \
dict(classic_prompt =
[ [('>>> for i in range(10):','for i in range(10):'),
('... print i',' print i'),
('... ', ''),
],
],
ipy_prompt =
[ [('In [24]: for i in range(10):','for i in range(10):'),
(' ....: print i',' print i'),
(' ....: ', ''),
],
],
Daniel Velkov
added test for issue #678
r5088
multiline_datastructure =
[ [('>>> a = [1,','a = [1,'),
('... 2]','2]'),
],
],
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 )
Fernando Perez
First pass of input syntax transformation support
r2719
def test_assign_system():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
Fernando Perez
First pass of input syntax transformation support
r2719
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
First pass of input syntax transformation support
r2719 def test_assign_magic():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
Fernando Perez
First pass of input syntax transformation support
r2719
def test_classic_prompt():
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
for example in syntax_ml['classic_prompt']:
transform_checker(example, isp.transform_classic_prompt)
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
First pass of input syntax transformation support
r2719
def test_ipy_prompt():
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
for example in syntax_ml['ipy_prompt']:
transform_checker(example, isp.transform_ipy_prompt)
Thomas Kluyver
Allow getting help mid-way through a command (e.g. a = abc.def?).
r4076
def test_end_help():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_noesc():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_shell():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_help():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_magic():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_quote():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_quote2():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_escaped_paren():
Thomas Kluyver
Return command to the next prompt if help was called halfway through a command. Also, ? at the end of a comment should not trigger help.
r4080 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
class IPythonInputTestCase(InputSplitterTestCase):
"""By just creating a new class whose .isp is a different instance, we
re-run the same test battery on the new input splitter.
In addition, this runs the tests over the syntax and syntax_ml dicts that
were tested by individual functions, as part of the OO interface.
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080
It also makes some checks on the raw buffer storage.
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 """
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 def setUp(self):
Fernando Perez
Rename input modes of input splitter to 'line' and 'block'....
r2862 self.isp = isp.IPythonInputSplitter(input_mode='line')
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
def test_syntax(self):
"""Call all single-line syntax tests from the main object"""
isp = self.isp
for example in syntax.itervalues():
for raw, out_t in example:
if raw.startswith(' '):
continue
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fix '%%cellm?' case, make tests more stringent to catch error.
r7000 isp.push(raw+'\n')
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 out, out_raw = isp.source_raw_reset()
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 self.assertEqual(out.rstrip(), out_t,
tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 self.assertEqual(out_raw.rstrip(), raw.rstrip())
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 def test_syntax_multiline(self):
isp = self.isp
for example in syntax_ml.itervalues():
out_t_parts = []
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 raw_parts = []
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 for line_pairs in example:
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 for lraw, out_t_part in line_pairs:
isp.push(lraw)
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 out_t_parts.append(out_t_part)
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 raw_parts.append(lraw)
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 out, out_raw = isp.source_raw_reset()
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 out_t = '\n'.join(out_t_parts).rstrip()
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 raw = '\n'.join(raw_parts).rstrip()
self.assertEqual(out.rstrip(), out_t)
self.assertEqual(out_raw.rstrip(), raw)
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861
class BlockIPythonInputTestCase(IPythonInputTestCase):
# Deactivate tests that don't make sense for the block mode
test_push3 = test_split = lambda s: None
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 def setUp(self):
Fernando Perez
Implement support for 'cell' mode with Ctrl-Enter....
r3004 self.isp = isp.IPythonInputSplitter(input_mode='cell')
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861
def test_syntax_multiline(self):
isp = self.isp
for example in syntax_ml.itervalues():
raw_parts = []
out_t_parts = []
for line_pairs in example:
for raw, out_t_part in line_pairs:
raw_parts.append(raw)
out_t_parts.append(out_t_part)
raw = '\n'.join(raw_parts)
out_t = '\n'.join(out_t_parts)
isp.push(raw)
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 out, out_raw = isp.source_raw_reset()
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 # Match ignoring trailing whitespace
self.assertEqual(out.rstrip(), out_t.rstrip())
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 self.assertEqual(out_raw.rstrip(), raw.rstrip())
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Add tests for new method.
r7488 def test_syntax_multiline_cell(self):
isp = self.isp
for example in syntax_ml.itervalues():
Aaron Meurer
Line continuations now terminate after one blank line (#2108)...
r7823
Fernando Perez
Add tests for new method.
r7488 out_t_parts = []
for line_pairs in example:
raw = '\n'.join(r for r, _ in line_pairs)
out_t = '\n'.join(t for _,t in line_pairs)
out = isp.transform_cell(raw)
# Match ignoring trailing whitespace
self.assertEqual(out.rstrip(), out_t.rstrip())
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 #-----------------------------------------------------------------------------
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 # Main - use as a script, mostly for developer experiments
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 #-----------------------------------------------------------------------------
if __name__ == '__main__':
# A simple demo for interactive experimentation. This code will not get
Fernando Perez
Fix bug with IPythonInputSplitter in block input mode.
r2861 # picked up by any test suite.
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
Fernando Perez
Final cleanups responding to Brian's code review....
r2782
# configure here the syntax to use, prompt and whether to autoindent
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 #isp, start_prompt = InputSplitter(), '>>> '
isp, start_prompt = IPythonInputSplitter(), 'In> '
autoindent = True
#autoindent = False
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 try:
while True:
prompt = start_prompt
while isp.push_accepts_more():
indent = ' '*isp.indent_spaces
if autoindent:
line = indent + raw_input(prompt+indent)
else:
line = raw_input(prompt)
isp.push(line)
prompt = '... '
# Here we just return input so we can use it in a test suite, but a
# real interpreter would instead send it for execution somewhere.
Fernando Perez
Final documentation changes from code review with Brian, ready to merge.
r2828 #src = isp.source; raise EOFError # dbg
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 src, raw = isp.source_raw_reset()
Fernando Perez
Final cleanups responding to Brian's code review....
r2782 print 'Input source was:\n', src
Fernando Perez
Add support for accessing raw data to inputsplitter....
r3080 print 'Raw source was:\n', raw
Fernando Perez
Completed first pass of inputsplitter with IPython syntax....
r2780 except EOFError:
print 'Bye'
Fernando Perez
Clean up implementation of cell magics in inputsplitter....
r6985
# Tests for cell magics support
def test_last_blank():
nt.assert_false(isp.last_blank(''))
nt.assert_false(isp.last_blank('abc'))
nt.assert_false(isp.last_blank('abc\n'))
nt.assert_false(isp.last_blank('abc\na'))
nt.assert_true(isp.last_blank('\n'))
nt.assert_true(isp.last_blank('\n '))
nt.assert_true(isp.last_blank('abc\n '))
nt.assert_true(isp.last_blank('abc\n\n'))
nt.assert_true(isp.last_blank('abc\nd\n\n'))
nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
nt.assert_true(isp.last_blank('abc \n \n \n\n'))
def test_last_two_blanks():
nt.assert_false(isp.last_two_blanks(''))
nt.assert_false(isp.last_two_blanks('abc'))
nt.assert_false(isp.last_two_blanks('abc\n'))
nt.assert_false(isp.last_two_blanks('abc\n\na'))
nt.assert_false(isp.last_two_blanks('abc\n \n'))
nt.assert_false(isp.last_two_blanks('abc\n\n'))
nt.assert_true(isp.last_two_blanks('\n\n'))
nt.assert_true(isp.last_two_blanks('\n\n '))
nt.assert_true(isp.last_two_blanks('\n \n'))
nt.assert_true(isp.last_two_blanks('abc\n\n '))
nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
Fernando Perez
Fix test failures under Python 3....
r7004 class CellMagicsCommon(object):
Aaron Meurer
Line continuations now terminate after one blank line (#2108)...
r7823
Fernando Perez
Clean up implementation of cell magics in inputsplitter....
r6985 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
Fernando Perez
Fix test failures under Python 3....
r7004 ref = u"get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n"
nt.assert_equal(out, py3compat.u_format(ref))
def tearDown(self):
self.sp.reset()
class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
sp = isp.IPythonInputSplitter(input_mode='cell')
Fernando Perez
Clean up implementation of cell magics in inputsplitter....
r6985
def test_incremental(self):
sp = self.sp
src = '%%cellm line2\n'
sp.push(src)
nt.assert_true(sp.push_accepts_more()) #1
src += '\n'
sp.push(src)
# Note: if we ever change the logic to allow full blank lines (see
# _handle_cell_magic), then the following test should change to true
nt.assert_false(sp.push_accepts_more()) #2
# By now, even with full blanks allowed, a second blank should signal
# the end. For now this test is only a redundancy safety, but don't
# delete it in case we change our mind and the previous one goes to
# true.
src += '\n'
sp.push(src)
nt.assert_false(sp.push_accepts_more()) #3
Fernando Perez
Fix test failures under Python 3....
r7004 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
Fernando Perez
Clean up implementation of cell magics in inputsplitter....
r6985 sp = isp.IPythonInputSplitter(input_mode='line')
def test_incremental(self):
sp = self.sp
sp.push('%%cellm line2\n')
nt.assert_true(sp.push_accepts_more()) #1
sp.push('\n')
nt.assert_false(sp.push_accepts_more()) #2