##// END OF EJS Templates
Suppress auto_rewrite of exit autocall.
Thomas Kluyver -
Show More
@@ -1,56 +1,58 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Autocall capabilities for IPython.core.
4 Autocall capabilities for IPython.core.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 * Thomas Kluyver
10 * Thomas Kluyver
11
11
12 Notes
12 Notes
13 -----
13 -----
14 """
14 """
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2009 The IPython Development Team
17 # Copyright (C) 2008-2009 The IPython Development Team
18 #
18 #
19 # Distributed under the terms of the BSD License. The full license is in
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Imports
24 # Imports
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Code
29 # Code
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class IPyAutocall(object):
32 class IPyAutocall(object):
33 """ Instances of this class are always autocalled
33 """ Instances of this class are always autocalled
34
34
35 This happens regardless of 'autocall' variable state. Use this to
35 This happens regardless of 'autocall' variable state. Use this to
36 develop macro-like mechanisms.
36 develop macro-like mechanisms.
37 """
37 """
38 _ip = None
38 _ip = None
39 rewrite = True
39 def __init__(self, ip=None):
40 def __init__(self, ip=None):
40 self._ip = ip
41 self._ip = ip
41
42
42 def set_ip(self, ip):
43 def set_ip(self, ip):
43 """ Will be used to set _ip point to current ipython instance b/f call
44 """ Will be used to set _ip point to current ipython instance b/f call
44
45
45 Override this method if you don't want this to happen.
46 Override this method if you don't want this to happen.
46
47
47 """
48 """
48 self._ip = ip
49 self._ip = ip
49
50
50
51
51 class ExitAutocall(IPyAutocall):
52 class ExitAutocall(IPyAutocall):
52 """An autocallable object which will be added to the user namespace so that
53 """An autocallable object which will be added to the user namespace so that
53 exit, exit(), quit or quit() are all valid ways to close the shell."""
54 exit, exit(), quit or quit() are all valid ways to close the shell."""
55 rewrite = False
54
56
55 def __call__(self):
57 def __call__(self):
56 self._ip.ask_exit()
58 self._ip.ask_exit()
@@ -1,1025 +1,1025 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Prefiltering components.
4 Prefiltering components.
5
5
6 Prefilters transform user input before it is exec'd by Python. These
6 Prefilters transform user input before it is exec'd by Python. These
7 transforms are used to implement additional syntax such as !ls and %magic.
7 transforms are used to implement additional syntax such as !ls and %magic.
8
8
9 Authors:
9 Authors:
10
10
11 * Brian Granger
11 * Brian Granger
12 * Fernando Perez
12 * Fernando Perez
13 * Dan Milstein
13 * Dan Milstein
14 * Ville Vainio
14 * Ville Vainio
15 """
15 """
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Copyright (C) 2008-2009 The IPython Development Team
18 # Copyright (C) 2008-2009 The IPython Development Team
19 #
19 #
20 # Distributed under the terms of the BSD License. The full license is in
20 # Distributed under the terms of the BSD License. The full license is in
21 # the file COPYING, distributed as part of this software.
21 # the file COPYING, distributed as part of this software.
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Imports
25 # Imports
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 import __builtin__
28 import __builtin__
29 import codeop
29 import codeop
30 import re
30 import re
31
31
32 from IPython.core.alias import AliasManager
32 from IPython.core.alias import AliasManager
33 from IPython.core.autocall import IPyAutocall
33 from IPython.core.autocall import IPyAutocall
34 from IPython.config.configurable import Configurable
34 from IPython.config.configurable import Configurable
35 from IPython.core.macro import Macro
35 from IPython.core.macro import Macro
36 from IPython.core.splitinput import split_user_input
36 from IPython.core.splitinput import split_user_input
37 from IPython.core import page
37 from IPython.core import page
38
38
39 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool, Instance
39 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool, Instance
40 import IPython.utils.io
40 import IPython.utils.io
41 from IPython.utils.text import make_quoted_expr
41 from IPython.utils.text import make_quoted_expr
42 from IPython.utils.autoattr import auto_attr
42 from IPython.utils.autoattr import auto_attr
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Global utilities, errors and constants
45 # Global utilities, errors and constants
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 # Warning, these cannot be changed unless various regular expressions
48 # Warning, these cannot be changed unless various regular expressions
49 # are updated in a number of places. Not great, but at least we told you.
49 # are updated in a number of places. Not great, but at least we told you.
50 ESC_SHELL = '!'
50 ESC_SHELL = '!'
51 ESC_SH_CAP = '!!'
51 ESC_SH_CAP = '!!'
52 ESC_HELP = '?'
52 ESC_HELP = '?'
53 ESC_MAGIC = '%'
53 ESC_MAGIC = '%'
54 ESC_QUOTE = ','
54 ESC_QUOTE = ','
55 ESC_QUOTE2 = ';'
55 ESC_QUOTE2 = ';'
56 ESC_PAREN = '/'
56 ESC_PAREN = '/'
57
57
58
58
59 class PrefilterError(Exception):
59 class PrefilterError(Exception):
60 pass
60 pass
61
61
62
62
63 # RegExp to identify potential function names
63 # RegExp to identify potential function names
64 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
64 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
65
65
66 # RegExp to exclude strings with this start from autocalling. In
66 # RegExp to exclude strings with this start from autocalling. In
67 # particular, all binary operators should be excluded, so that if foo is
67 # particular, all binary operators should be excluded, so that if foo is
68 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
68 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
69 # characters '!=()' don't need to be checked for, as the checkPythonChars
69 # characters '!=()' don't need to be checked for, as the checkPythonChars
70 # routine explicitely does so, to catch direct calls and rebindings of
70 # routine explicitely does so, to catch direct calls and rebindings of
71 # existing names.
71 # existing names.
72
72
73 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
73 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
74 # it affects the rest of the group in square brackets.
74 # it affects the rest of the group in square brackets.
75 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
75 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
76 r'|^is |^not |^in |^and |^or ')
76 r'|^is |^not |^in |^and |^or ')
77
77
78 # try to catch also methods for stuff in lists/tuples/dicts: off
78 # try to catch also methods for stuff in lists/tuples/dicts: off
79 # (experimental). For this to work, the line_split regexp would need
79 # (experimental). For this to work, the line_split regexp would need
80 # to be modified so it wouldn't break things at '['. That line is
80 # to be modified so it wouldn't break things at '['. That line is
81 # nasty enough that I shouldn't change it until I can test it _well_.
81 # nasty enough that I shouldn't change it until I can test it _well_.
82 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
82 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
83
83
84
84
85 # Handler Check Utilities
85 # Handler Check Utilities
86 def is_shadowed(identifier, ip):
86 def is_shadowed(identifier, ip):
87 """Is the given identifier defined in one of the namespaces which shadow
87 """Is the given identifier defined in one of the namespaces which shadow
88 the alias and magic namespaces? Note that an identifier is different
88 the alias and magic namespaces? Note that an identifier is different
89 than ifun, because it can not contain a '.' character."""
89 than ifun, because it can not contain a '.' character."""
90 # This is much safer than calling ofind, which can change state
90 # This is much safer than calling ofind, which can change state
91 return (identifier in ip.user_ns \
91 return (identifier in ip.user_ns \
92 or identifier in ip.internal_ns \
92 or identifier in ip.internal_ns \
93 or identifier in ip.ns_table['builtin'])
93 or identifier in ip.ns_table['builtin'])
94
94
95
95
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97 # The LineInfo class used throughout
97 # The LineInfo class used throughout
98 #-----------------------------------------------------------------------------
98 #-----------------------------------------------------------------------------
99
99
100
100
101 class LineInfo(object):
101 class LineInfo(object):
102 """A single line of input and associated info.
102 """A single line of input and associated info.
103
103
104 Includes the following as properties:
104 Includes the following as properties:
105
105
106 line
106 line
107 The original, raw line
107 The original, raw line
108
108
109 continue_prompt
109 continue_prompt
110 Is this line a continuation in a sequence of multiline input?
110 Is this line a continuation in a sequence of multiline input?
111
111
112 pre
112 pre
113 The initial esc character or whitespace.
113 The initial esc character or whitespace.
114
114
115 pre_char
115 pre_char
116 The escape character(s) in pre or the empty string if there isn't one.
116 The escape character(s) in pre or the empty string if there isn't one.
117 Note that '!!' is a possible value for pre_char. Otherwise it will
117 Note that '!!' is a possible value for pre_char. Otherwise it will
118 always be a single character.
118 always be a single character.
119
119
120 pre_whitespace
120 pre_whitespace
121 The leading whitespace from pre if it exists. If there is a pre_char,
121 The leading whitespace from pre if it exists. If there is a pre_char,
122 this is just ''.
122 this is just ''.
123
123
124 ifun
124 ifun
125 The 'function part', which is basically the maximal initial sequence
125 The 'function part', which is basically the maximal initial sequence
126 of valid python identifiers and the '.' character. This is what is
126 of valid python identifiers and the '.' character. This is what is
127 checked for alias and magic transformations, used for auto-calling,
127 checked for alias and magic transformations, used for auto-calling,
128 etc.
128 etc.
129
129
130 the_rest
130 the_rest
131 Everything else on the line.
131 Everything else on the line.
132 """
132 """
133 def __init__(self, line, continue_prompt):
133 def __init__(self, line, continue_prompt):
134 self.line = line
134 self.line = line
135 self.continue_prompt = continue_prompt
135 self.continue_prompt = continue_prompt
136 self.pre, self.ifun, self.the_rest = split_user_input(line)
136 self.pre, self.ifun, self.the_rest = split_user_input(line)
137
137
138 self.pre_char = self.pre.strip()
138 self.pre_char = self.pre.strip()
139 if self.pre_char:
139 if self.pre_char:
140 self.pre_whitespace = '' # No whitespace allowd before esc chars
140 self.pre_whitespace = '' # No whitespace allowd before esc chars
141 else:
141 else:
142 self.pre_whitespace = self.pre
142 self.pre_whitespace = self.pre
143
143
144 self._oinfo = None
144 self._oinfo = None
145
145
146 def ofind(self, ip):
146 def ofind(self, ip):
147 """Do a full, attribute-walking lookup of the ifun in the various
147 """Do a full, attribute-walking lookup of the ifun in the various
148 namespaces for the given IPython InteractiveShell instance.
148 namespaces for the given IPython InteractiveShell instance.
149
149
150 Return a dict with keys: found,obj,ospace,ismagic
150 Return a dict with keys: found,obj,ospace,ismagic
151
151
152 Note: can cause state changes because of calling getattr, but should
152 Note: can cause state changes because of calling getattr, but should
153 only be run if autocall is on and if the line hasn't matched any
153 only be run if autocall is on and if the line hasn't matched any
154 other, less dangerous handlers.
154 other, less dangerous handlers.
155
155
156 Does cache the results of the call, so can be called multiple times
156 Does cache the results of the call, so can be called multiple times
157 without worrying about *further* damaging state.
157 without worrying about *further* damaging state.
158 """
158 """
159 if not self._oinfo:
159 if not self._oinfo:
160 # ip.shell._ofind is actually on the Magic class!
160 # ip.shell._ofind is actually on the Magic class!
161 self._oinfo = ip.shell._ofind(self.ifun)
161 self._oinfo = ip.shell._ofind(self.ifun)
162 return self._oinfo
162 return self._oinfo
163
163
164 def __str__(self):
164 def __str__(self):
165 return "Lineinfo [%s|%s|%s]" %(self.pre, self.ifun, self.the_rest)
165 return "Lineinfo [%s|%s|%s]" %(self.pre, self.ifun, self.the_rest)
166
166
167
167
168 #-----------------------------------------------------------------------------
168 #-----------------------------------------------------------------------------
169 # Main Prefilter manager
169 # Main Prefilter manager
170 #-----------------------------------------------------------------------------
170 #-----------------------------------------------------------------------------
171
171
172
172
173 class PrefilterManager(Configurable):
173 class PrefilterManager(Configurable):
174 """Main prefilter component.
174 """Main prefilter component.
175
175
176 The IPython prefilter is run on all user input before it is run. The
176 The IPython prefilter is run on all user input before it is run. The
177 prefilter consumes lines of input and produces transformed lines of
177 prefilter consumes lines of input and produces transformed lines of
178 input.
178 input.
179
179
180 The iplementation consists of two phases:
180 The iplementation consists of two phases:
181
181
182 1. Transformers
182 1. Transformers
183 2. Checkers and handlers
183 2. Checkers and handlers
184
184
185 Over time, we plan on deprecating the checkers and handlers and doing
185 Over time, we plan on deprecating the checkers and handlers and doing
186 everything in the transformers.
186 everything in the transformers.
187
187
188 The transformers are instances of :class:`PrefilterTransformer` and have
188 The transformers are instances of :class:`PrefilterTransformer` and have
189 a single method :meth:`transform` that takes a line and returns a
189 a single method :meth:`transform` that takes a line and returns a
190 transformed line. The transformation can be accomplished using any
190 transformed line. The transformation can be accomplished using any
191 tool, but our current ones use regular expressions for speed. We also
191 tool, but our current ones use regular expressions for speed. We also
192 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
192 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
193
193
194 After all the transformers have been run, the line is fed to the checkers,
194 After all the transformers have been run, the line is fed to the checkers,
195 which are instances of :class:`PrefilterChecker`. The line is passed to
195 which are instances of :class:`PrefilterChecker`. The line is passed to
196 the :meth:`check` method, which either returns `None` or a
196 the :meth:`check` method, which either returns `None` or a
197 :class:`PrefilterHandler` instance. If `None` is returned, the other
197 :class:`PrefilterHandler` instance. If `None` is returned, the other
198 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
198 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
199 the line is passed to the :meth:`handle` method of the returned
199 the line is passed to the :meth:`handle` method of the returned
200 handler and no further checkers are tried.
200 handler and no further checkers are tried.
201
201
202 Both transformers and checkers have a `priority` attribute, that determines
202 Both transformers and checkers have a `priority` attribute, that determines
203 the order in which they are called. Smaller priorities are tried first.
203 the order in which they are called. Smaller priorities are tried first.
204
204
205 Both transformers and checkers also have `enabled` attribute, which is
205 Both transformers and checkers also have `enabled` attribute, which is
206 a boolean that determines if the instance is used.
206 a boolean that determines if the instance is used.
207
207
208 Users or developers can change the priority or enabled attribute of
208 Users or developers can change the priority or enabled attribute of
209 transformers or checkers, but they must call the :meth:`sort_checkers`
209 transformers or checkers, but they must call the :meth:`sort_checkers`
210 or :meth:`sort_transformers` method after changing the priority.
210 or :meth:`sort_transformers` method after changing the priority.
211 """
211 """
212
212
213 multi_line_specials = CBool(True, config=True)
213 multi_line_specials = CBool(True, config=True)
214 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
214 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
215
215
216 def __init__(self, shell=None, config=None):
216 def __init__(self, shell=None, config=None):
217 super(PrefilterManager, self).__init__(shell=shell, config=config)
217 super(PrefilterManager, self).__init__(shell=shell, config=config)
218 self.shell = shell
218 self.shell = shell
219 self.init_transformers()
219 self.init_transformers()
220 self.init_handlers()
220 self.init_handlers()
221 self.init_checkers()
221 self.init_checkers()
222
222
223 #-------------------------------------------------------------------------
223 #-------------------------------------------------------------------------
224 # API for managing transformers
224 # API for managing transformers
225 #-------------------------------------------------------------------------
225 #-------------------------------------------------------------------------
226
226
227 def init_transformers(self):
227 def init_transformers(self):
228 """Create the default transformers."""
228 """Create the default transformers."""
229 self._transformers = []
229 self._transformers = []
230 for transformer_cls in _default_transformers:
230 for transformer_cls in _default_transformers:
231 transformer_cls(
231 transformer_cls(
232 shell=self.shell, prefilter_manager=self, config=self.config
232 shell=self.shell, prefilter_manager=self, config=self.config
233 )
233 )
234
234
235 def sort_transformers(self):
235 def sort_transformers(self):
236 """Sort the transformers by priority.
236 """Sort the transformers by priority.
237
237
238 This must be called after the priority of a transformer is changed.
238 This must be called after the priority of a transformer is changed.
239 The :meth:`register_transformer` method calls this automatically.
239 The :meth:`register_transformer` method calls this automatically.
240 """
240 """
241 self._transformers.sort(key=lambda x: x.priority)
241 self._transformers.sort(key=lambda x: x.priority)
242
242
243 @property
243 @property
244 def transformers(self):
244 def transformers(self):
245 """Return a list of checkers, sorted by priority."""
245 """Return a list of checkers, sorted by priority."""
246 return self._transformers
246 return self._transformers
247
247
248 def register_transformer(self, transformer):
248 def register_transformer(self, transformer):
249 """Register a transformer instance."""
249 """Register a transformer instance."""
250 if transformer not in self._transformers:
250 if transformer not in self._transformers:
251 self._transformers.append(transformer)
251 self._transformers.append(transformer)
252 self.sort_transformers()
252 self.sort_transformers()
253
253
254 def unregister_transformer(self, transformer):
254 def unregister_transformer(self, transformer):
255 """Unregister a transformer instance."""
255 """Unregister a transformer instance."""
256 if transformer in self._transformers:
256 if transformer in self._transformers:
257 self._transformers.remove(transformer)
257 self._transformers.remove(transformer)
258
258
259 #-------------------------------------------------------------------------
259 #-------------------------------------------------------------------------
260 # API for managing checkers
260 # API for managing checkers
261 #-------------------------------------------------------------------------
261 #-------------------------------------------------------------------------
262
262
263 def init_checkers(self):
263 def init_checkers(self):
264 """Create the default checkers."""
264 """Create the default checkers."""
265 self._checkers = []
265 self._checkers = []
266 for checker in _default_checkers:
266 for checker in _default_checkers:
267 checker(
267 checker(
268 shell=self.shell, prefilter_manager=self, config=self.config
268 shell=self.shell, prefilter_manager=self, config=self.config
269 )
269 )
270
270
271 def sort_checkers(self):
271 def sort_checkers(self):
272 """Sort the checkers by priority.
272 """Sort the checkers by priority.
273
273
274 This must be called after the priority of a checker is changed.
274 This must be called after the priority of a checker is changed.
275 The :meth:`register_checker` method calls this automatically.
275 The :meth:`register_checker` method calls this automatically.
276 """
276 """
277 self._checkers.sort(key=lambda x: x.priority)
277 self._checkers.sort(key=lambda x: x.priority)
278
278
279 @property
279 @property
280 def checkers(self):
280 def checkers(self):
281 """Return a list of checkers, sorted by priority."""
281 """Return a list of checkers, sorted by priority."""
282 return self._checkers
282 return self._checkers
283
283
284 def register_checker(self, checker):
284 def register_checker(self, checker):
285 """Register a checker instance."""
285 """Register a checker instance."""
286 if checker not in self._checkers:
286 if checker not in self._checkers:
287 self._checkers.append(checker)
287 self._checkers.append(checker)
288 self.sort_checkers()
288 self.sort_checkers()
289
289
290 def unregister_checker(self, checker):
290 def unregister_checker(self, checker):
291 """Unregister a checker instance."""
291 """Unregister a checker instance."""
292 if checker in self._checkers:
292 if checker in self._checkers:
293 self._checkers.remove(checker)
293 self._checkers.remove(checker)
294
294
295 #-------------------------------------------------------------------------
295 #-------------------------------------------------------------------------
296 # API for managing checkers
296 # API for managing checkers
297 #-------------------------------------------------------------------------
297 #-------------------------------------------------------------------------
298
298
299 def init_handlers(self):
299 def init_handlers(self):
300 """Create the default handlers."""
300 """Create the default handlers."""
301 self._handlers = {}
301 self._handlers = {}
302 self._esc_handlers = {}
302 self._esc_handlers = {}
303 for handler in _default_handlers:
303 for handler in _default_handlers:
304 handler(
304 handler(
305 shell=self.shell, prefilter_manager=self, config=self.config
305 shell=self.shell, prefilter_manager=self, config=self.config
306 )
306 )
307
307
308 @property
308 @property
309 def handlers(self):
309 def handlers(self):
310 """Return a dict of all the handlers."""
310 """Return a dict of all the handlers."""
311 return self._handlers
311 return self._handlers
312
312
313 def register_handler(self, name, handler, esc_strings):
313 def register_handler(self, name, handler, esc_strings):
314 """Register a handler instance by name with esc_strings."""
314 """Register a handler instance by name with esc_strings."""
315 self._handlers[name] = handler
315 self._handlers[name] = handler
316 for esc_str in esc_strings:
316 for esc_str in esc_strings:
317 self._esc_handlers[esc_str] = handler
317 self._esc_handlers[esc_str] = handler
318
318
319 def unregister_handler(self, name, handler, esc_strings):
319 def unregister_handler(self, name, handler, esc_strings):
320 """Unregister a handler instance by name with esc_strings."""
320 """Unregister a handler instance by name with esc_strings."""
321 try:
321 try:
322 del self._handlers[name]
322 del self._handlers[name]
323 except KeyError:
323 except KeyError:
324 pass
324 pass
325 for esc_str in esc_strings:
325 for esc_str in esc_strings:
326 h = self._esc_handlers.get(esc_str)
326 h = self._esc_handlers.get(esc_str)
327 if h is handler:
327 if h is handler:
328 del self._esc_handlers[esc_str]
328 del self._esc_handlers[esc_str]
329
329
330 def get_handler_by_name(self, name):
330 def get_handler_by_name(self, name):
331 """Get a handler by its name."""
331 """Get a handler by its name."""
332 return self._handlers.get(name)
332 return self._handlers.get(name)
333
333
334 def get_handler_by_esc(self, esc_str):
334 def get_handler_by_esc(self, esc_str):
335 """Get a handler by its escape string."""
335 """Get a handler by its escape string."""
336 return self._esc_handlers.get(esc_str)
336 return self._esc_handlers.get(esc_str)
337
337
338 #-------------------------------------------------------------------------
338 #-------------------------------------------------------------------------
339 # Main prefiltering API
339 # Main prefiltering API
340 #-------------------------------------------------------------------------
340 #-------------------------------------------------------------------------
341
341
342 def prefilter_line_info(self, line_info):
342 def prefilter_line_info(self, line_info):
343 """Prefilter a line that has been converted to a LineInfo object.
343 """Prefilter a line that has been converted to a LineInfo object.
344
344
345 This implements the checker/handler part of the prefilter pipe.
345 This implements the checker/handler part of the prefilter pipe.
346 """
346 """
347 # print "prefilter_line_info: ", line_info
347 # print "prefilter_line_info: ", line_info
348 handler = self.find_handler(line_info)
348 handler = self.find_handler(line_info)
349 return handler.handle(line_info)
349 return handler.handle(line_info)
350
350
351 def find_handler(self, line_info):
351 def find_handler(self, line_info):
352 """Find a handler for the line_info by trying checkers."""
352 """Find a handler for the line_info by trying checkers."""
353 for checker in self.checkers:
353 for checker in self.checkers:
354 if checker.enabled:
354 if checker.enabled:
355 handler = checker.check(line_info)
355 handler = checker.check(line_info)
356 if handler:
356 if handler:
357 return handler
357 return handler
358 return self.get_handler_by_name('normal')
358 return self.get_handler_by_name('normal')
359
359
360 def transform_line(self, line, continue_prompt):
360 def transform_line(self, line, continue_prompt):
361 """Calls the enabled transformers in order of increasing priority."""
361 """Calls the enabled transformers in order of increasing priority."""
362 for transformer in self.transformers:
362 for transformer in self.transformers:
363 if transformer.enabled:
363 if transformer.enabled:
364 line = transformer.transform(line, continue_prompt)
364 line = transformer.transform(line, continue_prompt)
365 return line
365 return line
366
366
367 def prefilter_line(self, line, continue_prompt=False):
367 def prefilter_line(self, line, continue_prompt=False):
368 """Prefilter a single input line as text.
368 """Prefilter a single input line as text.
369
369
370 This method prefilters a single line of text by calling the
370 This method prefilters a single line of text by calling the
371 transformers and then the checkers/handlers.
371 transformers and then the checkers/handlers.
372 """
372 """
373
373
374 # print "prefilter_line: ", line, continue_prompt
374 # print "prefilter_line: ", line, continue_prompt
375 # All handlers *must* return a value, even if it's blank ('').
375 # All handlers *must* return a value, even if it's blank ('').
376
376
377 # save the line away in case we crash, so the post-mortem handler can
377 # save the line away in case we crash, so the post-mortem handler can
378 # record it
378 # record it
379 self.shell._last_input_line = line
379 self.shell._last_input_line = line
380
380
381 if not line:
381 if not line:
382 # Return immediately on purely empty lines, so that if the user
382 # Return immediately on purely empty lines, so that if the user
383 # previously typed some whitespace that started a continuation
383 # previously typed some whitespace that started a continuation
384 # prompt, he can break out of that loop with just an empty line.
384 # prompt, he can break out of that loop with just an empty line.
385 # This is how the default python prompt works.
385 # This is how the default python prompt works.
386
386
387 # Only return if the accumulated input buffer was just whitespace!
387 # Only return if the accumulated input buffer was just whitespace!
388 if ''.join(self.shell.buffer).isspace():
388 if ''.join(self.shell.buffer).isspace():
389 self.shell.buffer[:] = []
389 self.shell.buffer[:] = []
390 return ''
390 return ''
391
391
392 # At this point, we invoke our transformers.
392 # At this point, we invoke our transformers.
393 if not continue_prompt or (continue_prompt and self.multi_line_specials):
393 if not continue_prompt or (continue_prompt and self.multi_line_specials):
394 line = self.transform_line(line, continue_prompt)
394 line = self.transform_line(line, continue_prompt)
395
395
396 # Now we compute line_info for the checkers and handlers
396 # Now we compute line_info for the checkers and handlers
397 line_info = LineInfo(line, continue_prompt)
397 line_info = LineInfo(line, continue_prompt)
398
398
399 # the input history needs to track even empty lines
399 # the input history needs to track even empty lines
400 stripped = line.strip()
400 stripped = line.strip()
401
401
402 normal_handler = self.get_handler_by_name('normal')
402 normal_handler = self.get_handler_by_name('normal')
403 if not stripped:
403 if not stripped:
404 if not continue_prompt:
404 if not continue_prompt:
405 self.shell.displayhook.prompt_count -= 1
405 self.shell.displayhook.prompt_count -= 1
406
406
407 return normal_handler.handle(line_info)
407 return normal_handler.handle(line_info)
408
408
409 # special handlers are only allowed for single line statements
409 # special handlers are only allowed for single line statements
410 if continue_prompt and not self.multi_line_specials:
410 if continue_prompt and not self.multi_line_specials:
411 return normal_handler.handle(line_info)
411 return normal_handler.handle(line_info)
412
412
413 prefiltered = self.prefilter_line_info(line_info)
413 prefiltered = self.prefilter_line_info(line_info)
414 # print "prefiltered line: %r" % prefiltered
414 # print "prefiltered line: %r" % prefiltered
415 return prefiltered
415 return prefiltered
416
416
417 def prefilter_lines(self, lines, continue_prompt=False):
417 def prefilter_lines(self, lines, continue_prompt=False):
418 """Prefilter multiple input lines of text.
418 """Prefilter multiple input lines of text.
419
419
420 This is the main entry point for prefiltering multiple lines of
420 This is the main entry point for prefiltering multiple lines of
421 input. This simply calls :meth:`prefilter_line` for each line of
421 input. This simply calls :meth:`prefilter_line` for each line of
422 input.
422 input.
423
423
424 This covers cases where there are multiple lines in the user entry,
424 This covers cases where there are multiple lines in the user entry,
425 which is the case when the user goes back to a multiline history
425 which is the case when the user goes back to a multiline history
426 entry and presses enter.
426 entry and presses enter.
427 """
427 """
428 llines = lines.rstrip('\n').split('\n')
428 llines = lines.rstrip('\n').split('\n')
429 # We can get multiple lines in one shot, where multiline input 'blends'
429 # We can get multiple lines in one shot, where multiline input 'blends'
430 # into one line, in cases like recalling from the readline history
430 # into one line, in cases like recalling from the readline history
431 # buffer. We need to make sure that in such cases, we correctly
431 # buffer. We need to make sure that in such cases, we correctly
432 # communicate downstream which line is first and which are continuation
432 # communicate downstream which line is first and which are continuation
433 # ones.
433 # ones.
434 if len(llines) > 1:
434 if len(llines) > 1:
435 out = '\n'.join([self.prefilter_line(line, lnum>0)
435 out = '\n'.join([self.prefilter_line(line, lnum>0)
436 for lnum, line in enumerate(llines) ])
436 for lnum, line in enumerate(llines) ])
437 else:
437 else:
438 out = self.prefilter_line(llines[0], continue_prompt)
438 out = self.prefilter_line(llines[0], continue_prompt)
439
439
440 return out
440 return out
441
441
442 #-----------------------------------------------------------------------------
442 #-----------------------------------------------------------------------------
443 # Prefilter transformers
443 # Prefilter transformers
444 #-----------------------------------------------------------------------------
444 #-----------------------------------------------------------------------------
445
445
446
446
447 class PrefilterTransformer(Configurable):
447 class PrefilterTransformer(Configurable):
448 """Transform a line of user input."""
448 """Transform a line of user input."""
449
449
450 priority = Int(100, config=True)
450 priority = Int(100, config=True)
451 # Transformers don't currently use shell or prefilter_manager, but as we
451 # Transformers don't currently use shell or prefilter_manager, but as we
452 # move away from checkers and handlers, they will need them.
452 # move away from checkers and handlers, they will need them.
453 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
453 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
454 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
454 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
455 enabled = Bool(True, config=True)
455 enabled = Bool(True, config=True)
456
456
457 def __init__(self, shell=None, prefilter_manager=None, config=None):
457 def __init__(self, shell=None, prefilter_manager=None, config=None):
458 super(PrefilterTransformer, self).__init__(
458 super(PrefilterTransformer, self).__init__(
459 shell=shell, prefilter_manager=prefilter_manager, config=config
459 shell=shell, prefilter_manager=prefilter_manager, config=config
460 )
460 )
461 self.prefilter_manager.register_transformer(self)
461 self.prefilter_manager.register_transformer(self)
462
462
463 def transform(self, line, continue_prompt):
463 def transform(self, line, continue_prompt):
464 """Transform a line, returning the new one."""
464 """Transform a line, returning the new one."""
465 return None
465 return None
466
466
467 def __repr__(self):
467 def __repr__(self):
468 return "<%s(priority=%r, enabled=%r)>" % (
468 return "<%s(priority=%r, enabled=%r)>" % (
469 self.__class__.__name__, self.priority, self.enabled)
469 self.__class__.__name__, self.priority, self.enabled)
470
470
471
471
472 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
472 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
473 r'\s*=\s*!(?P<cmd>.*)')
473 r'\s*=\s*!(?P<cmd>.*)')
474
474
475
475
476 class AssignSystemTransformer(PrefilterTransformer):
476 class AssignSystemTransformer(PrefilterTransformer):
477 """Handle the `files = !ls` syntax."""
477 """Handle the `files = !ls` syntax."""
478
478
479 priority = Int(100, config=True)
479 priority = Int(100, config=True)
480
480
481 def transform(self, line, continue_prompt):
481 def transform(self, line, continue_prompt):
482 m = _assign_system_re.match(line)
482 m = _assign_system_re.match(line)
483 if m is not None:
483 if m is not None:
484 cmd = m.group('cmd')
484 cmd = m.group('cmd')
485 lhs = m.group('lhs')
485 lhs = m.group('lhs')
486 expr = make_quoted_expr("sc =%s" % cmd)
486 expr = make_quoted_expr("sc =%s" % cmd)
487 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
487 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
488 return new_line
488 return new_line
489 return line
489 return line
490
490
491
491
492 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
492 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
493 r'\s*=\s*%(?P<cmd>.*)')
493 r'\s*=\s*%(?P<cmd>.*)')
494
494
495 class AssignMagicTransformer(PrefilterTransformer):
495 class AssignMagicTransformer(PrefilterTransformer):
496 """Handle the `a = %who` syntax."""
496 """Handle the `a = %who` syntax."""
497
497
498 priority = Int(200, config=True)
498 priority = Int(200, config=True)
499
499
500 def transform(self, line, continue_prompt):
500 def transform(self, line, continue_prompt):
501 m = _assign_magic_re.match(line)
501 m = _assign_magic_re.match(line)
502 if m is not None:
502 if m is not None:
503 cmd = m.group('cmd')
503 cmd = m.group('cmd')
504 lhs = m.group('lhs')
504 lhs = m.group('lhs')
505 expr = make_quoted_expr(cmd)
505 expr = make_quoted_expr(cmd)
506 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
506 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
507 return new_line
507 return new_line
508 return line
508 return line
509
509
510
510
511 _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
511 _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
512
512
513 class PyPromptTransformer(PrefilterTransformer):
513 class PyPromptTransformer(PrefilterTransformer):
514 """Handle inputs that start with '>>> ' syntax."""
514 """Handle inputs that start with '>>> ' syntax."""
515
515
516 priority = Int(50, config=True)
516 priority = Int(50, config=True)
517
517
518 def transform(self, line, continue_prompt):
518 def transform(self, line, continue_prompt):
519
519
520 if not line or line.isspace() or line.strip() == '...':
520 if not line or line.isspace() or line.strip() == '...':
521 # This allows us to recognize multiple input prompts separated by
521 # This allows us to recognize multiple input prompts separated by
522 # blank lines and pasted in a single chunk, very common when
522 # blank lines and pasted in a single chunk, very common when
523 # pasting doctests or long tutorial passages.
523 # pasting doctests or long tutorial passages.
524 return ''
524 return ''
525 m = _classic_prompt_re.match(line)
525 m = _classic_prompt_re.match(line)
526 if m:
526 if m:
527 return line[len(m.group(0)):]
527 return line[len(m.group(0)):]
528 else:
528 else:
529 return line
529 return line
530
530
531
531
532 _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
532 _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
533
533
534 class IPyPromptTransformer(PrefilterTransformer):
534 class IPyPromptTransformer(PrefilterTransformer):
535 """Handle inputs that start classic IPython prompt syntax."""
535 """Handle inputs that start classic IPython prompt syntax."""
536
536
537 priority = Int(50, config=True)
537 priority = Int(50, config=True)
538
538
539 def transform(self, line, continue_prompt):
539 def transform(self, line, continue_prompt):
540
540
541 if not line or line.isspace() or line.strip() == '...':
541 if not line or line.isspace() or line.strip() == '...':
542 # This allows us to recognize multiple input prompts separated by
542 # This allows us to recognize multiple input prompts separated by
543 # blank lines and pasted in a single chunk, very common when
543 # blank lines and pasted in a single chunk, very common when
544 # pasting doctests or long tutorial passages.
544 # pasting doctests or long tutorial passages.
545 return ''
545 return ''
546 m = _ipy_prompt_re.match(line)
546 m = _ipy_prompt_re.match(line)
547 if m:
547 if m:
548 return line[len(m.group(0)):]
548 return line[len(m.group(0)):]
549 else:
549 else:
550 return line
550 return line
551
551
552 #-----------------------------------------------------------------------------
552 #-----------------------------------------------------------------------------
553 # Prefilter checkers
553 # Prefilter checkers
554 #-----------------------------------------------------------------------------
554 #-----------------------------------------------------------------------------
555
555
556
556
557 class PrefilterChecker(Configurable):
557 class PrefilterChecker(Configurable):
558 """Inspect an input line and return a handler for that line."""
558 """Inspect an input line and return a handler for that line."""
559
559
560 priority = Int(100, config=True)
560 priority = Int(100, config=True)
561 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
561 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
562 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
562 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
563 enabled = Bool(True, config=True)
563 enabled = Bool(True, config=True)
564
564
565 def __init__(self, shell=None, prefilter_manager=None, config=None):
565 def __init__(self, shell=None, prefilter_manager=None, config=None):
566 super(PrefilterChecker, self).__init__(
566 super(PrefilterChecker, self).__init__(
567 shell=shell, prefilter_manager=prefilter_manager, config=config
567 shell=shell, prefilter_manager=prefilter_manager, config=config
568 )
568 )
569 self.prefilter_manager.register_checker(self)
569 self.prefilter_manager.register_checker(self)
570
570
571 def check(self, line_info):
571 def check(self, line_info):
572 """Inspect line_info and return a handler instance or None."""
572 """Inspect line_info and return a handler instance or None."""
573 return None
573 return None
574
574
575 def __repr__(self):
575 def __repr__(self):
576 return "<%s(priority=%r, enabled=%r)>" % (
576 return "<%s(priority=%r, enabled=%r)>" % (
577 self.__class__.__name__, self.priority, self.enabled)
577 self.__class__.__name__, self.priority, self.enabled)
578
578
579
579
580 class EmacsChecker(PrefilterChecker):
580 class EmacsChecker(PrefilterChecker):
581
581
582 priority = Int(100, config=True)
582 priority = Int(100, config=True)
583 enabled = Bool(False, config=True)
583 enabled = Bool(False, config=True)
584
584
585 def check(self, line_info):
585 def check(self, line_info):
586 "Emacs ipython-mode tags certain input lines."
586 "Emacs ipython-mode tags certain input lines."
587 if line_info.line.endswith('# PYTHON-MODE'):
587 if line_info.line.endswith('# PYTHON-MODE'):
588 return self.prefilter_manager.get_handler_by_name('emacs')
588 return self.prefilter_manager.get_handler_by_name('emacs')
589 else:
589 else:
590 return None
590 return None
591
591
592
592
593 class ShellEscapeChecker(PrefilterChecker):
593 class ShellEscapeChecker(PrefilterChecker):
594
594
595 priority = Int(200, config=True)
595 priority = Int(200, config=True)
596
596
597 def check(self, line_info):
597 def check(self, line_info):
598 if line_info.line.lstrip().startswith(ESC_SHELL):
598 if line_info.line.lstrip().startswith(ESC_SHELL):
599 return self.prefilter_manager.get_handler_by_name('shell')
599 return self.prefilter_manager.get_handler_by_name('shell')
600
600
601
601
602 class MacroChecker(PrefilterChecker):
602 class MacroChecker(PrefilterChecker):
603
603
604 priority = Int(250, config=True)
604 priority = Int(250, config=True)
605
605
606 def check(self, line_info):
606 def check(self, line_info):
607 obj = self.shell.user_ns.get(line_info.ifun)
607 obj = self.shell.user_ns.get(line_info.ifun)
608 if isinstance(obj, Macro):
608 if isinstance(obj, Macro):
609 return self.prefilter_manager.get_handler_by_name('macro')
609 return self.prefilter_manager.get_handler_by_name('macro')
610 else:
610 else:
611 return None
611 return None
612
612
613
613
614 class IPyAutocallChecker(PrefilterChecker):
614 class IPyAutocallChecker(PrefilterChecker):
615
615
616 priority = Int(300, config=True)
616 priority = Int(300, config=True)
617
617
618 def check(self, line_info):
618 def check(self, line_info):
619 "Instances of IPyAutocall in user_ns get autocalled immediately"
619 "Instances of IPyAutocall in user_ns get autocalled immediately"
620 obj = self.shell.user_ns.get(line_info.ifun, None)
620 obj = self.shell.user_ns.get(line_info.ifun, None)
621 if isinstance(obj, IPyAutocall):
621 if isinstance(obj, IPyAutocall):
622 obj.set_ip(self.shell)
622 obj.set_ip(self.shell)
623 return self.prefilter_manager.get_handler_by_name('auto')
623 return self.prefilter_manager.get_handler_by_name('auto')
624 else:
624 else:
625 return None
625 return None
626
626
627
627
628 class MultiLineMagicChecker(PrefilterChecker):
628 class MultiLineMagicChecker(PrefilterChecker):
629
629
630 priority = Int(400, config=True)
630 priority = Int(400, config=True)
631
631
632 def check(self, line_info):
632 def check(self, line_info):
633 "Allow ! and !! in multi-line statements if multi_line_specials is on"
633 "Allow ! and !! in multi-line statements if multi_line_specials is on"
634 # Note that this one of the only places we check the first character of
634 # Note that this one of the only places we check the first character of
635 # ifun and *not* the pre_char. Also note that the below test matches
635 # ifun and *not* the pre_char. Also note that the below test matches
636 # both ! and !!.
636 # both ! and !!.
637 if line_info.continue_prompt \
637 if line_info.continue_prompt \
638 and self.prefilter_manager.multi_line_specials:
638 and self.prefilter_manager.multi_line_specials:
639 if line_info.ifun.startswith(ESC_MAGIC):
639 if line_info.ifun.startswith(ESC_MAGIC):
640 return self.prefilter_manager.get_handler_by_name('magic')
640 return self.prefilter_manager.get_handler_by_name('magic')
641 else:
641 else:
642 return None
642 return None
643
643
644
644
645 class EscCharsChecker(PrefilterChecker):
645 class EscCharsChecker(PrefilterChecker):
646
646
647 priority = Int(500, config=True)
647 priority = Int(500, config=True)
648
648
649 def check(self, line_info):
649 def check(self, line_info):
650 """Check for escape character and return either a handler to handle it,
650 """Check for escape character and return either a handler to handle it,
651 or None if there is no escape char."""
651 or None if there is no escape char."""
652 if line_info.line[-1] == ESC_HELP \
652 if line_info.line[-1] == ESC_HELP \
653 and line_info.pre_char != ESC_SHELL \
653 and line_info.pre_char != ESC_SHELL \
654 and line_info.pre_char != ESC_SH_CAP:
654 and line_info.pre_char != ESC_SH_CAP:
655 # the ? can be at the end, but *not* for either kind of shell escape,
655 # the ? can be at the end, but *not* for either kind of shell escape,
656 # because a ? can be a vaild final char in a shell cmd
656 # because a ? can be a vaild final char in a shell cmd
657 return self.prefilter_manager.get_handler_by_name('help')
657 return self.prefilter_manager.get_handler_by_name('help')
658 else:
658 else:
659 # This returns None like it should if no handler exists
659 # This returns None like it should if no handler exists
660 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
660 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
661
661
662
662
663 class AssignmentChecker(PrefilterChecker):
663 class AssignmentChecker(PrefilterChecker):
664
664
665 priority = Int(600, config=True)
665 priority = Int(600, config=True)
666
666
667 def check(self, line_info):
667 def check(self, line_info):
668 """Check to see if user is assigning to a var for the first time, in
668 """Check to see if user is assigning to a var for the first time, in
669 which case we want to avoid any sort of automagic / autocall games.
669 which case we want to avoid any sort of automagic / autocall games.
670
670
671 This allows users to assign to either alias or magic names true python
671 This allows users to assign to either alias or magic names true python
672 variables (the magic/alias systems always take second seat to true
672 variables (the magic/alias systems always take second seat to true
673 python code). E.g. ls='hi', or ls,that=1,2"""
673 python code). E.g. ls='hi', or ls,that=1,2"""
674 if line_info.the_rest:
674 if line_info.the_rest:
675 if line_info.the_rest[0] in '=,':
675 if line_info.the_rest[0] in '=,':
676 return self.prefilter_manager.get_handler_by_name('normal')
676 return self.prefilter_manager.get_handler_by_name('normal')
677 else:
677 else:
678 return None
678 return None
679
679
680
680
681 class AutoMagicChecker(PrefilterChecker):
681 class AutoMagicChecker(PrefilterChecker):
682
682
683 priority = Int(700, config=True)
683 priority = Int(700, config=True)
684
684
685 def check(self, line_info):
685 def check(self, line_info):
686 """If the ifun is magic, and automagic is on, run it. Note: normal,
686 """If the ifun is magic, and automagic is on, run it. Note: normal,
687 non-auto magic would already have been triggered via '%' in
687 non-auto magic would already have been triggered via '%' in
688 check_esc_chars. This just checks for automagic. Also, before
688 check_esc_chars. This just checks for automagic. Also, before
689 triggering the magic handler, make sure that there is nothing in the
689 triggering the magic handler, make sure that there is nothing in the
690 user namespace which could shadow it."""
690 user namespace which could shadow it."""
691 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
691 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
692 return None
692 return None
693
693
694 # We have a likely magic method. Make sure we should actually call it.
694 # We have a likely magic method. Make sure we should actually call it.
695 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
695 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
696 return None
696 return None
697
697
698 head = line_info.ifun.split('.',1)[0]
698 head = line_info.ifun.split('.',1)[0]
699 if is_shadowed(head, self.shell):
699 if is_shadowed(head, self.shell):
700 return None
700 return None
701
701
702 return self.prefilter_manager.get_handler_by_name('magic')
702 return self.prefilter_manager.get_handler_by_name('magic')
703
703
704
704
705 class AliasChecker(PrefilterChecker):
705 class AliasChecker(PrefilterChecker):
706
706
707 priority = Int(800, config=True)
707 priority = Int(800, config=True)
708
708
709 def check(self, line_info):
709 def check(self, line_info):
710 "Check if the initital identifier on the line is an alias."
710 "Check if the initital identifier on the line is an alias."
711 # Note: aliases can not contain '.'
711 # Note: aliases can not contain '.'
712 head = line_info.ifun.split('.',1)[0]
712 head = line_info.ifun.split('.',1)[0]
713 if line_info.ifun not in self.shell.alias_manager \
713 if line_info.ifun not in self.shell.alias_manager \
714 or head not in self.shell.alias_manager \
714 or head not in self.shell.alias_manager \
715 or is_shadowed(head, self.shell):
715 or is_shadowed(head, self.shell):
716 return None
716 return None
717
717
718 return self.prefilter_manager.get_handler_by_name('alias')
718 return self.prefilter_manager.get_handler_by_name('alias')
719
719
720
720
721 class PythonOpsChecker(PrefilterChecker):
721 class PythonOpsChecker(PrefilterChecker):
722
722
723 priority = Int(900, config=True)
723 priority = Int(900, config=True)
724
724
725 def check(self, line_info):
725 def check(self, line_info):
726 """If the 'rest' of the line begins with a function call or pretty much
726 """If the 'rest' of the line begins with a function call or pretty much
727 any python operator, we should simply execute the line (regardless of
727 any python operator, we should simply execute the line (regardless of
728 whether or not there's a possible autocall expansion). This avoids
728 whether or not there's a possible autocall expansion). This avoids
729 spurious (and very confusing) geattr() accesses."""
729 spurious (and very confusing) geattr() accesses."""
730 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
730 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
731 return self.prefilter_manager.get_handler_by_name('normal')
731 return self.prefilter_manager.get_handler_by_name('normal')
732 else:
732 else:
733 return None
733 return None
734
734
735
735
736 class AutocallChecker(PrefilterChecker):
736 class AutocallChecker(PrefilterChecker):
737
737
738 priority = Int(1000, config=True)
738 priority = Int(1000, config=True)
739
739
740 def check(self, line_info):
740 def check(self, line_info):
741 "Check if the initial word/function is callable and autocall is on."
741 "Check if the initial word/function is callable and autocall is on."
742 if not self.shell.autocall:
742 if not self.shell.autocall:
743 return None
743 return None
744
744
745 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
745 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
746 if not oinfo['found']:
746 if not oinfo['found']:
747 return None
747 return None
748
748
749 if callable(oinfo['obj']) \
749 if callable(oinfo['obj']) \
750 and (not re_exclude_auto.match(line_info.the_rest)) \
750 and (not re_exclude_auto.match(line_info.the_rest)) \
751 and re_fun_name.match(line_info.ifun):
751 and re_fun_name.match(line_info.ifun):
752 return self.prefilter_manager.get_handler_by_name('auto')
752 return self.prefilter_manager.get_handler_by_name('auto')
753 else:
753 else:
754 return None
754 return None
755
755
756
756
757 #-----------------------------------------------------------------------------
757 #-----------------------------------------------------------------------------
758 # Prefilter handlers
758 # Prefilter handlers
759 #-----------------------------------------------------------------------------
759 #-----------------------------------------------------------------------------
760
760
761
761
762 class PrefilterHandler(Configurable):
762 class PrefilterHandler(Configurable):
763
763
764 handler_name = Str('normal')
764 handler_name = Str('normal')
765 esc_strings = List([])
765 esc_strings = List([])
766 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
766 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
767 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
767 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
768
768
769 def __init__(self, shell=None, prefilter_manager=None, config=None):
769 def __init__(self, shell=None, prefilter_manager=None, config=None):
770 super(PrefilterHandler, self).__init__(
770 super(PrefilterHandler, self).__init__(
771 shell=shell, prefilter_manager=prefilter_manager, config=config
771 shell=shell, prefilter_manager=prefilter_manager, config=config
772 )
772 )
773 self.prefilter_manager.register_handler(
773 self.prefilter_manager.register_handler(
774 self.handler_name,
774 self.handler_name,
775 self,
775 self,
776 self.esc_strings
776 self.esc_strings
777 )
777 )
778
778
779 def handle(self, line_info):
779 def handle(self, line_info):
780 # print "normal: ", line_info
780 # print "normal: ", line_info
781 """Handle normal input lines. Use as a template for handlers."""
781 """Handle normal input lines. Use as a template for handlers."""
782
782
783 # With autoindent on, we need some way to exit the input loop, and I
783 # With autoindent on, we need some way to exit the input loop, and I
784 # don't want to force the user to have to backspace all the way to
784 # don't want to force the user to have to backspace all the way to
785 # clear the line. The rule will be in this case, that either two
785 # clear the line. The rule will be in this case, that either two
786 # lines of pure whitespace in a row, or a line of pure whitespace but
786 # lines of pure whitespace in a row, or a line of pure whitespace but
787 # of a size different to the indent level, will exit the input loop.
787 # of a size different to the indent level, will exit the input loop.
788 line = line_info.line
788 line = line_info.line
789 continue_prompt = line_info.continue_prompt
789 continue_prompt = line_info.continue_prompt
790
790
791 if (continue_prompt and
791 if (continue_prompt and
792 self.shell.autoindent and
792 self.shell.autoindent and
793 line.isspace() and
793 line.isspace() and
794
794
795 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2
795 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2
796 or
796 or
797 not self.shell.buffer
797 not self.shell.buffer
798 or
798 or
799 (self.shell.buffer[-1]).isspace()
799 (self.shell.buffer[-1]).isspace()
800 )
800 )
801 ):
801 ):
802 line = ''
802 line = ''
803
803
804 return line
804 return line
805
805
806 def __str__(self):
806 def __str__(self):
807 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
807 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
808
808
809
809
810 class AliasHandler(PrefilterHandler):
810 class AliasHandler(PrefilterHandler):
811
811
812 handler_name = Str('alias')
812 handler_name = Str('alias')
813
813
814 def handle(self, line_info):
814 def handle(self, line_info):
815 """Handle alias input lines. """
815 """Handle alias input lines. """
816 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
816 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
817 # pre is needed, because it carries the leading whitespace. Otherwise
817 # pre is needed, because it carries the leading whitespace. Otherwise
818 # aliases won't work in indented sections.
818 # aliases won't work in indented sections.
819 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
819 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
820 make_quoted_expr(transformed))
820 make_quoted_expr(transformed))
821
821
822 return line_out
822 return line_out
823
823
824
824
825 class ShellEscapeHandler(PrefilterHandler):
825 class ShellEscapeHandler(PrefilterHandler):
826
826
827 handler_name = Str('shell')
827 handler_name = Str('shell')
828 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
828 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
829
829
830 def handle(self, line_info):
830 def handle(self, line_info):
831 """Execute the line in a shell, empty return value"""
831 """Execute the line in a shell, empty return value"""
832 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
832 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
833
833
834 line = line_info.line
834 line = line_info.line
835 if line.lstrip().startswith(ESC_SH_CAP):
835 if line.lstrip().startswith(ESC_SH_CAP):
836 # rewrite LineInfo's line, ifun and the_rest to properly hold the
836 # rewrite LineInfo's line, ifun and the_rest to properly hold the
837 # call to %sx and the actual command to be executed, so
837 # call to %sx and the actual command to be executed, so
838 # handle_magic can work correctly. Note that this works even if
838 # handle_magic can work correctly. Note that this works even if
839 # the line is indented, so it handles multi_line_specials
839 # the line is indented, so it handles multi_line_specials
840 # properly.
840 # properly.
841 new_rest = line.lstrip()[2:]
841 new_rest = line.lstrip()[2:]
842 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
842 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
843 line_info.ifun = 'sx'
843 line_info.ifun = 'sx'
844 line_info.the_rest = new_rest
844 line_info.the_rest = new_rest
845 return magic_handler.handle(line_info)
845 return magic_handler.handle(line_info)
846 else:
846 else:
847 cmd = line.lstrip().lstrip(ESC_SHELL)
847 cmd = line.lstrip().lstrip(ESC_SHELL)
848 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
848 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
849 make_quoted_expr(cmd))
849 make_quoted_expr(cmd))
850 return line_out
850 return line_out
851
851
852
852
853 class MacroHandler(PrefilterHandler):
853 class MacroHandler(PrefilterHandler):
854 handler_name = Str("macro")
854 handler_name = Str("macro")
855
855
856 def handle(self, line_info):
856 def handle(self, line_info):
857 obj = self.shell.user_ns.get(line_info.ifun)
857 obj = self.shell.user_ns.get(line_info.ifun)
858 pre_space = line_info.pre_whitespace
858 pre_space = line_info.pre_whitespace
859 line_sep = "\n" + pre_space
859 line_sep = "\n" + pre_space
860 return pre_space + line_sep.join(obj.value.splitlines())
860 return pre_space + line_sep.join(obj.value.splitlines())
861
861
862
862
863 class MagicHandler(PrefilterHandler):
863 class MagicHandler(PrefilterHandler):
864
864
865 handler_name = Str('magic')
865 handler_name = Str('magic')
866 esc_strings = List([ESC_MAGIC])
866 esc_strings = List([ESC_MAGIC])
867
867
868 def handle(self, line_info):
868 def handle(self, line_info):
869 """Execute magic functions."""
869 """Execute magic functions."""
870 ifun = line_info.ifun
870 ifun = line_info.ifun
871 the_rest = line_info.the_rest
871 the_rest = line_info.the_rest
872 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
872 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
873 make_quoted_expr(ifun + " " + the_rest))
873 make_quoted_expr(ifun + " " + the_rest))
874 return cmd
874 return cmd
875
875
876
876
877 class AutoHandler(PrefilterHandler):
877 class AutoHandler(PrefilterHandler):
878
878
879 handler_name = Str('auto')
879 handler_name = Str('auto')
880 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
880 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
881
881
882 def handle(self, line_info):
882 def handle(self, line_info):
883 """Handle lines which can be auto-executed, quoting if requested."""
883 """Handle lines which can be auto-executed, quoting if requested."""
884 line = line_info.line
884 line = line_info.line
885 ifun = line_info.ifun
885 ifun = line_info.ifun
886 the_rest = line_info.the_rest
886 the_rest = line_info.the_rest
887 pre = line_info.pre
887 pre = line_info.pre
888 continue_prompt = line_info.continue_prompt
888 continue_prompt = line_info.continue_prompt
889 obj = line_info.ofind(self)['obj']
889 obj = line_info.ofind(self)['obj']
890 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
890 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
891
891
892 # This should only be active for single-line input!
892 # This should only be active for single-line input!
893 if continue_prompt:
893 if continue_prompt:
894 return line
894 return line
895
895
896 force_auto = isinstance(obj, IPyAutocall)
896 force_auto = isinstance(obj, IPyAutocall)
897 auto_rewrite = True
897 auto_rewrite = getattr(obj, 'rewrite', True)
898
898
899 if pre == ESC_QUOTE:
899 if pre == ESC_QUOTE:
900 # Auto-quote splitting on whitespace
900 # Auto-quote splitting on whitespace
901 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
901 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
902 elif pre == ESC_QUOTE2:
902 elif pre == ESC_QUOTE2:
903 # Auto-quote whole string
903 # Auto-quote whole string
904 newcmd = '%s("%s")' % (ifun,the_rest)
904 newcmd = '%s("%s")' % (ifun,the_rest)
905 elif pre == ESC_PAREN:
905 elif pre == ESC_PAREN:
906 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
906 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
907 else:
907 else:
908 # Auto-paren.
908 # Auto-paren.
909 # We only apply it to argument-less calls if the autocall
909 # We only apply it to argument-less calls if the autocall
910 # parameter is set to 2. We only need to check that autocall is <
910 # parameter is set to 2. We only need to check that autocall is <
911 # 2, since this function isn't called unless it's at least 1.
911 # 2, since this function isn't called unless it's at least 1.
912 if not the_rest and (self.shell.autocall < 2) and not force_auto:
912 if not the_rest and (self.shell.autocall < 2) and not force_auto:
913 newcmd = '%s %s' % (ifun,the_rest)
913 newcmd = '%s %s' % (ifun,the_rest)
914 auto_rewrite = False
914 auto_rewrite = False
915 else:
915 else:
916 if not force_auto and the_rest.startswith('['):
916 if not force_auto and the_rest.startswith('['):
917 if hasattr(obj,'__getitem__'):
917 if hasattr(obj,'__getitem__'):
918 # Don't autocall in this case: item access for an object
918 # Don't autocall in this case: item access for an object
919 # which is BOTH callable and implements __getitem__.
919 # which is BOTH callable and implements __getitem__.
920 newcmd = '%s %s' % (ifun,the_rest)
920 newcmd = '%s %s' % (ifun,the_rest)
921 auto_rewrite = False
921 auto_rewrite = False
922 else:
922 else:
923 # if the object doesn't support [] access, go ahead and
923 # if the object doesn't support [] access, go ahead and
924 # autocall
924 # autocall
925 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
925 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
926 elif the_rest.endswith(';'):
926 elif the_rest.endswith(';'):
927 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
927 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
928 else:
928 else:
929 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
929 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
930
930
931 if auto_rewrite:
931 if auto_rewrite:
932 self.shell.auto_rewrite_input(newcmd)
932 self.shell.auto_rewrite_input(newcmd)
933
933
934 return newcmd
934 return newcmd
935
935
936
936
937 class HelpHandler(PrefilterHandler):
937 class HelpHandler(PrefilterHandler):
938
938
939 handler_name = Str('help')
939 handler_name = Str('help')
940 esc_strings = List([ESC_HELP])
940 esc_strings = List([ESC_HELP])
941
941
942 def handle(self, line_info):
942 def handle(self, line_info):
943 """Try to get some help for the object.
943 """Try to get some help for the object.
944
944
945 obj? or ?obj -> basic information.
945 obj? or ?obj -> basic information.
946 obj?? or ??obj -> more details.
946 obj?? or ??obj -> more details.
947 """
947 """
948 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
948 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
949 line = line_info.line
949 line = line_info.line
950 # We need to make sure that we don't process lines which would be
950 # We need to make sure that we don't process lines which would be
951 # otherwise valid python, such as "x=1 # what?"
951 # otherwise valid python, such as "x=1 # what?"
952 try:
952 try:
953 codeop.compile_command(line)
953 codeop.compile_command(line)
954 except SyntaxError:
954 except SyntaxError:
955 # We should only handle as help stuff which is NOT valid syntax
955 # We should only handle as help stuff which is NOT valid syntax
956 if line[0]==ESC_HELP:
956 if line[0]==ESC_HELP:
957 line = line[1:]
957 line = line[1:]
958 elif line[-1]==ESC_HELP:
958 elif line[-1]==ESC_HELP:
959 line = line[:-1]
959 line = line[:-1]
960 if line:
960 if line:
961 #print 'line:<%r>' % line # dbg
961 #print 'line:<%r>' % line # dbg
962 self.shell.magic_pinfo(line)
962 self.shell.magic_pinfo(line)
963 else:
963 else:
964 self.shell.show_usage()
964 self.shell.show_usage()
965 return '' # Empty string is needed here!
965 return '' # Empty string is needed here!
966 except:
966 except:
967 raise
967 raise
968 # Pass any other exceptions through to the normal handler
968 # Pass any other exceptions through to the normal handler
969 return normal_handler.handle(line_info)
969 return normal_handler.handle(line_info)
970 else:
970 else:
971 # If the code compiles ok, we should handle it normally
971 # If the code compiles ok, we should handle it normally
972 return normal_handler.handle(line_info)
972 return normal_handler.handle(line_info)
973
973
974
974
975 class EmacsHandler(PrefilterHandler):
975 class EmacsHandler(PrefilterHandler):
976
976
977 handler_name = Str('emacs')
977 handler_name = Str('emacs')
978 esc_strings = List([])
978 esc_strings = List([])
979
979
980 def handle(self, line_info):
980 def handle(self, line_info):
981 """Handle input lines marked by python-mode."""
981 """Handle input lines marked by python-mode."""
982
982
983 # Currently, nothing is done. Later more functionality can be added
983 # Currently, nothing is done. Later more functionality can be added
984 # here if needed.
984 # here if needed.
985
985
986 # The input cache shouldn't be updated
986 # The input cache shouldn't be updated
987 return line_info.line
987 return line_info.line
988
988
989
989
990 #-----------------------------------------------------------------------------
990 #-----------------------------------------------------------------------------
991 # Defaults
991 # Defaults
992 #-----------------------------------------------------------------------------
992 #-----------------------------------------------------------------------------
993
993
994
994
995 _default_transformers = [
995 _default_transformers = [
996 AssignSystemTransformer,
996 AssignSystemTransformer,
997 AssignMagicTransformer,
997 AssignMagicTransformer,
998 PyPromptTransformer,
998 PyPromptTransformer,
999 IPyPromptTransformer,
999 IPyPromptTransformer,
1000 ]
1000 ]
1001
1001
1002 _default_checkers = [
1002 _default_checkers = [
1003 EmacsChecker,
1003 EmacsChecker,
1004 ShellEscapeChecker,
1004 ShellEscapeChecker,
1005 MacroChecker,
1005 MacroChecker,
1006 IPyAutocallChecker,
1006 IPyAutocallChecker,
1007 MultiLineMagicChecker,
1007 MultiLineMagicChecker,
1008 EscCharsChecker,
1008 EscCharsChecker,
1009 AssignmentChecker,
1009 AssignmentChecker,
1010 AutoMagicChecker,
1010 AutoMagicChecker,
1011 AliasChecker,
1011 AliasChecker,
1012 PythonOpsChecker,
1012 PythonOpsChecker,
1013 AutocallChecker
1013 AutocallChecker
1014 ]
1014 ]
1015
1015
1016 _default_handlers = [
1016 _default_handlers = [
1017 PrefilterHandler,
1017 PrefilterHandler,
1018 AliasHandler,
1018 AliasHandler,
1019 ShellEscapeHandler,
1019 ShellEscapeHandler,
1020 MacroHandler,
1020 MacroHandler,
1021 MagicHandler,
1021 MagicHandler,
1022 AutoHandler,
1022 AutoHandler,
1023 HelpHandler,
1023 HelpHandler,
1024 EmacsHandler
1024 EmacsHandler
1025 ]
1025 ]
General Comments 0
You need to be logged in to leave comments. Login now