##// END OF EJS Templates
Merge branch 'rising-intonation'
Thomas Kluyver -
r4085:665bef43 merge
parent child Browse files
Show More
@@ -70,6 +70,8 b' import ast'
70 import codeop
70 import codeop
71 import re
71 import re
72 import sys
72 import sys
73 import tokenize
74 from StringIO import StringIO
73
75
74 # IPython modules
76 # IPython modules
75 from IPython.utils.text import make_quoted_expr
77 from IPython.utils.text import make_quoted_expr
@@ -155,6 +157,24 b' def remove_comments(src):'
155 """
157 """
156
158
157 return re.sub('#.*', '', src)
159 return re.sub('#.*', '', src)
160
161 def has_comment(src):
162 """Indicate whether an input line has (i.e. ends in, or is) a comment.
163
164 This uses tokenize, so it can distinguish comments from # inside strings.
165
166 Parameters
167 ----------
168 src : string
169 A single line input string.
170
171 Returns
172 -------
173 Boolean: True if source has a comment.
174 """
175 readline = StringIO(src).readline
176 toktypes = set(t[0] for t in tokenize.generate_tokens(readline))
177 return(tokenize.COMMENT in toktypes)
158
178
159
179
160 def get_input_encoding():
180 def get_input_encoding():
@@ -173,20 +193,14 b' def get_input_encoding():'
173 #-----------------------------------------------------------------------------
193 #-----------------------------------------------------------------------------
174
194
175 class InputSplitter(object):
195 class InputSplitter(object):
176 """An object that can split Python source input in executable blocks.
196 """An object that can accumulate lines of Python source before execution.
177
178 This object is designed to be used in one of two basic modes:
179
197
180 1. By feeding it python source line-by-line, using :meth:`push`. In this
198 This object is designed to be fed python source line-by-line, using
181 mode, it will return on each push whether the currently pushed code
199 :meth:`push`. It will return on each push whether the currently pushed
182 could be executed already. In addition, it provides a method called
200 code could be executed already. In addition, it provides a method called
183 :meth:`push_accepts_more` that can be used to query whether more input
201 :meth:`push_accepts_more` that can be used to query whether more input
184 can be pushed into a single interactive block.
202 can be pushed into a single interactive block.
185
203
186 2. By calling :meth:`split_blocks` with a single, multiline Python string,
187 that is then split into blocks each of which can be executed
188 interactively as a single statement.
189
190 This is a simple example of how an interactive terminal-based client can use
204 This is a simple example of how an interactive terminal-based client can use
191 this tool::
205 this tool::
192
206
@@ -347,9 +361,6 b' class InputSplitter(object):'
347 *line-oriented* frontends, since it means that intermediate blank lines
361 *line-oriented* frontends, since it means that intermediate blank lines
348 are not allowed in function definitions (or any other indented block).
362 are not allowed in function definitions (or any other indented block).
349
363
350 Block-oriented frontends that have a separate keyboard event to
351 indicate execution should use the :meth:`split_blocks` method instead.
352
353 If the current input produces a syntax error, this method immediately
364 If the current input produces a syntax error, this method immediately
354 returns False but does *not* raise the syntax error exception, as
365 returns False but does *not* raise the syntax error exception, as
355 typically clients will want to send invalid syntax to an execution
366 typically clients will want to send invalid syntax to an execution
@@ -658,6 +669,42 b' def transform_ipy_prompt(line):'
658 return line
669 return line
659
670
660
671
672 def _make_help_call(target, esc, lspace, next_input=None):
673 """Prepares a pinfo(2)/psearch call from a target name and the escape
674 (i.e. ? or ??)"""
675 method = 'pinfo2' if esc == '??' \
676 else 'psearch' if '*' in target \
677 else 'pinfo'
678
679 if next_input:
680 tpl = '%sget_ipython().magic(u"%s %s", next_input=%s)'
681 return tpl % (lspace, method, target, make_quoted_expr(next_input))
682 else:
683 return '%sget_ipython().magic(u"%s %s")' % (lspace, method, target)
684
685 _initial_space_re = re.compile(r'\s*')
686 _help_end_re = re.compile(r"""(%?
687 [a-zA-Z_*][a-zA-Z0-9_*]* # Variable name
688 (\.[a-zA-Z_*][a-zA-Z0-9_*]*)* # .etc.etc
689 )
690 (\?\??)$ # ? or ??""",
691 re.VERBOSE)
692 def transform_help_end(line):
693 """Translate lines with ?/?? at the end"""
694 m = _help_end_re.search(line)
695 if m is None or has_comment(line):
696 return line
697 target = m.group(1)
698 esc = m.group(3)
699 lspace = _initial_space_re.match(line).group(0)
700 newline = _make_help_call(target, esc, lspace)
701
702 # If we're mid-command, put it back on the next prompt for the user.
703 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
704
705 return _make_help_call(target, esc, lspace, next_input)
706
707
661 class EscapedTransformer(object):
708 class EscapedTransformer(object):
662 """Class to transform lines that are explicitly escaped out."""
709 """Class to transform lines that are explicitly escaped out."""
663
710
@@ -694,28 +741,8 b' class EscapedTransformer(object):'
694 # A naked help line should just fire the intro help screen
741 # A naked help line should just fire the intro help screen
695 if not line_info.line[1:]:
742 if not line_info.line[1:]:
696 return 'get_ipython().show_usage()'
743 return 'get_ipython().show_usage()'
697
744
698 # There may be one or two '?' at the end, move them to the front so that
745 return _make_help_call(line_info.fpart, line_info.esc, line_info.lspace)
699 # the rest of the logic can assume escapes are at the start
700 l_ori = line_info
701 line = line_info.line
702 if line.endswith('?'):
703 line = line[-1] + line[:-1]
704 if line.endswith('?'):
705 line = line[-1] + line[:-1]
706 line_info = LineInfo(line)
707
708 # From here on, simply choose which level of detail to get, and
709 # special-case the psearch syntax
710 pinfo = 'pinfo' # default
711 if '*' in line_info.line:
712 pinfo = 'psearch'
713 elif line_info.esc == '??':
714 pinfo = 'pinfo2'
715
716 tpl = '%sget_ipython().magic(u"%s %s")'
717 return tpl % (line_info.lspace, pinfo,
718 ' '.join([line_info.fpart, line_info.rest]).strip())
719
746
720 @staticmethod
747 @staticmethod
721 def _tr_magic(line_info):
748 def _tr_magic(line_info):
@@ -756,14 +783,9 b' class EscapedTransformer(object):'
756 # Get line endpoints, where the escapes can be
783 # Get line endpoints, where the escapes can be
757 line_info = LineInfo(line)
784 line_info = LineInfo(line)
758
785
759 # If the escape is not at the start, only '?' needs to be special-cased.
760 # All other escapes are only valid at the start
761 if not line_info.esc in self.tr:
786 if not line_info.esc in self.tr:
762 if line.endswith(ESC_HELP):
787 # If we don't recognize the escape, don't modify the line
763 return self._tr_help(line_info)
788 return line
764 else:
765 # If we don't recognize the escape, don't modify the line
766 return line
767
789
768 return self.tr[line_info.esc](line_info)
790 return self.tr[line_info.esc](line_info)
769
791
@@ -815,9 +837,9 b' class IPythonInputSplitter(InputSplitter):'
815
837
816 lines_list = lines.splitlines()
838 lines_list = lines.splitlines()
817
839
818 transforms = [transform_escaped, transform_assign_system,
840 transforms = [transform_ipy_prompt, transform_classic_prompt,
819 transform_assign_magic, transform_ipy_prompt,
841 transform_escaped, transform_help_end,
820 transform_classic_prompt]
842 transform_assign_system, transform_assign_magic]
821
843
822 # Transform logic
844 # Transform logic
823 #
845 #
@@ -1703,7 +1703,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1703 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1703 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1704 [D:\ipython]|2> Hello Word_ # cursor is here
1704 [D:\ipython]|2> Hello Word_ # cursor is here
1705 """
1705 """
1706
1706 if isinstance(s, unicode):
1707 s = s.encode(self.stdin_encoding, 'replace')
1707 self.rl_next_input = s
1708 self.rl_next_input = s
1708
1709
1709 # Maybe move this to the terminal subclass?
1710 # Maybe move this to the terminal subclass?
@@ -1841,7 +1842,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1841 from . import history
1842 from . import history
1842 history.init_ipython(self)
1843 history.init_ipython(self)
1843
1844
1844 def magic(self,arg_s):
1845 def magic(self, arg_s, next_input=None):
1845 """Call a magic function by name.
1846 """Call a magic function by name.
1846
1847
1847 Input: a string containing the name of the magic function to call and
1848 Input: a string containing the name of the magic function to call and
@@ -1858,6 +1859,11 b' class InteractiveShell(SingletonConfigurable, Magic):'
1858 valid Python code you can type at the interpreter, including loops and
1859 valid Python code you can type at the interpreter, including loops and
1859 compound statements.
1860 compound statements.
1860 """
1861 """
1862 # Allow setting the next input - this is used if the user does `a=abs?`.
1863 # We do this first so that magic functions can override it.
1864 if next_input:
1865 self.set_next_input(next_input)
1866
1861 args = arg_s.split(' ',1)
1867 args = arg_s.split(' ',1)
1862 magic_name = args[0]
1868 magic_name = args[0]
1863 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1869 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
@@ -25,6 +25,7 b' import nose.tools as nt'
25
25
26 # Our own
26 # Our own
27 from IPython.core import inputsplitter as isp
27 from IPython.core import inputsplitter as isp
28 from IPython.testing import tools as tt
28
29
29 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
30 # Semi-complete examples (also used as tests)
31 # Semi-complete examples (also used as tests)
@@ -92,9 +93,7 b' def test_spaces():'
92 ('\tx', 1),
93 ('\tx', 1),
93 ('\t x', 2),
94 ('\t x', 2),
94 ]
95 ]
95
96 tt.check_pairs(isp.num_ini_spaces, tests)
96 for s, nsp in tests:
97 nt.assert_equal(isp.num_ini_spaces(s), nsp)
98
97
99
98
100 def test_remove_comments():
99 def test_remove_comments():
@@ -106,9 +105,19 b' def test_remove_comments():'
106 ('line # c \nline#c2 \nline\nline #c\n\n',
105 ('line # c \nline#c2 \nline\nline #c\n\n',
107 'line \nline\nline\nline \n\n'),
106 'line \nline\nline\nline \n\n'),
108 ]
107 ]
109
108 tt.check_pairs(isp.remove_comments, tests)
110 for inp, out in tests:
109
111 nt.assert_equal(isp.remove_comments(inp), out)
110 def test_has_comment():
111 tests = [('text', False),
112 ('text #comment', True),
113 ('text #comment\n', True),
114 ('#comment', True),
115 ('#comment\n', True),
116 ('a = "#string"', False),
117 ('a = "#string" # comment', True),
118 ('a #comment not "string"', True),
119 ]
120 tt.check_pairs(isp.has_comment, tests)
112
121
113
122
114 def test_get_input_encoding():
123 def test_get_input_encoding():
@@ -434,12 +443,22 b' syntax = \\'
434 [ ('?', 'get_ipython().show_usage()'),
443 [ ('?', 'get_ipython().show_usage()'),
435 ('?x1', 'get_ipython().magic(u"pinfo x1")'),
444 ('?x1', 'get_ipython().magic(u"pinfo x1")'),
436 ('??x2', 'get_ipython().magic(u"pinfo2 x2")'),
445 ('??x2', 'get_ipython().magic(u"pinfo2 x2")'),
437 ('x3?', 'get_ipython().magic(u"pinfo x3")'),
446 ('?a.*s', 'get_ipython().magic(u"psearch a.*s")'),
438 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
447 ('?%hist', 'get_ipython().magic(u"pinfo %hist")'),
439 ('%hist?', 'get_ipython().magic(u"pinfo %hist")'),
448 ('?abc = qwe', 'get_ipython().magic(u"pinfo abc")'),
440 ('f*?', 'get_ipython().magic(u"psearch f*")'),
441 ('ax.*aspe*?', 'get_ipython().magic(u"psearch ax.*aspe*")'),
442 ],
449 ],
450
451 end_help =
452 [ ('x3?', 'get_ipython().magic(u"pinfo x3")'),
453 ('x4??', 'get_ipython().magic(u"pinfo2 x4")'),
454 ('%hist?', 'get_ipython().magic(u"pinfo %hist")'),
455 ('f*?', 'get_ipython().magic(u"psearch f*")'),
456 ('ax.*aspe*?', 'get_ipython().magic(u"psearch ax.*aspe*")'),
457 ('a = abc?', 'get_ipython().magic(u"pinfo abc", next_input=u"a = abc")'),
458 ('a = abc.qe??', 'get_ipython().magic(u"pinfo2 abc.qe", next_input=u"a = abc.qe")'),
459 ('a = *.items?', 'get_ipython().magic(u"psearch *.items", next_input=u"a = *.items")'),
460 ('a*2 #comment?', 'a*2 #comment?'),
461 ],
443
462
444 # Explicit magic calls
463 # Explicit magic calls
445 escaped_magic =
464 escaped_magic =
@@ -471,7 +490,15 b' syntax = \\'
471 (' /f y', ' f(y)'),
490 (' /f y', ' f(y)'),
472 ('/f a b', 'f(a, b)'),
491 ('/f a b', 'f(a, b)'),
473 ],
492 ],
474
493
494 # Check that we transform prompts before other transforms
495 mixed =
496 [ ('In [1]: %lsmagic', 'get_ipython().magic(u"lsmagic")'),
497 ('>>> %lsmagic', 'get_ipython().magic(u"lsmagic")'),
498 ('In [2]: !ls', 'get_ipython().system(u"ls")'),
499 ('In [3]: abs?', 'get_ipython().magic(u"pinfo abs")'),
500 ('In [4]: b = %who', 'b = get_ipython().magic(u"who")'),
501 ],
475 )
502 )
476
503
477 # multiline syntax examples. Each of these should be a list of lists, with
504 # multiline syntax examples. Each of these should be a list of lists, with
@@ -496,11 +523,11 b' syntax_ml = \\'
496
523
497
524
498 def test_assign_system():
525 def test_assign_system():
499 transform_checker(syntax['assign_system'], isp.transform_assign_system)
526 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
500
527
501
528
502 def test_assign_magic():
529 def test_assign_magic():
503 transform_checker(syntax['assign_magic'], isp.transform_assign_magic)
530 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
504
531
505
532
506 def test_classic_prompt():
533 def test_classic_prompt():
@@ -513,34 +540,36 b' def test_ipy_prompt():'
513 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
540 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
514 for example in syntax_ml['ipy_prompt']:
541 for example in syntax_ml['ipy_prompt']:
515 transform_checker(example, isp.transform_ipy_prompt)
542 transform_checker(example, isp.transform_ipy_prompt)
516
543
544 def test_end_help():
545 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
517
546
518 def test_escaped_noesc():
547 def test_escaped_noesc():
519 transform_checker(syntax['escaped_noesc'], isp.transform_escaped)
548 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
520
549
521
550
522 def test_escaped_shell():
551 def test_escaped_shell():
523 transform_checker(syntax['escaped_shell'], isp.transform_escaped)
552 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
524
553
525
554
526 def test_escaped_help():
555 def test_escaped_help():
527 transform_checker(syntax['escaped_help'], isp.transform_escaped)
556 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
528
557
529
558
530 def test_escaped_magic():
559 def test_escaped_magic():
531 transform_checker(syntax['escaped_magic'], isp.transform_escaped)
560 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
532
561
533
562
534 def test_escaped_quote():
563 def test_escaped_quote():
535 transform_checker(syntax['escaped_quote'], isp.transform_escaped)
564 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
536
565
537
566
538 def test_escaped_quote2():
567 def test_escaped_quote2():
539 transform_checker(syntax['escaped_quote2'], isp.transform_escaped)
568 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
540
569
541
570
542 def test_escaped_paren():
571 def test_escaped_paren():
543 transform_checker(syntax['escaped_paren'], isp.transform_escaped)
572 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
544
573
545
574
546 class IPythonInputTestCase(InputSplitterTestCase):
575 class IPythonInputTestCase(InputSplitterTestCase):
@@ -281,3 +281,29 b' class TempFileMixin(object):'
281 # delete it. I have no clue why
281 # delete it. I have no clue why
282 pass
282 pass
283
283
284 pair_fail_msg = ("Testing function {0}\n\n"
285 "In:\n"
286 " {1!r}\n"
287 "Expected:\n"
288 " {2!r}\n"
289 "Got:\n"
290 " {3!r}\n")
291 def check_pairs(func, pairs):
292 """Utility function for the common case of checking a function with a
293 sequence of input/output pairs.
294
295 Parameters
296 ----------
297 func : callable
298 The function to be tested. Should accept a single argument.
299 pairs : iterable
300 A list of (input, expected_output) tuples.
301
302 Returns
303 -------
304 None. Raises an AssertionError if any output does not match the expected
305 value.
306 """
307 for inp, expected in pairs:
308 out = func(inp)
309 assert out == expected, pair_fail_msg.format(func.func_name, inp, expected, out)
@@ -33,7 +33,7 b' ZMQ architecture'
33 There is a new GUI framework for IPython, based on a client-server model in
33 There is a new GUI framework for IPython, based on a client-server model in
34 which multiple clients can communicate with one IPython kernel, using the
34 which multiple clients can communicate with one IPython kernel, using the
35 ZeroMQ messaging framework. There is already a Qt console client, which can
35 ZeroMQ messaging framework. There is already a Qt console client, which can
36 be started by calling ``ipython-qtconsole``. The protocol is :ref:`documented
36 be started by calling ``ipython qtconsole``. The protocol is :ref:`documented
37 <messaging>`.
37 <messaging>`.
38
38
39 The parallel computing framework has also been rewritten using ZMQ. The
39 The parallel computing framework has also been rewritten using ZMQ. The
@@ -43,6 +43,10 b' new :mod:`IPython.parallel` module.'
43 New features
43 New features
44 ------------
44 ------------
45
45
46 * You can now get help on an object halfway through typing a command. For
47 instance, typing ``a = zip?`` shows the details of :func:`zip`. It also
48 leaves the command at the next prompt so you can carry on with it.
49
46 * The input history is now written to an SQLite database. The API for
50 * The input history is now written to an SQLite database. The API for
47 retrieving items from the history has also been redesigned.
51 retrieving items from the history has also been redesigned.
48
52
@@ -63,7 +67,7 b' New features'
63
67
64 * The methods of :class:`~IPython.core.iplib.InteractiveShell` have
68 * The methods of :class:`~IPython.core.iplib.InteractiveShell` have
65 been organized into sections to make it easier to turn more sections
69 been organized into sections to make it easier to turn more sections
66 of functionality into componenets.
70 of functionality into components.
67
71
68 * The embedded shell has been refactored into a truly standalone subclass of
72 * The embedded shell has been refactored into a truly standalone subclass of
69 :class:`InteractiveShell` called :class:`InteractiveShellEmbed`. All
73 :class:`InteractiveShell` called :class:`InteractiveShellEmbed`. All
General Comments 0
You need to be logged in to leave comments. Login now