##// END OF EJS Templates
Improvements in the code that breaks up user input.
Thomas Kluyver -
Show More
@@ -38,7 +38,7 b' from IPython.utils.warn import warn, error'
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # This is used as the pattern for calls to split_user_input.
41 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
41 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
42 42
43 43 def default_aliases():
44 44 """Return list of shell aliases to auto-define.
@@ -222,7 +222,7 b' class AliasManager(Configurable):'
222 222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
223 223 """
224 224
225 pre,fn,rest = split_user_input(line)
225 pre,_,fn,rest = split_user_input(line)
226 226 res = pre + self.expand_aliases(fn, rest)
227 227 return res
228 228
@@ -242,7 +242,7 b' class AliasManager(Configurable):'
242 242
243 243 done = set()
244 244 while 1:
245 pre,fn,rest = split_user_input(line, shell_line_split)
245 pre,_,fn,rest = split_user_input(line, shell_line_split)
246 246 if fn in self.alias_table:
247 247 if fn in done:
248 248 warn("Cyclic alias definition, repeated '%s'" % fn)
@@ -24,12 +24,16 b' import os'
24 24 import sys
25 25 import types
26 26 from collections import namedtuple
27 from itertools import izip_longest
27 try:
28 from itertools import izip_longest
29 except ImportError:
30 from itertools import zip_longest as izip_longest
28 31
29 32 # IPython's own
30 33 from IPython.core import page
31 34 from IPython.utils import PyColorize
32 35 from IPython.utils import io
36 from IPython.utils import py3compat
33 37 from IPython.utils.text import indent
34 38 from IPython.utils.wildcard import list_namespace
35 39 from IPython.utils.coloransi import *
@@ -249,7 +253,7 b' class Inspector:'
249 253 try:
250 254 # We need a plain string here, NOT unicode!
251 255 hdef = oname + inspect.formatargspec(*getargspec(obj))
252 return hdef.encode('ascii')
256 return py3compat.unicode_to_str(hdef.encode('ascii'))
253 257 except:
254 258 return None
255 259
@@ -362,7 +366,7 b' class Inspector:'
362 366 except:
363 367 self.noinfo('source',oname)
364 368 else:
365 page.page(self.format(src))
369 page.page(self.format(py3compat.unicode_to_str(src)))
366 370
367 371 def pfile(self,obj,oname=''):
368 372 """Show the whole file where an object was defined."""
@@ -131,7 +131,7 b' class LineInfo(object):'
131 131 def __init__(self, line, continue_prompt):
132 132 self.line = line
133 133 self.continue_prompt = continue_prompt
134 self.pre, self.ifun, self.the_rest = split_user_input(line)
134 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
135 135
136 136 self.pre_char = self.pre.strip()
137 137 if self.pre_char:
@@ -630,7 +630,7 b' class MultiLineMagicChecker(PrefilterChecker):'
630 630 # both ! and !!.
631 631 if line_info.continue_prompt \
632 632 and self.prefilter_manager.multi_line_specials:
633 if line_info.ifun.startswith(ESC_MAGIC):
633 if line_info.esc == ESC_MAGIC:
634 634 return self.prefilter_manager.get_handler_by_name('magic')
635 635 else:
636 636 return None
@@ -644,14 +644,16 b' class EscCharsChecker(PrefilterChecker):'
644 644 """Check for escape character and return either a handler to handle it,
645 645 or None if there is no escape char."""
646 646 if line_info.line[-1] == ESC_HELP \
647 and line_info.pre_char != ESC_SHELL \
648 and line_info.pre_char != ESC_SH_CAP:
647 and line_info.esc != ESC_SHELL \
648 and line_info.esc != ESC_SH_CAP:
649 649 # the ? can be at the end, but *not* for either kind of shell escape,
650 650 # because a ? can be a vaild final char in a shell cmd
651 651 return self.prefilter_manager.get_handler_by_name('help')
652 652 else:
653 if line_info.pre:
654 return None
653 655 # This returns None like it should if no handler exists
654 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
656 return self.prefilter_manager.get_handler_by_esc(line_info.esc)
655 657
656 658
657 659 class AssignmentChecker(PrefilterChecker):
@@ -872,6 +874,7 b' class AutoHandler(PrefilterHandler):'
872 874 ifun = line_info.ifun
873 875 the_rest = line_info.the_rest
874 876 pre = line_info.pre
877 esc = line_info.esc
875 878 continue_prompt = line_info.continue_prompt
876 879 obj = line_info.ofind(self)['obj']
877 880 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
@@ -883,13 +886,13 b' class AutoHandler(PrefilterHandler):'
883 886 force_auto = isinstance(obj, IPyAutocall)
884 887 auto_rewrite = getattr(obj, 'rewrite', True)
885 888
886 if pre == ESC_QUOTE:
889 if esc == ESC_QUOTE:
887 890 # Auto-quote splitting on whitespace
888 891 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
889 elif pre == ESC_QUOTE2:
892 elif esc == ESC_QUOTE2:
890 893 # Auto-quote whole string
891 894 newcmd = '%s("%s")' % (ifun,the_rest)
892 elif pre == ESC_PAREN:
895 elif esc == ESC_PAREN:
893 896 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
894 897 else:
895 898 # Auto-paren.
@@ -946,7 +949,7 b' class HelpHandler(PrefilterHandler):'
946 949 line = line[:-1]
947 950 if line:
948 951 #print 'line:<%r>' % line # dbg
949 self.shell.magic_pinfo(line)
952 self.shell.magic_pinfo(line_info.ifun)
950 953 else:
951 954 self.shell.show_usage()
952 955 return '' # Empty string is needed here!
@@ -40,13 +40,15 b' from IPython.utils import py3compat'
40 40 # ! and !! trigger if they are first char(s) *or* follow an indent
41 41 # ? triggers as first or last char.
42 42
43 # The three parts of the regex are:
44 # 1) pre: pre_char *or* initial whitespace
45 # 2) ifun: first word/method (mix of \w and '.')
46 # 3) the_rest: rest of line (separated from ifun by space if non-empty)
47 line_split = re.compile(r'^([,;/%?]|!!?|\s*)'
43 # The four parts of the regex are:
44 # 1) pre: initial whitespace
45 # 2) esc: escape character
46 # 3) ifun: first word/method (mix of \w and '.')
47 # 4) the_rest: rest of line (separated from ifun by space if non-empty)
48 line_split = re.compile(r'^(\s*)'
49 r'([,;/%?]|!!?)?'
48 50 r'\s*([\w\.]+)'
49 r'(\s+.*$|$)')
51 r'(.*$|$)')
50 52
51 53 # r'[\w\.]+'
52 54 # r'\s*=\s*%.*'
@@ -71,19 +73,14 b' def split_user_input(line, pattern=None):'
71 73 # print "split failed for line '%s'" % line
72 74 ifun, the_rest = line, u''
73 75 pre = re.match('^(\s*)(.*)',line).groups()[0]
76 esc = ""
74 77 else:
75 pre,ifun,the_rest = match.groups()
78 pre, esc, ifun, the_rest = match.groups()
76 79
77 if not py3compat.PY3:
78 # ifun has to be a valid python identifier, so it better encode into
79 # ascii. We do still make it a unicode string so that we consistently
80 # return unicode, but it will be one that is guaranteed to be pure ascii
81 try:
82 ifun = unicode(ifun.encode('ascii'))
83 except UnicodeEncodeError:
84 the_rest = ifun + u' ' + the_rest
85 ifun = u''
80 if not py3compat.isidentifier(ifun, dotted=True):
81 the_rest = ifun + u' ' + the_rest
82 ifun = u''
86 83
87 84 #print 'line:<%s>' % line # dbg
88 85 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
89 return pre, ifun.strip(), the_rest.lstrip()
86 return pre, esc, ifun.strip(), the_rest.lstrip()
@@ -10,6 +10,7 b' import nose.tools as nt'
10 10 # our own packages
11 11 from IPython.core import autocall
12 12 from IPython.testing import decorators as dec
13 from IPython.testing import tools as tt
13 14 from IPython.testing.globalipapp import get_ipython
14 15
15 16 #-----------------------------------------------------------------------------
@@ -40,15 +41,7 b' def run(tests):'
40 41 """Loop through a list of (pre, post) inputs, where pre is the string
41 42 handed to ipython, and post is how that string looks after it's been
42 43 transformed (i.e. ipython's notion of _i)"""
43 for pre, post in tests:
44 global num_tests
45 num_tests += 1
46 actual = ip.prefilter_manager.prefilter_lines(pre)
47 if actual != None:
48 actual = actual.rstrip('\n')
49 if actual != post:
50 failures.append('Expected %r to become %r, found %r' % (
51 pre, post, actual))
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
52 45
53 46
54 47 def test_handlers():
General Comments 0
You need to be logged in to leave comments. Login now