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