##// END OF EJS Templates
move safe_unicode to py3compat
MinRK -
Show More
@@ -1,618 +1,597 b''
1 """A ZMQ-based subclass of InteractiveShell.
1 """A ZMQ-based subclass of InteractiveShell.
2
2
3 This code is meant to ease the refactoring of the base InteractiveShell into
3 This code is meant to ease the refactoring of the base InteractiveShell into
4 something with a cleaner architecture for 2-process use, without actually
4 something with a cleaner architecture for 2-process use, without actually
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 we subclass and override what we want to fix. Once this is working well, we
6 we subclass and override what we want to fix. Once this is working well, we
7 can go back to the base class and refactor the code for a cleaner inheritance
7 can go back to the base class and refactor the code for a cleaner inheritance
8 implementation that doesn't rely on so much monkeypatching.
8 implementation that doesn't rely on so much monkeypatching.
9
9
10 But this lets us maintain a fully working IPython as we develop the new
10 But this lets us maintain a fully working IPython as we develop the new
11 machinery. This should thus be thought of as scaffolding.
11 machinery. This should thus be thought of as scaffolding.
12 """
12 """
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from __future__ import print_function
16 from __future__ import print_function
17
17
18 # Stdlib
18 # Stdlib
19 import os
19 import os
20 import sys
20 import sys
21 import time
21 import time
22
22
23 # System library imports
23 # System library imports
24 from zmq.eventloop import ioloop
24 from zmq.eventloop import ioloop
25
25
26 # Our own
26 # Our own
27 from IPython.core.interactiveshell import (
27 from IPython.core.interactiveshell import (
28 InteractiveShell, InteractiveShellABC
28 InteractiveShell, InteractiveShellABC
29 )
29 )
30 from IPython.core import page
30 from IPython.core import page
31 from IPython.core.autocall import ZMQExitAutocall
31 from IPython.core.autocall import ZMQExitAutocall
32 from IPython.core.displaypub import DisplayPublisher
32 from IPython.core.displaypub import DisplayPublisher
33 from IPython.core.error import UsageError
33 from IPython.core.error import UsageError
34 from IPython.core.magics import MacroToEdit, CodeMagics
34 from IPython.core.magics import MacroToEdit, CodeMagics
35 from IPython.core.magic import magics_class, line_magic, Magics
35 from IPython.core.magic import magics_class, line_magic, Magics
36 from IPython.core.payloadpage import install_payload_page
36 from IPython.core.payloadpage import install_payload_page
37 from IPython.display import display, Javascript
37 from IPython.display import display, Javascript
38 from IPython.kernel.inprocess.socket import SocketABC
38 from IPython.kernel.inprocess.socket import SocketABC
39 from IPython.kernel import (
39 from IPython.kernel import (
40 get_connection_file, get_connection_info, connect_qtconsole
40 get_connection_file, get_connection_info, connect_qtconsole
41 )
41 )
42 from IPython.testing.skipdoctest import skip_doctest
42 from IPython.testing.skipdoctest import skip_doctest
43 from IPython.utils import io, openpy
43 from IPython.utils import io, openpy
44 from IPython.utils.jsonutil import json_clean, encode_images
44 from IPython.utils.jsonutil import json_clean, encode_images
45 from IPython.utils.process import arg_split
45 from IPython.utils.process import arg_split
46 from IPython.utils import py3compat
46 from IPython.utils import py3compat
47 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
47 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
48 from IPython.utils.warn import warn, error
48 from IPython.utils.warn import warn, error
49 from IPython.kernel.zmq.displayhook import ZMQShellDisplayHook
49 from IPython.kernel.zmq.displayhook import ZMQShellDisplayHook
50 from IPython.kernel.zmq.datapub import ZMQDataPublisher
50 from IPython.kernel.zmq.datapub import ZMQDataPublisher
51 from IPython.kernel.zmq.session import extract_header
51 from IPython.kernel.zmq.session import extract_header
52 from session import Session
52 from session import Session
53
53
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55 # Functions and classes
55 # Functions and classes
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57
57
58 class ZMQDisplayPublisher(DisplayPublisher):
58 class ZMQDisplayPublisher(DisplayPublisher):
59 """A display publisher that publishes data using a ZeroMQ PUB socket."""
59 """A display publisher that publishes data using a ZeroMQ PUB socket."""
60
60
61 session = Instance(Session)
61 session = Instance(Session)
62 pub_socket = Instance(SocketABC)
62 pub_socket = Instance(SocketABC)
63 parent_header = Dict({})
63 parent_header = Dict({})
64 topic = CBytes(b'displaypub')
64 topic = CBytes(b'displaypub')
65
65
66 def set_parent(self, parent):
66 def set_parent(self, parent):
67 """Set the parent for outbound messages."""
67 """Set the parent for outbound messages."""
68 self.parent_header = extract_header(parent)
68 self.parent_header = extract_header(parent)
69
69
70 def _flush_streams(self):
70 def _flush_streams(self):
71 """flush IO Streams prior to display"""
71 """flush IO Streams prior to display"""
72 sys.stdout.flush()
72 sys.stdout.flush()
73 sys.stderr.flush()
73 sys.stderr.flush()
74
74
75 def publish(self, source, data, metadata=None):
75 def publish(self, source, data, metadata=None):
76 self._flush_streams()
76 self._flush_streams()
77 if metadata is None:
77 if metadata is None:
78 metadata = {}
78 metadata = {}
79 self._validate_data(source, data, metadata)
79 self._validate_data(source, data, metadata)
80 content = {}
80 content = {}
81 content['source'] = source
81 content['source'] = source
82 content['data'] = encode_images(data)
82 content['data'] = encode_images(data)
83 content['metadata'] = metadata
83 content['metadata'] = metadata
84 self.session.send(
84 self.session.send(
85 self.pub_socket, u'display_data', json_clean(content),
85 self.pub_socket, u'display_data', json_clean(content),
86 parent=self.parent_header, ident=self.topic,
86 parent=self.parent_header, ident=self.topic,
87 )
87 )
88
88
89 def clear_output(self, stdout=True, stderr=True, other=True):
89 def clear_output(self, stdout=True, stderr=True, other=True):
90 content = dict(stdout=stdout, stderr=stderr, other=other)
90 content = dict(stdout=stdout, stderr=stderr, other=other)
91
91
92 if stdout:
92 if stdout:
93 print('\r', file=sys.stdout, end='')
93 print('\r', file=sys.stdout, end='')
94 if stderr:
94 if stderr:
95 print('\r', file=sys.stderr, end='')
95 print('\r', file=sys.stderr, end='')
96
96
97 self._flush_streams()
97 self._flush_streams()
98
98
99 self.session.send(
99 self.session.send(
100 self.pub_socket, u'clear_output', content,
100 self.pub_socket, u'clear_output', content,
101 parent=self.parent_header, ident=self.topic,
101 parent=self.parent_header, ident=self.topic,
102 )
102 )
103
103
104 @magics_class
104 @magics_class
105 class KernelMagics(Magics):
105 class KernelMagics(Magics):
106 #------------------------------------------------------------------------
106 #------------------------------------------------------------------------
107 # Magic overrides
107 # Magic overrides
108 #------------------------------------------------------------------------
108 #------------------------------------------------------------------------
109 # Once the base class stops inheriting from magic, this code needs to be
109 # Once the base class stops inheriting from magic, this code needs to be
110 # moved into a separate machinery as well. For now, at least isolate here
110 # moved into a separate machinery as well. For now, at least isolate here
111 # the magics which this class needs to implement differently from the base
111 # the magics which this class needs to implement differently from the base
112 # class, or that are unique to it.
112 # class, or that are unique to it.
113
113
114 @line_magic
114 @line_magic
115 def doctest_mode(self, parameter_s=''):
115 def doctest_mode(self, parameter_s=''):
116 """Toggle doctest mode on and off.
116 """Toggle doctest mode on and off.
117
117
118 This mode is intended to make IPython behave as much as possible like a
118 This mode is intended to make IPython behave as much as possible like a
119 plain Python shell, from the perspective of how its prompts, exceptions
119 plain Python shell, from the perspective of how its prompts, exceptions
120 and output look. This makes it easy to copy and paste parts of a
120 and output look. This makes it easy to copy and paste parts of a
121 session into doctests. It does so by:
121 session into doctests. It does so by:
122
122
123 - Changing the prompts to the classic ``>>>`` ones.
123 - Changing the prompts to the classic ``>>>`` ones.
124 - Changing the exception reporting mode to 'Plain'.
124 - Changing the exception reporting mode to 'Plain'.
125 - Disabling pretty-printing of output.
125 - Disabling pretty-printing of output.
126
126
127 Note that IPython also supports the pasting of code snippets that have
127 Note that IPython also supports the pasting of code snippets that have
128 leading '>>>' and '...' prompts in them. This means that you can paste
128 leading '>>>' and '...' prompts in them. This means that you can paste
129 doctests from files or docstrings (even if they have leading
129 doctests from files or docstrings (even if they have leading
130 whitespace), and the code will execute correctly. You can then use
130 whitespace), and the code will execute correctly. You can then use
131 '%history -t' to see the translated history; this will give you the
131 '%history -t' to see the translated history; this will give you the
132 input after removal of all the leading prompts and whitespace, which
132 input after removal of all the leading prompts and whitespace, which
133 can be pasted back into an editor.
133 can be pasted back into an editor.
134
134
135 With these features, you can switch into this mode easily whenever you
135 With these features, you can switch into this mode easily whenever you
136 need to do testing and changes to doctests, without having to leave
136 need to do testing and changes to doctests, without having to leave
137 your existing IPython session.
137 your existing IPython session.
138 """
138 """
139
139
140 from IPython.utils.ipstruct import Struct
140 from IPython.utils.ipstruct import Struct
141
141
142 # Shorthands
142 # Shorthands
143 shell = self.shell
143 shell = self.shell
144 disp_formatter = self.shell.display_formatter
144 disp_formatter = self.shell.display_formatter
145 ptformatter = disp_formatter.formatters['text/plain']
145 ptformatter = disp_formatter.formatters['text/plain']
146 # dstore is a data store kept in the instance metadata bag to track any
146 # dstore is a data store kept in the instance metadata bag to track any
147 # changes we make, so we can undo them later.
147 # changes we make, so we can undo them later.
148 dstore = shell.meta.setdefault('doctest_mode', Struct())
148 dstore = shell.meta.setdefault('doctest_mode', Struct())
149 save_dstore = dstore.setdefault
149 save_dstore = dstore.setdefault
150
150
151 # save a few values we'll need to recover later
151 # save a few values we'll need to recover later
152 mode = save_dstore('mode', False)
152 mode = save_dstore('mode', False)
153 save_dstore('rc_pprint', ptformatter.pprint)
153 save_dstore('rc_pprint', ptformatter.pprint)
154 save_dstore('rc_active_types',disp_formatter.active_types)
154 save_dstore('rc_active_types',disp_formatter.active_types)
155 save_dstore('xmode', shell.InteractiveTB.mode)
155 save_dstore('xmode', shell.InteractiveTB.mode)
156
156
157 if mode == False:
157 if mode == False:
158 # turn on
158 # turn on
159 ptformatter.pprint = False
159 ptformatter.pprint = False
160 disp_formatter.active_types = ['text/plain']
160 disp_formatter.active_types = ['text/plain']
161 shell.magic('xmode Plain')
161 shell.magic('xmode Plain')
162 else:
162 else:
163 # turn off
163 # turn off
164 ptformatter.pprint = dstore.rc_pprint
164 ptformatter.pprint = dstore.rc_pprint
165 disp_formatter.active_types = dstore.rc_active_types
165 disp_formatter.active_types = dstore.rc_active_types
166 shell.magic("xmode " + dstore.xmode)
166 shell.magic("xmode " + dstore.xmode)
167
167
168 # Store new mode and inform on console
168 # Store new mode and inform on console
169 dstore.mode = bool(1-int(mode))
169 dstore.mode = bool(1-int(mode))
170 mode_label = ['OFF','ON'][dstore.mode]
170 mode_label = ['OFF','ON'][dstore.mode]
171 print('Doctest mode is:', mode_label)
171 print('Doctest mode is:', mode_label)
172
172
173 # Send the payload back so that clients can modify their prompt display
173 # Send the payload back so that clients can modify their prompt display
174 payload = dict(
174 payload = dict(
175 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.doctest_mode',
175 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.doctest_mode',
176 mode=dstore.mode)
176 mode=dstore.mode)
177 shell.payload_manager.write_payload(payload)
177 shell.payload_manager.write_payload(payload)
178
178
179
179
180 _find_edit_target = CodeMagics._find_edit_target
180 _find_edit_target = CodeMagics._find_edit_target
181
181
182 @skip_doctest
182 @skip_doctest
183 @line_magic
183 @line_magic
184 def edit(self, parameter_s='', last_call=['','']):
184 def edit(self, parameter_s='', last_call=['','']):
185 """Bring up an editor and execute the resulting code.
185 """Bring up an editor and execute the resulting code.
186
186
187 Usage:
187 Usage:
188 %edit [options] [args]
188 %edit [options] [args]
189
189
190 %edit runs an external text editor. You will need to set the command for
190 %edit runs an external text editor. You will need to set the command for
191 this editor via the ``TerminalInteractiveShell.editor`` option in your
191 this editor via the ``TerminalInteractiveShell.editor`` option in your
192 configuration file before it will work.
192 configuration file before it will work.
193
193
194 This command allows you to conveniently edit multi-line code right in
194 This command allows you to conveniently edit multi-line code right in
195 your IPython session.
195 your IPython session.
196
196
197 If called without arguments, %edit opens up an empty editor with a
197 If called without arguments, %edit opens up an empty editor with a
198 temporary file and will execute the contents of this file when you
198 temporary file and will execute the contents of this file when you
199 close it (don't forget to save it!).
199 close it (don't forget to save it!).
200
200
201
201
202 Options:
202 Options:
203
203
204 -n <number>: open the editor at a specified line number. By default,
204 -n <number>: open the editor at a specified line number. By default,
205 the IPython editor hook uses the unix syntax 'editor +N filename', but
205 the IPython editor hook uses the unix syntax 'editor +N filename', but
206 you can configure this by providing your own modified hook if your
206 you can configure this by providing your own modified hook if your
207 favorite editor supports line-number specifications with a different
207 favorite editor supports line-number specifications with a different
208 syntax.
208 syntax.
209
209
210 -p: this will call the editor with the same data as the previous time
210 -p: this will call the editor with the same data as the previous time
211 it was used, regardless of how long ago (in your current session) it
211 it was used, regardless of how long ago (in your current session) it
212 was.
212 was.
213
213
214 -r: use 'raw' input. This option only applies to input taken from the
214 -r: use 'raw' input. This option only applies to input taken from the
215 user's history. By default, the 'processed' history is used, so that
215 user's history. By default, the 'processed' history is used, so that
216 magics are loaded in their transformed version to valid Python. If
216 magics are loaded in their transformed version to valid Python. If
217 this option is given, the raw input as typed as the command line is
217 this option is given, the raw input as typed as the command line is
218 used instead. When you exit the editor, it will be executed by
218 used instead. When you exit the editor, it will be executed by
219 IPython's own processor.
219 IPython's own processor.
220
220
221 -x: do not execute the edited code immediately upon exit. This is
221 -x: do not execute the edited code immediately upon exit. This is
222 mainly useful if you are editing programs which need to be called with
222 mainly useful if you are editing programs which need to be called with
223 command line arguments, which you can then do using %run.
223 command line arguments, which you can then do using %run.
224
224
225
225
226 Arguments:
226 Arguments:
227
227
228 If arguments are given, the following possibilites exist:
228 If arguments are given, the following possibilites exist:
229
229
230 - The arguments are numbers or pairs of colon-separated numbers (like
230 - The arguments are numbers or pairs of colon-separated numbers (like
231 1 4:8 9). These are interpreted as lines of previous input to be
231 1 4:8 9). These are interpreted as lines of previous input to be
232 loaded into the editor. The syntax is the same of the %macro command.
232 loaded into the editor. The syntax is the same of the %macro command.
233
233
234 - If the argument doesn't start with a number, it is evaluated as a
234 - If the argument doesn't start with a number, it is evaluated as a
235 variable and its contents loaded into the editor. You can thus edit
235 variable and its contents loaded into the editor. You can thus edit
236 any string which contains python code (including the result of
236 any string which contains python code (including the result of
237 previous edits).
237 previous edits).
238
238
239 - If the argument is the name of an object (other than a string),
239 - If the argument is the name of an object (other than a string),
240 IPython will try to locate the file where it was defined and open the
240 IPython will try to locate the file where it was defined and open the
241 editor at the point where it is defined. You can use `%edit function`
241 editor at the point where it is defined. You can use `%edit function`
242 to load an editor exactly at the point where 'function' is defined,
242 to load an editor exactly at the point where 'function' is defined,
243 edit it and have the file be executed automatically.
243 edit it and have the file be executed automatically.
244
244
245 If the object is a macro (see %macro for details), this opens up your
245 If the object is a macro (see %macro for details), this opens up your
246 specified editor with a temporary file containing the macro's data.
246 specified editor with a temporary file containing the macro's data.
247 Upon exit, the macro is reloaded with the contents of the file.
247 Upon exit, the macro is reloaded with the contents of the file.
248
248
249 Note: opening at an exact line is only supported under Unix, and some
249 Note: opening at an exact line is only supported under Unix, and some
250 editors (like kedit and gedit up to Gnome 2.8) do not understand the
250 editors (like kedit and gedit up to Gnome 2.8) do not understand the
251 '+NUMBER' parameter necessary for this feature. Good editors like
251 '+NUMBER' parameter necessary for this feature. Good editors like
252 (X)Emacs, vi, jed, pico and joe all do.
252 (X)Emacs, vi, jed, pico and joe all do.
253
253
254 - If the argument is not found as a variable, IPython will look for a
254 - If the argument is not found as a variable, IPython will look for a
255 file with that name (adding .py if necessary) and load it into the
255 file with that name (adding .py if necessary) and load it into the
256 editor. It will execute its contents with execfile() when you exit,
256 editor. It will execute its contents with execfile() when you exit,
257 loading any code in the file into your interactive namespace.
257 loading any code in the file into your interactive namespace.
258
258
259 After executing your code, %edit will return as output the code you
259 After executing your code, %edit will return as output the code you
260 typed in the editor (except when it was an existing file). This way
260 typed in the editor (except when it was an existing file). This way
261 you can reload the code in further invocations of %edit as a variable,
261 you can reload the code in further invocations of %edit as a variable,
262 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
262 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
263 the output.
263 the output.
264
264
265 Note that %edit is also available through the alias %ed.
265 Note that %edit is also available through the alias %ed.
266
266
267 This is an example of creating a simple function inside the editor and
267 This is an example of creating a simple function inside the editor and
268 then modifying it. First, start up the editor:
268 then modifying it. First, start up the editor:
269
269
270 In [1]: ed
270 In [1]: ed
271 Editing... done. Executing edited code...
271 Editing... done. Executing edited code...
272 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
272 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
273
273
274 We can then call the function foo():
274 We can then call the function foo():
275
275
276 In [2]: foo()
276 In [2]: foo()
277 foo() was defined in an editing session
277 foo() was defined in an editing session
278
278
279 Now we edit foo. IPython automatically loads the editor with the
279 Now we edit foo. IPython automatically loads the editor with the
280 (temporary) file where foo() was previously defined:
280 (temporary) file where foo() was previously defined:
281
281
282 In [3]: ed foo
282 In [3]: ed foo
283 Editing... done. Executing edited code...
283 Editing... done. Executing edited code...
284
284
285 And if we call foo() again we get the modified version:
285 And if we call foo() again we get the modified version:
286
286
287 In [4]: foo()
287 In [4]: foo()
288 foo() has now been changed!
288 foo() has now been changed!
289
289
290 Here is an example of how to edit a code snippet successive
290 Here is an example of how to edit a code snippet successive
291 times. First we call the editor:
291 times. First we call the editor:
292
292
293 In [5]: ed
293 In [5]: ed
294 Editing... done. Executing edited code...
294 Editing... done. Executing edited code...
295 hello
295 hello
296 Out[5]: "print 'hello'n"
296 Out[5]: "print 'hello'n"
297
297
298 Now we call it again with the previous output (stored in _):
298 Now we call it again with the previous output (stored in _):
299
299
300 In [6]: ed _
300 In [6]: ed _
301 Editing... done. Executing edited code...
301 Editing... done. Executing edited code...
302 hello world
302 hello world
303 Out[6]: "print 'hello world'n"
303 Out[6]: "print 'hello world'n"
304
304
305 Now we call it with the output #8 (stored in _8, also as Out[8]):
305 Now we call it with the output #8 (stored in _8, also as Out[8]):
306
306
307 In [7]: ed _8
307 In [7]: ed _8
308 Editing... done. Executing edited code...
308 Editing... done. Executing edited code...
309 hello again
309 hello again
310 Out[7]: "print 'hello again'n"
310 Out[7]: "print 'hello again'n"
311 """
311 """
312
312
313 opts,args = self.parse_options(parameter_s,'prn:')
313 opts,args = self.parse_options(parameter_s,'prn:')
314
314
315 try:
315 try:
316 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
316 filename, lineno, _ = CodeMagics._find_edit_target(self.shell, args, opts, last_call)
317 except MacroToEdit as e:
317 except MacroToEdit as e:
318 # TODO: Implement macro editing over 2 processes.
318 # TODO: Implement macro editing over 2 processes.
319 print("Macro editing not yet implemented in 2-process model.")
319 print("Macro editing not yet implemented in 2-process model.")
320 return
320 return
321
321
322 # Make sure we send to the client an absolute path, in case the working
322 # Make sure we send to the client an absolute path, in case the working
323 # directory of client and kernel don't match
323 # directory of client and kernel don't match
324 filename = os.path.abspath(filename)
324 filename = os.path.abspath(filename)
325
325
326 payload = {
326 payload = {
327 'source' : 'IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
327 'source' : 'IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
328 'filename' : filename,
328 'filename' : filename,
329 'line_number' : lineno
329 'line_number' : lineno
330 }
330 }
331 self.shell.payload_manager.write_payload(payload)
331 self.shell.payload_manager.write_payload(payload)
332
332
333 # A few magics that are adapted to the specifics of using pexpect and a
333 # A few magics that are adapted to the specifics of using pexpect and a
334 # remote terminal
334 # remote terminal
335
335
336 @line_magic
336 @line_magic
337 def clear(self, arg_s):
337 def clear(self, arg_s):
338 """Clear the terminal."""
338 """Clear the terminal."""
339 if os.name == 'posix':
339 if os.name == 'posix':
340 self.shell.system("clear")
340 self.shell.system("clear")
341 else:
341 else:
342 self.shell.system("cls")
342 self.shell.system("cls")
343
343
344 if os.name == 'nt':
344 if os.name == 'nt':
345 # This is the usual name in windows
345 # This is the usual name in windows
346 cls = line_magic('cls')(clear)
346 cls = line_magic('cls')(clear)
347
347
348 # Terminal pagers won't work over pexpect, but we do have our own pager
348 # Terminal pagers won't work over pexpect, but we do have our own pager
349
349
350 @line_magic
350 @line_magic
351 def less(self, arg_s):
351 def less(self, arg_s):
352 """Show a file through the pager.
352 """Show a file through the pager.
353
353
354 Files ending in .py are syntax-highlighted."""
354 Files ending in .py are syntax-highlighted."""
355 if not arg_s:
355 if not arg_s:
356 raise UsageError('Missing filename.')
356 raise UsageError('Missing filename.')
357
357
358 cont = open(arg_s).read()
358 cont = open(arg_s).read()
359 if arg_s.endswith('.py'):
359 if arg_s.endswith('.py'):
360 cont = self.shell.pycolorize(openpy.read_py_file(arg_s, skip_encoding_cookie=False))
360 cont = self.shell.pycolorize(openpy.read_py_file(arg_s, skip_encoding_cookie=False))
361 else:
361 else:
362 cont = open(arg_s).read()
362 cont = open(arg_s).read()
363 page.page(cont)
363 page.page(cont)
364
364
365 more = line_magic('more')(less)
365 more = line_magic('more')(less)
366
366
367 # Man calls a pager, so we also need to redefine it
367 # Man calls a pager, so we also need to redefine it
368 if os.name == 'posix':
368 if os.name == 'posix':
369 @line_magic
369 @line_magic
370 def man(self, arg_s):
370 def man(self, arg_s):
371 """Find the man page for the given command and display in pager."""
371 """Find the man page for the given command and display in pager."""
372 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
372 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
373 split=False))
373 split=False))
374
374
375 @line_magic
375 @line_magic
376 def connect_info(self, arg_s):
376 def connect_info(self, arg_s):
377 """Print information for connecting other clients to this kernel
377 """Print information for connecting other clients to this kernel
378
378
379 It will print the contents of this session's connection file, as well as
379 It will print the contents of this session's connection file, as well as
380 shortcuts for local clients.
380 shortcuts for local clients.
381
381
382 In the simplest case, when called from the most recently launched kernel,
382 In the simplest case, when called from the most recently launched kernel,
383 secondary clients can be connected, simply with:
383 secondary clients can be connected, simply with:
384
384
385 $> ipython <app> --existing
385 $> ipython <app> --existing
386
386
387 """
387 """
388
388
389 from IPython.core.application import BaseIPythonApplication as BaseIPApp
389 from IPython.core.application import BaseIPythonApplication as BaseIPApp
390
390
391 if BaseIPApp.initialized():
391 if BaseIPApp.initialized():
392 app = BaseIPApp.instance()
392 app = BaseIPApp.instance()
393 security_dir = app.profile_dir.security_dir
393 security_dir = app.profile_dir.security_dir
394 profile = app.profile
394 profile = app.profile
395 else:
395 else:
396 profile = 'default'
396 profile = 'default'
397 security_dir = ''
397 security_dir = ''
398
398
399 try:
399 try:
400 connection_file = get_connection_file()
400 connection_file = get_connection_file()
401 info = get_connection_info(unpack=False)
401 info = get_connection_info(unpack=False)
402 except Exception as e:
402 except Exception as e:
403 error("Could not get connection info: %r" % e)
403 error("Could not get connection info: %r" % e)
404 return
404 return
405
405
406 # add profile flag for non-default profile
406 # add profile flag for non-default profile
407 profile_flag = "--profile %s" % profile if profile != 'default' else ""
407 profile_flag = "--profile %s" % profile if profile != 'default' else ""
408
408
409 # if it's in the security dir, truncate to basename
409 # if it's in the security dir, truncate to basename
410 if security_dir == os.path.dirname(connection_file):
410 if security_dir == os.path.dirname(connection_file):
411 connection_file = os.path.basename(connection_file)
411 connection_file = os.path.basename(connection_file)
412
412
413
413
414 print (info + '\n')
414 print (info + '\n')
415 print ("Paste the above JSON into a file, and connect with:\n"
415 print ("Paste the above JSON into a file, and connect with:\n"
416 " $> ipython <app> --existing <file>\n"
416 " $> ipython <app> --existing <file>\n"
417 "or, if you are local, you can connect with just:\n"
417 "or, if you are local, you can connect with just:\n"
418 " $> ipython <app> --existing {0} {1}\n"
418 " $> ipython <app> --existing {0} {1}\n"
419 "or even just:\n"
419 "or even just:\n"
420 " $> ipython <app> --existing {1}\n"
420 " $> ipython <app> --existing {1}\n"
421 "if this is the most recent IPython session you have started.".format(
421 "if this is the most recent IPython session you have started.".format(
422 connection_file, profile_flag
422 connection_file, profile_flag
423 )
423 )
424 )
424 )
425
425
426 @line_magic
426 @line_magic
427 def qtconsole(self, arg_s):
427 def qtconsole(self, arg_s):
428 """Open a qtconsole connected to this kernel.
428 """Open a qtconsole connected to this kernel.
429
429
430 Useful for connecting a qtconsole to running notebooks, for better
430 Useful for connecting a qtconsole to running notebooks, for better
431 debugging.
431 debugging.
432 """
432 """
433
433
434 # %qtconsole should imply bind_kernel for engines:
434 # %qtconsole should imply bind_kernel for engines:
435 try:
435 try:
436 from IPython.parallel import bind_kernel
436 from IPython.parallel import bind_kernel
437 except ImportError:
437 except ImportError:
438 # technically possible, because parallel has higher pyzmq min-version
438 # technically possible, because parallel has higher pyzmq min-version
439 pass
439 pass
440 else:
440 else:
441 bind_kernel()
441 bind_kernel()
442
442
443 try:
443 try:
444 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
444 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
445 except Exception as e:
445 except Exception as e:
446 error("Could not start qtconsole: %r" % e)
446 error("Could not start qtconsole: %r" % e)
447 return
447 return
448
448
449 @line_magic
449 @line_magic
450 def autosave(self, arg_s):
450 def autosave(self, arg_s):
451 """Set the autosave interval in the notebook (in seconds).
451 """Set the autosave interval in the notebook (in seconds).
452
452
453 The default value is 120, or two minutes.
453 The default value is 120, or two minutes.
454 ``%autosave 0`` will disable autosave.
454 ``%autosave 0`` will disable autosave.
455
455
456 This magic only has an effect when called from the notebook interface.
456 This magic only has an effect when called from the notebook interface.
457 It has no effect when called in a startup file.
457 It has no effect when called in a startup file.
458 """
458 """
459
459
460 try:
460 try:
461 interval = int(arg_s)
461 interval = int(arg_s)
462 except ValueError:
462 except ValueError:
463 raise UsageError("%%autosave requires an integer, got %r" % arg_s)
463 raise UsageError("%%autosave requires an integer, got %r" % arg_s)
464
464
465 # javascript wants milliseconds
465 # javascript wants milliseconds
466 milliseconds = 1000 * interval
466 milliseconds = 1000 * interval
467 display(Javascript("IPython.notebook.set_autosave_interval(%i)" % milliseconds),
467 display(Javascript("IPython.notebook.set_autosave_interval(%i)" % milliseconds),
468 include=['application/javascript']
468 include=['application/javascript']
469 )
469 )
470 if interval:
470 if interval:
471 print("Autosaving every %i seconds" % interval)
471 print("Autosaving every %i seconds" % interval)
472 else:
472 else:
473 print("Autosave disabled")
473 print("Autosave disabled")
474
474
475 def safe_unicode(e):
476 """unicode(e) with various fallbacks. Used for exceptions, which may not be
477 safe to call unicode() on.
478 """
479 try:
480 return unicode(e)
481 except UnicodeError:
482 pass
483
484 try:
485 return py3compat.str_to_unicode(str(e))
486 except UnicodeError:
487 pass
488
489 try:
490 return py3compat.str_to_unicode(repr(e))
491 except UnicodeError:
492 pass
493
494 return u'Unrecoverably corrupt evalue'
495
496
475
497 class ZMQInteractiveShell(InteractiveShell):
476 class ZMQInteractiveShell(InteractiveShell):
498 """A subclass of InteractiveShell for ZMQ."""
477 """A subclass of InteractiveShell for ZMQ."""
499
478
500 displayhook_class = Type(ZMQShellDisplayHook)
479 displayhook_class = Type(ZMQShellDisplayHook)
501 display_pub_class = Type(ZMQDisplayPublisher)
480 display_pub_class = Type(ZMQDisplayPublisher)
502 data_pub_class = Type(ZMQDataPublisher)
481 data_pub_class = Type(ZMQDataPublisher)
503
482
504 # Override the traitlet in the parent class, because there's no point using
483 # Override the traitlet in the parent class, because there's no point using
505 # readline for the kernel. Can be removed when the readline code is moved
484 # readline for the kernel. Can be removed when the readline code is moved
506 # to the terminal frontend.
485 # to the terminal frontend.
507 colors_force = CBool(True)
486 colors_force = CBool(True)
508 readline_use = CBool(False)
487 readline_use = CBool(False)
509 # autoindent has no meaning in a zmqshell, and attempting to enable it
488 # autoindent has no meaning in a zmqshell, and attempting to enable it
510 # will print a warning in the absence of readline.
489 # will print a warning in the absence of readline.
511 autoindent = CBool(False)
490 autoindent = CBool(False)
512
491
513 exiter = Instance(ZMQExitAutocall)
492 exiter = Instance(ZMQExitAutocall)
514 def _exiter_default(self):
493 def _exiter_default(self):
515 return ZMQExitAutocall(self)
494 return ZMQExitAutocall(self)
516
495
517 def _exit_now_changed(self, name, old, new):
496 def _exit_now_changed(self, name, old, new):
518 """stop eventloop when exit_now fires"""
497 """stop eventloop when exit_now fires"""
519 if new:
498 if new:
520 loop = ioloop.IOLoop.instance()
499 loop = ioloop.IOLoop.instance()
521 loop.add_timeout(time.time()+0.1, loop.stop)
500 loop.add_timeout(time.time()+0.1, loop.stop)
522
501
523 keepkernel_on_exit = None
502 keepkernel_on_exit = None
524
503
525 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
504 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
526 # interactive input being read; we provide event loop support in ipkernel
505 # interactive input being read; we provide event loop support in ipkernel
527 from .eventloops import enable_gui
506 from .eventloops import enable_gui
528 enable_gui = staticmethod(enable_gui)
507 enable_gui = staticmethod(enable_gui)
529
508
530 def init_environment(self):
509 def init_environment(self):
531 """Configure the user's environment.
510 """Configure the user's environment.
532
511
533 """
512 """
534 env = os.environ
513 env = os.environ
535 # These two ensure 'ls' produces nice coloring on BSD-derived systems
514 # These two ensure 'ls' produces nice coloring on BSD-derived systems
536 env['TERM'] = 'xterm-color'
515 env['TERM'] = 'xterm-color'
537 env['CLICOLOR'] = '1'
516 env['CLICOLOR'] = '1'
538 # Since normal pagers don't work at all (over pexpect we don't have
517 # Since normal pagers don't work at all (over pexpect we don't have
539 # single-key control of the subprocess), try to disable paging in
518 # single-key control of the subprocess), try to disable paging in
540 # subprocesses as much as possible.
519 # subprocesses as much as possible.
541 env['PAGER'] = 'cat'
520 env['PAGER'] = 'cat'
542 env['GIT_PAGER'] = 'cat'
521 env['GIT_PAGER'] = 'cat'
543
522
544 # And install the payload version of page.
523 # And install the payload version of page.
545 install_payload_page()
524 install_payload_page()
546
525
547 def auto_rewrite_input(self, cmd):
526 def auto_rewrite_input(self, cmd):
548 """Called to show the auto-rewritten input for autocall and friends.
527 """Called to show the auto-rewritten input for autocall and friends.
549
528
550 FIXME: this payload is currently not correctly processed by the
529 FIXME: this payload is currently not correctly processed by the
551 frontend.
530 frontend.
552 """
531 """
553 new = self.prompt_manager.render('rewrite') + cmd
532 new = self.prompt_manager.render('rewrite') + cmd
554 payload = dict(
533 payload = dict(
555 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
534 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
556 transformed_input=new,
535 transformed_input=new,
557 )
536 )
558 self.payload_manager.write_payload(payload)
537 self.payload_manager.write_payload(payload)
559
538
560 def ask_exit(self):
539 def ask_exit(self):
561 """Engage the exit actions."""
540 """Engage the exit actions."""
562 self.exit_now = True
541 self.exit_now = True
563 payload = dict(
542 payload = dict(
564 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
543 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
565 exit=True,
544 exit=True,
566 keepkernel=self.keepkernel_on_exit,
545 keepkernel=self.keepkernel_on_exit,
567 )
546 )
568 self.payload_manager.write_payload(payload)
547 self.payload_manager.write_payload(payload)
569
548
570 def _showtraceback(self, etype, evalue, stb):
549 def _showtraceback(self, etype, evalue, stb):
571
550
572 exc_content = {
551 exc_content = {
573 u'traceback' : stb,
552 u'traceback' : stb,
574 u'ename' : unicode(etype.__name__),
553 u'ename' : unicode(etype.__name__),
575 u'evalue' : safe_unicode(evalue)
554 u'evalue' : py3compat.safe_unicode(evalue),
576 }
555 }
577
556
578 dh = self.displayhook
557 dh = self.displayhook
579 # Send exception info over pub socket for other clients than the caller
558 # Send exception info over pub socket for other clients than the caller
580 # to pick up
559 # to pick up
581 topic = None
560 topic = None
582 if dh.topic:
561 if dh.topic:
583 topic = dh.topic.replace(b'pyout', b'pyerr')
562 topic = dh.topic.replace(b'pyout', b'pyerr')
584
563
585 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
564 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
586
565
587 # FIXME - Hack: store exception info in shell object. Right now, the
566 # FIXME - Hack: store exception info in shell object. Right now, the
588 # caller is reading this info after the fact, we need to fix this logic
567 # caller is reading this info after the fact, we need to fix this logic
589 # to remove this hack. Even uglier, we need to store the error status
568 # to remove this hack. Even uglier, we need to store the error status
590 # here, because in the main loop, the logic that sets it is being
569 # here, because in the main loop, the logic that sets it is being
591 # skipped because runlines swallows the exceptions.
570 # skipped because runlines swallows the exceptions.
592 exc_content[u'status'] = u'error'
571 exc_content[u'status'] = u'error'
593 self._reply_content = exc_content
572 self._reply_content = exc_content
594 # /FIXME
573 # /FIXME
595
574
596 return exc_content
575 return exc_content
597
576
598 def set_next_input(self, text):
577 def set_next_input(self, text):
599 """Send the specified text to the frontend to be presented at the next
578 """Send the specified text to the frontend to be presented at the next
600 input cell."""
579 input cell."""
601 payload = dict(
580 payload = dict(
602 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
581 source='IPython.kernel.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
603 text=text
582 text=text
604 )
583 )
605 self.payload_manager.write_payload(payload)
584 self.payload_manager.write_payload(payload)
606
585
607 #-------------------------------------------------------------------------
586 #-------------------------------------------------------------------------
608 # Things related to magics
587 # Things related to magics
609 #-------------------------------------------------------------------------
588 #-------------------------------------------------------------------------
610
589
611 def init_magics(self):
590 def init_magics(self):
612 super(ZMQInteractiveShell, self).init_magics()
591 super(ZMQInteractiveShell, self).init_magics()
613 self.register_magics(KernelMagics)
592 self.register_magics(KernelMagics)
614 self.magics_manager.register_alias('ed', 'edit')
593 self.magics_manager.register_alias('ed', 'edit')
615
594
616
595
617
596
618 InteractiveShellABC.register(ZMQInteractiveShell)
597 InteractiveShellABC.register(ZMQInteractiveShell)
@@ -1,183 +1,204 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 import __builtin__
3 import __builtin__
4 import functools
4 import functools
5 import sys
5 import sys
6 import re
6 import re
7 import types
7 import types
8
8
9 from .encoding import DEFAULT_ENCODING
9 from .encoding import DEFAULT_ENCODING
10
10
11 orig_open = open
11 orig_open = open
12
12
13 def no_code(x, encoding=None):
13 def no_code(x, encoding=None):
14 return x
14 return x
15
15
16 def decode(s, encoding=None):
16 def decode(s, encoding=None):
17 encoding = encoding or DEFAULT_ENCODING
17 encoding = encoding or DEFAULT_ENCODING
18 return s.decode(encoding, "replace")
18 return s.decode(encoding, "replace")
19
19
20 def encode(u, encoding=None):
20 def encode(u, encoding=None):
21 encoding = encoding or DEFAULT_ENCODING
21 encoding = encoding or DEFAULT_ENCODING
22 return u.encode(encoding, "replace")
22 return u.encode(encoding, "replace")
23
23
24
24
25 def cast_unicode(s, encoding=None):
25 def cast_unicode(s, encoding=None):
26 if isinstance(s, bytes):
26 if isinstance(s, bytes):
27 return decode(s, encoding)
27 return decode(s, encoding)
28 return s
28 return s
29
29
30 def cast_bytes(s, encoding=None):
30 def cast_bytes(s, encoding=None):
31 if not isinstance(s, bytes):
31 if not isinstance(s, bytes):
32 return encode(s, encoding)
32 return encode(s, encoding)
33 return s
33 return s
34
34
35 def _modify_str_or_docstring(str_change_func):
35 def _modify_str_or_docstring(str_change_func):
36 @functools.wraps(str_change_func)
36 @functools.wraps(str_change_func)
37 def wrapper(func_or_str):
37 def wrapper(func_or_str):
38 if isinstance(func_or_str, basestring):
38 if isinstance(func_or_str, basestring):
39 func = None
39 func = None
40 doc = func_or_str
40 doc = func_or_str
41 else:
41 else:
42 func = func_or_str
42 func = func_or_str
43 doc = func.__doc__
43 doc = func.__doc__
44
44
45 doc = str_change_func(doc)
45 doc = str_change_func(doc)
46
46
47 if func:
47 if func:
48 func.__doc__ = doc
48 func.__doc__ = doc
49 return func
49 return func
50 return doc
50 return doc
51 return wrapper
51 return wrapper
52
52
53 def safe_unicode(e):
54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
55 safe to call unicode() on.
56 """
57 try:
58 return unicode(e)
59 except UnicodeError:
60 pass
61
62 try:
63 return py3compat.str_to_unicode(str(e))
64 except UnicodeError:
65 pass
66
67 try:
68 return py3compat.str_to_unicode(repr(e))
69 except UnicodeError:
70 pass
71
72 return u'Unrecoverably corrupt evalue'
73
53 if sys.version_info[0] >= 3:
74 if sys.version_info[0] >= 3:
54 PY3 = True
75 PY3 = True
55
76
56 input = input
77 input = input
57 builtin_mod_name = "builtins"
78 builtin_mod_name = "builtins"
58
79
59 str_to_unicode = no_code
80 str_to_unicode = no_code
60 unicode_to_str = no_code
81 unicode_to_str = no_code
61 str_to_bytes = encode
82 str_to_bytes = encode
62 bytes_to_str = decode
83 bytes_to_str = decode
63 cast_bytes_py2 = no_code
84 cast_bytes_py2 = no_code
64
85
65 string_types = (str,)
86 string_types = (str,)
66
87
67 def isidentifier(s, dotted=False):
88 def isidentifier(s, dotted=False):
68 if dotted:
89 if dotted:
69 return all(isidentifier(a) for a in s.split("."))
90 return all(isidentifier(a) for a in s.split("."))
70 return s.isidentifier()
91 return s.isidentifier()
71
92
72 open = orig_open
93 open = orig_open
73
94
74 MethodType = types.MethodType
95 MethodType = types.MethodType
75
96
76 def execfile(fname, glob, loc=None):
97 def execfile(fname, glob, loc=None):
77 loc = loc if (loc is not None) else glob
98 loc = loc if (loc is not None) else glob
78 with open(fname, 'rb') as f:
99 with open(fname, 'rb') as f:
79 exec compile(f.read(), fname, 'exec') in glob, loc
100 exec compile(f.read(), fname, 'exec') in glob, loc
80
101
81 # Refactor print statements in doctests.
102 # Refactor print statements in doctests.
82 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
103 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
83 def _print_statement_sub(match):
104 def _print_statement_sub(match):
84 expr = match.groups('expr')
105 expr = match.groups('expr')
85 return "print(%s)" % expr
106 return "print(%s)" % expr
86
107
87 @_modify_str_or_docstring
108 @_modify_str_or_docstring
88 def doctest_refactor_print(doc):
109 def doctest_refactor_print(doc):
89 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
110 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
90 unfortunately doesn't pick up on our doctests.
111 unfortunately doesn't pick up on our doctests.
91
112
92 Can accept a string or a function, so it can be used as a decorator."""
113 Can accept a string or a function, so it can be used as a decorator."""
93 return _print_statement_re.sub(_print_statement_sub, doc)
114 return _print_statement_re.sub(_print_statement_sub, doc)
94
115
95 # Abstract u'abc' syntax:
116 # Abstract u'abc' syntax:
96 @_modify_str_or_docstring
117 @_modify_str_or_docstring
97 def u_format(s):
118 def u_format(s):
98 """"{u}'abc'" --> "'abc'" (Python 3)
119 """"{u}'abc'" --> "'abc'" (Python 3)
99
120
100 Accepts a string or a function, so it can be used as a decorator."""
121 Accepts a string or a function, so it can be used as a decorator."""
101 return s.format(u='')
122 return s.format(u='')
102
123
103 else:
124 else:
104 PY3 = False
125 PY3 = False
105
126
106 input = raw_input
127 input = raw_input
107 builtin_mod_name = "__builtin__"
128 builtin_mod_name = "__builtin__"
108
129
109 str_to_unicode = decode
130 str_to_unicode = decode
110 unicode_to_str = encode
131 unicode_to_str = encode
111 str_to_bytes = no_code
132 str_to_bytes = no_code
112 bytes_to_str = no_code
133 bytes_to_str = no_code
113 cast_bytes_py2 = cast_bytes
134 cast_bytes_py2 = cast_bytes
114
135
115 string_types = (str, unicode)
136 string_types = (str, unicode)
116
137
117 import re
138 import re
118 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
139 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
119 def isidentifier(s, dotted=False):
140 def isidentifier(s, dotted=False):
120 if dotted:
141 if dotted:
121 return all(isidentifier(a) for a in s.split("."))
142 return all(isidentifier(a) for a in s.split("."))
122 return bool(_name_re.match(s))
143 return bool(_name_re.match(s))
123
144
124 class open(object):
145 class open(object):
125 """Wrapper providing key part of Python 3 open() interface."""
146 """Wrapper providing key part of Python 3 open() interface."""
126 def __init__(self, fname, mode="r", encoding="utf-8"):
147 def __init__(self, fname, mode="r", encoding="utf-8"):
127 self.f = orig_open(fname, mode)
148 self.f = orig_open(fname, mode)
128 self.enc = encoding
149 self.enc = encoding
129
150
130 def write(self, s):
151 def write(self, s):
131 return self.f.write(s.encode(self.enc))
152 return self.f.write(s.encode(self.enc))
132
153
133 def read(self, size=-1):
154 def read(self, size=-1):
134 return self.f.read(size).decode(self.enc)
155 return self.f.read(size).decode(self.enc)
135
156
136 def close(self):
157 def close(self):
137 return self.f.close()
158 return self.f.close()
138
159
139 def __enter__(self):
160 def __enter__(self):
140 return self
161 return self
141
162
142 def __exit__(self, etype, value, traceback):
163 def __exit__(self, etype, value, traceback):
143 self.f.close()
164 self.f.close()
144
165
145 def MethodType(func, instance):
166 def MethodType(func, instance):
146 return types.MethodType(func, instance, type(instance))
167 return types.MethodType(func, instance, type(instance))
147
168
148 # don't override system execfile on 2.x:
169 # don't override system execfile on 2.x:
149 execfile = execfile
170 execfile = execfile
150
171
151 def doctest_refactor_print(func_or_str):
172 def doctest_refactor_print(func_or_str):
152 return func_or_str
173 return func_or_str
153
174
154
175
155 # Abstract u'abc' syntax:
176 # Abstract u'abc' syntax:
156 @_modify_str_or_docstring
177 @_modify_str_or_docstring
157 def u_format(s):
178 def u_format(s):
158 """"{u}'abc'" --> "u'abc'" (Python 2)
179 """"{u}'abc'" --> "u'abc'" (Python 2)
159
180
160 Accepts a string or a function, so it can be used as a decorator."""
181 Accepts a string or a function, so it can be used as a decorator."""
161 return s.format(u='u')
182 return s.format(u='u')
162
183
163 if sys.platform == 'win32':
184 if sys.platform == 'win32':
164 def execfile(fname, glob=None, loc=None):
185 def execfile(fname, glob=None, loc=None):
165 loc = loc if (loc is not None) else glob
186 loc = loc if (loc is not None) else glob
166 # The rstrip() is necessary b/c trailing whitespace in files will
187 # The rstrip() is necessary b/c trailing whitespace in files will
167 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
188 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
168 # but we still support 2.6). See issue 1027.
189 # but we still support 2.6). See issue 1027.
169 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
190 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
170 # compile converts unicode filename to str assuming
191 # compile converts unicode filename to str assuming
171 # ascii. Let's do the conversion before calling compile
192 # ascii. Let's do the conversion before calling compile
172 if isinstance(fname, unicode):
193 if isinstance(fname, unicode):
173 filename = unicode_to_str(fname)
194 filename = unicode_to_str(fname)
174 else:
195 else:
175 filename = fname
196 filename = fname
176 exec compile(scripttext, filename, 'exec') in glob, loc
197 exec compile(scripttext, filename, 'exec') in glob, loc
177 else:
198 else:
178 def execfile(fname, *where):
199 def execfile(fname, *where):
179 if isinstance(fname, unicode):
200 if isinstance(fname, unicode):
180 filename = fname.encode(sys.getfilesystemencoding())
201 filename = fname.encode(sys.getfilesystemencoding())
181 else:
202 else:
182 filename = fname
203 filename = fname
183 __builtin__.execfile(filename, *where)
204 __builtin__.execfile(filename, *where)
General Comments 0
You need to be logged in to leave comments. Login now