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