aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/ipython/py3/IPython/core/splitinput.py
blob: 925c1f8f21e6e921948a3019197e5c198f179eee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# encoding: utf-8 
""" 
Simple utility for splitting user input. This is used by both inputsplitter and 
prefilter. 
 
Authors: 
 
* Brian Granger 
* Fernando Perez 
""" 
 
#----------------------------------------------------------------------------- 
#  Copyright (C) 2008-2011  The IPython Development Team 
# 
#  Distributed under the terms of the BSD License.  The full license is in 
#  the file COPYING, distributed as part of this software. 
#----------------------------------------------------------------------------- 
 
#----------------------------------------------------------------------------- 
# Imports 
#----------------------------------------------------------------------------- 
 
import re 
import sys 
 
from IPython.utils import py3compat 
from IPython.utils.encoding import get_stream_enc 
 
#----------------------------------------------------------------------------- 
# Main function 
#----------------------------------------------------------------------------- 
 
# RegExp for splitting line contents into pre-char//first word-method//rest. 
# For clarity, each group in on one line. 
 
# WARNING: update the regexp if the escapes in interactiveshell are changed, as 
# they are hardwired in. 
 
# Although it's not solely driven by the regex, note that: 
# ,;/% only trigger if they are the first character on the line 
# ! and !! trigger if they are first char(s) *or* follow an indent 
# ? triggers as first or last char. 
 
line_split = re.compile(r""" 
             ^(\s*)               # any leading space 
             ([,;/%]|!!?|\?\??)?  # escape character or characters 
             \s*(%{0,2}[\w\.\*]*)     # function/method, possibly with leading % 
                                  # to correctly treat things like '?%magic' 
             (.*?$|$)             # rest of line 
             """, re.VERBOSE) 
 
 
def split_user_input(line, pattern=None): 
    """Split user input into initial whitespace, escape character, function part 
    and the rest. 
    """ 
    # We need to ensure that the rest of this routine deals only with unicode 
    encoding = get_stream_enc(sys.stdin, 'utf-8') 
    line = py3compat.cast_unicode(line, encoding) 
 
    if pattern is None: 
        pattern = line_split 
    match = pattern.match(line) 
    if not match: 
        # print "match failed for line '%s'" % line 
        try: 
            ifun, the_rest = line.split(None,1) 
        except ValueError: 
            # print "split failed for line '%s'" % line 
            ifun, the_rest = line, u'' 
        pre = re.match(r'^(\s*)(.*)',line).groups()[0] 
        esc = "" 
    else: 
        pre, esc, ifun, the_rest = match.groups() 
 
    #print 'line:<%s>' % line # dbg 
    #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg 
    return pre, esc or '', ifun.strip(), the_rest.lstrip() 
 
 
class LineInfo(object): 
    """A single line of input and associated info. 
 
    Includes the following as properties: 
 
    line 
      The original, raw line 
 
    continue_prompt 
      Is this line a continuation in a sequence of multiline input? 
 
    pre 
      Any leading whitespace. 
 
    esc 
      The escape character(s) in pre or the empty string if there isn't one. 
      Note that '!!' and '??' are possible values for esc. Otherwise it will 
      always be a single character. 
 
    ifun 
      The 'function part', which is basically the maximal initial sequence 
      of valid python identifiers and the '.' character. This is what is 
      checked for alias and magic transformations, used for auto-calling, 
      etc. In contrast to Python identifiers, it may start with "%" and contain 
      "*". 
 
    the_rest 
      Everything else on the line. 
    """ 
    def __init__(self, line, continue_prompt=False): 
        self.line            = line 
        self.continue_prompt = continue_prompt 
        self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line) 
 
        self.pre_char       = self.pre.strip() 
        if self.pre_char: 
            self.pre_whitespace = '' # No whitespace allowed before esc chars 
        else: 
            self.pre_whitespace = self.pre 
 
    def ofind(self, ip): 
        """Do a full, attribute-walking lookup of the ifun in the various 
        namespaces for the given IPython InteractiveShell instance. 
 
        Return a dict with keys: {found, obj, ospace, ismagic} 
 
        Note: can cause state changes because of calling getattr, but should 
        only be run if autocall is on and if the line hasn't matched any 
        other, less dangerous handlers. 
 
        Does cache the results of the call, so can be called multiple times 
        without worrying about *further* damaging state. 
        """ 
        return ip._ofind(self.ifun) 
 
    def __str__(self): 
        return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)