##// END OF EJS Templates
Remove args/kwargs handling in TryNext....
Bradley M. Froehle -
Show More
@@ -1,66 +1,53 b''
1 1 # encoding: utf-8
2 2 """
3 3 Global exception classes for IPython.core.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Min Ragan-Kelley
10 10
11 11 Notes
12 12 -----
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Copyright (C) 2008-2011 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Exception classes
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class IPythonCoreError(Exception):
31 31 pass
32 32
33 33
34 34 class TryNext(IPythonCoreError):
35 35 """Try next hook exception.
36 36
37 37 Raise this in your hook function to indicate that the next hook handler
38 should be used to handle the operation. If you pass arguments to the
39 constructor those arguments will be used by the next hook instead of the
40 original ones.
41
42 A _msg argument will not be passed on, so it can be used as a displayable
43 error message.
38 should be used to handle the operation.
44 39 """
45 40
46 def __init__(self, _msg="", *args, **kwargs):
47 self.args = args
48 self.kwargs = kwargs
49 self.msg = _msg
50
51 def __str__(self):
52 return str(self.msg)
53
54 41 class UsageError(IPythonCoreError):
55 42 """Error in magic function arguments, etc.
56 43
57 44 Something that probably won't warrant a full traceback, but should
58 45 nevertheless interrupt a macro / batch file.
59 46 """
60 47
61 48 class StdinNotImplementedError(IPythonCoreError, NotImplementedError):
62 49 """raw_input was requested in a context where it is not supported
63 50
64 51 For use in IPython kernels, where only some frontends may support
65 52 stdin requests.
66 53 """
@@ -1,231 +1,229 b''
1 1 """hooks for IPython.
2 2
3 3 In Python, it is possible to overwrite any method of any object if you really
4 4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
5 5 be overwritten by users for customization purposes. This module defines the
6 6 default versions of all such hooks, which get used by IPython if not
7 7 overridden by the user.
8 8
9 9 hooks are simple functions, but they should be declared with 'self' as their
10 10 first argument, because when activated they are registered into IPython as
11 11 instance methods. The self argument will be the IPython running instance
12 12 itself, so hooks have full access to the entire IPython object.
13 13
14 14 If you wish to define a new hook and activate it, you need to put the
15 15 necessary code into a python file which can be either imported or execfile()'d
16 16 from within your profile's ipython_config.py configuration.
17 17
18 18 For example, suppose that you have a module called 'myiphooks' in your
19 19 PYTHONPATH, which contains the following definition:
20 20
21 21 import os
22 22 from IPython.core import ipapi
23 23 ip = ipapi.get()
24 24
25 25 def calljed(self,filename, linenum):
26 26 "My editor hook calls the jed editor directly."
27 27 print "Calling my own editor, jed ..."
28 28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
29 29 raise TryNext()
30 30
31 31 ip.set_hook('editor', calljed)
32 32
33 33 You can then enable the functionality by doing 'import myiphooks'
34 34 somewhere in your configuration files or ipython command line.
35 35 """
36 36
37 37 #*****************************************************************************
38 38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
39 39 #
40 40 # Distributed under the terms of the BSD License. The full license is in
41 41 # the file COPYING, distributed as part of this software.
42 42 #*****************************************************************************
43 43
44 44 import os, bisect
45 45 import subprocess
46 46 import sys
47 47
48 48 from IPython.core.error import TryNext
49 49
50 50 # List here all the default hooks. For now it's just the editor functions
51 51 # but over time we'll move here all the public API for user-accessible things.
52 52
53 53 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
54 54 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
55 55 'show_in_pager','pre_prompt_hook',
56 56 'pre_run_code_hook', 'clipboard_get']
57 57
58 58 def editor(self, filename, linenum=None, wait=True):
59 59 """Open the default editor at the given filename and linenumber.
60 60
61 61 This is IPython's default editor hook, you can use it as an example to
62 62 write your own modified one. To set your own editor function as the
63 63 new editor hook, call ip.set_hook('editor',yourfunc)."""
64 64
65 65 # IPython configures a default editor at startup by reading $EDITOR from
66 66 # the environment, and falling back on vi (unix) or notepad (win32).
67 67 editor = self.editor
68 68
69 69 # marker for at which line to open the file (for existing objects)
70 70 if linenum is None or editor=='notepad':
71 71 linemark = ''
72 72 else:
73 73 linemark = '+%d' % int(linenum)
74 74
75 75 # Enclose in quotes if necessary and legal
76 76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
77 77 editor = '"%s"' % editor
78 78
79 79 # Call the actual editor
80 80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
81 81 shell=True)
82 82 if wait and proc.wait() != 0:
83 83 raise TryNext()
84 84
85 85 import tempfile
86 86 def fix_error_editor(self,filename,linenum,column,msg):
87 87 """Open the editor at the given filename, linenumber, column and
88 88 show an error message. This is used for correcting syntax errors.
89 89 The current implementation only has special support for the VIM editor,
90 90 and falls back on the 'editor' hook if VIM is not used.
91 91
92 92 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
93 93 """
94 94 def vim_quickfix_file():
95 95 t = tempfile.NamedTemporaryFile()
96 96 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
97 97 t.flush()
98 98 return t
99 99 if os.path.basename(self.editor) != 'vim':
100 100 self.hooks.editor(filename,linenum)
101 101 return
102 102 t = vim_quickfix_file()
103 103 try:
104 104 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
105 105 raise TryNext()
106 106 finally:
107 107 t.close()
108 108
109 109
110 110 def synchronize_with_editor(self, filename, linenum, column):
111 111 pass
112 112
113 113
114 114 class CommandChainDispatcher:
115 115 """ Dispatch calls to a chain of commands until some func can handle it
116 116
117 117 Usage: instantiate, execute "add" to add commands (with optional
118 118 priority), execute normally via f() calling mechanism.
119 119
120 120 """
121 121 def __init__(self,commands=None):
122 122 if commands is None:
123 123 self.chain = []
124 124 else:
125 125 self.chain = commands
126 126
127 127
128 128 def __call__(self,*args, **kw):
129 129 """ Command chain is called just like normal func.
130 130
131 131 This will call all funcs in chain with the same args as were given to
132 132 this function, and return the result of first func that didn't raise
133 133 TryNext"""
134
134 last_exc = TryNext()
135 135 for prio,cmd in self.chain:
136 136 #print "prio",prio,"cmd",cmd #dbg
137 137 try:
138 138 return cmd(*args, **kw)
139 except TryNext, exc:
140 if exc.args or exc.kwargs:
141 args = exc.args
142 kw = exc.kwargs
139 except TryNext as exc:
140 last_exc = exc
143 141 # if no function will accept it, raise TryNext up to the caller
144 raise TryNext(*args, **kw)
142 raise last_exc
145 143
146 144 def __str__(self):
147 145 return str(self.chain)
148 146
149 147 def add(self, func, priority=0):
150 148 """ Add a func to the cmd chain with given priority """
151 149 bisect.insort(self.chain,(priority,func))
152 150
153 151 def __iter__(self):
154 152 """ Return all objects in chain.
155 153
156 154 Handy if the objects are not callable.
157 155 """
158 156 return iter(self.chain)
159 157
160 158
161 159 def input_prefilter(self,line):
162 160 """ Default input prefilter
163 161
164 162 This returns the line as unchanged, so that the interpreter
165 163 knows that nothing was done and proceeds with "classic" prefiltering
166 164 (%magics, !shell commands etc.).
167 165
168 166 Note that leading whitespace is not passed to this hook. Prefilter
169 167 can't alter indentation.
170 168
171 169 """
172 170 #print "attempt to rewrite",line #dbg
173 171 return line
174 172
175 173
176 174 def shutdown_hook(self):
177 175 """ default shutdown hook
178 176
179 177 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
180 178 """
181 179
182 180 #print "default shutdown hook ok" # dbg
183 181 return
184 182
185 183
186 184 def late_startup_hook(self):
187 185 """ Executed after ipython has been constructed and configured
188 186
189 187 """
190 188 #print "default startup hook ok" # dbg
191 189
192 190
193 191 def show_in_pager(self,s):
194 192 """ Run a string through pager """
195 193 # raising TryNext here will use the default paging functionality
196 194 raise TryNext
197 195
198 196
199 197 def pre_prompt_hook(self):
200 198 """ Run before displaying the next prompt
201 199
202 200 Use this e.g. to display output from asynchronous operations (in order
203 201 to not mess up text entry)
204 202 """
205 203
206 204 return None
207 205
208 206
209 207 def pre_run_code_hook(self):
210 208 """ Executed before running the (prefiltered) code in IPython """
211 209 return None
212 210
213 211
214 212 def clipboard_get(self):
215 213 """ Get text from the clipboard.
216 214 """
217 215 from IPython.lib.clipboard import (
218 216 osx_clipboard_get, tkinter_clipboard_get,
219 217 win32_clipboard_get
220 218 )
221 219 if sys.platform == 'win32':
222 220 chain = [win32_clipboard_get, tkinter_clipboard_get]
223 221 elif sys.platform == 'darwin':
224 222 chain = [osx_clipboard_get, tkinter_clipboard_get]
225 223 else:
226 224 chain = [tkinter_clipboard_get]
227 225 dispatcher = CommandChainDispatcher()
228 226 for func in chain:
229 227 dispatcher.add(func)
230 228 text = dispatcher()
231 229 return text
@@ -1,56 +1,54 b''
1 1 """ Utilities for accessing the platform's clipboard.
2 2 """
3 3
4 4 import subprocess
5 5 import sys
6 6
7 7 from IPython.core.error import TryNext
8 8
9 9
10 10 def win32_clipboard_get():
11 11 """ Get the current clipboard's text on Windows.
12 12
13 13 Requires Mark Hammond's pywin32 extensions.
14 14 """
15 15 try:
16 16 import win32clipboard
17 17 except ImportError:
18 message = ("Getting text from the clipboard requires the pywin32 "
19 "extensions: http://sourceforge.net/projects/pywin32/")
20 raise TryNext(_msg=message)
18 raise TryNext("Getting text from the clipboard requires the pywin32 "
19 "extensions: http://sourceforge.net/projects/pywin32/")
21 20 win32clipboard.OpenClipboard()
22 21 text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
23 22 # FIXME: convert \r\n to \n?
24 23 win32clipboard.CloseClipboard()
25 24 return text
26 25
27 26 def osx_clipboard_get():
28 27 """ Get the clipboard's text on OS X.
29 28 """
30 29 p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'],
31 30 stdout=subprocess.PIPE)
32 31 text, stderr = p.communicate()
33 32 # Text comes in with old Mac \r line endings. Change them to \n.
34 33 text = text.replace('\r', '\n')
35 34 return text
36 35
37 36 def tkinter_clipboard_get():
38 37 """ Get the clipboard's text using Tkinter.
39 38
40 39 This is the default on systems that are not Windows or OS X. It may
41 40 interfere with other UI toolkits and should be replaced with an
42 41 implementation that uses that toolkit.
43 42 """
44 43 try:
45 44 import Tkinter
46 45 except ImportError:
47 message = ("Getting text from the clipboard on this platform "
48 "requires Tkinter.")
49 raise TryNext(_msg=message)
46 raise TryNext("Getting text from the clipboard on this platform "
47 "requires Tkinter.")
50 48 root = Tkinter.Tk()
51 49 root.withdraw()
52 50 text = root.clipboard_get()
53 51 root.destroy()
54 52 return text
55 53
56 54
@@ -1,27 +1,35 b''
1 1 =====================
2 2 Development version
3 3 =====================
4 4
5 5 This document describes in-flight development work.
6 6
7 7 Redesigned IPython notebook user interface
8 8 ------------------------------------------
9 9
10 10 .. add details
11 11
12 12 Other new features
13 13 ------------------
14 14
15 15 * **%install_ext**: A new magic function to install an IPython extension from
16 16 a URL. E.g. ``%install_ext https://bitbucket.org/birkenfeld/ipython-physics/raw/d1310a2ab15d/physics.py``.
17 17
18 18 * The :envvar:`IPYTHON_DIR` environment variable, introduced in the Great
19 19 Reorganization of 0.11 and existing only in versions 0.11-0.13, has been
20 20 deprecated. As described in :ghissue:`1167`, the complexity and confusion of
21 21 migrating to this variable is not worth the aesthetic improvement. Please use
22 22 the historical :envvar:`IPYTHONDIR` environment variable instead.
23 23
24 24 * The default value of *interactivity* passed from
25 25 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` to
26 26 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_ast_nodes`
27 27 is now configurable.
28
29 Backwards incompatible changes
30 ------------------------------
31
32 * The exception :exc:`IPython.core.error.TryNext` previously accepted
33 arguments and keyword arguments to be passed to the next implementation
34 of the hook. This feature was removed as it made error message propagation
35 difficult and violated the principle of loose coupling.
General Comments 0
You need to be logged in to leave comments. Login now