##// END OF EJS Templates
bug fixed in prompt count after traceback
Omar Andres Zapata Mesa -
Show More
@@ -1,282 +1,283 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Frontend of ipython working with python-zmq
3 3
4 4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
5 5
6 6 For more details, see the ipython-zmq design
7 7 """
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2010 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 import __builtin__
20 20 from contextlib import nested
21 21 import time
22 22 import sys
23 23 import os
24 24 import signal
25 25 import uuid
26 26 import cPickle as pickle
27 27 import code
28 28 import zmq
29 29 import readline
30 30 import rlcompleter
31 31 import time
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Imports from ipython
35 35 #-----------------------------------------------------------------------------
36 36 from IPython.external.argparse import ArgumentParser
37 37 from IPython.utils.traitlets import (
38 38 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
39 39 )
40 40 from IPython.core.interactiveshell import get_default_colors
41 41 from IPython.core.excolors import exception_colors
42 42 from IPython.utils import PyColorize
43 43 from IPython.core.inputsplitter import InputSplitter
44 44 from IPython.frontend.terminal.kernelmanager import KernelManager2p as KernelManager
45 45 from IPython.zmq.session import Session
46 46 from IPython.frontend.terminal.completer import ClientCompleter2p
47 47
48 48 #-----------------------------------------------------------------------------
49 49 # Network Constants
50 50 #-----------------------------------------------------------------------------
51 51
52 52 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
53 53 class Frontend(object):
54 54 """ this class is a simple frontend to ipython-zmq
55 55
56 56 NOTE: this class use kernelmanager to manipulate sockets
57 57
58 58 Parameters:
59 59 -----------
60 60 kernelmanager : object
61 61 instantiated object from class KernelManager in module kernelmanager
62 62
63 63 """
64 64
65 65 def __init__(self,kernelmanager):
66 66 self.km = kernelmanager
67 67 self.session = kernelmanager.session
68 68 self.request_socket = self.km.xreq_channel.socket
69 69 self.sub_socket = self.km.sub_channel.socket
70 70 self.reply_socket = self.km.rep_channel.socket
71 71 self.msg_header = self.km.session.msg_header()
72 72 self.completer = ClientCompleter2p(self,self.km)
73 73 readline.parse_and_bind("tab: complete")
74 74 readline.parse_and_bind('set show-all-if-ambiguous on')
75 75 readline.set_completer(self.completer.complete)
76 76
77 77 history_path = os.path.expanduser('~/.ipython/history')
78 78 if os.path.isfile(history_path):
79 79 rlcompleter.readline.read_history_file(history_path)
80 80 else:
81 81 print("history file can not be readed.")
82 82
83 83 self.messages = {}
84 84
85 85 self._splitter = InputSplitter()
86 86 self.code = ""
87 87
88 88 self.prompt_count = 0
89 89 self._get_initail_promt()
90 90
91 91 def _get_initail_promt(self):
92 92 self._execute('', hidden=True)
93 93
94 94 def interact(self):
95 95 """ let you get input from console using inputsplitter, then
96 96 while you enter code it can indent and set index id to any input
97 97
98 98 """
99 99
100 100 try:
101 101 self._splitter.push(raw_input('In[%i]:'%self.prompt_count+self.code))
102 102 while self._splitter.push_accepts_more():
103 103 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
104 104 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
105 105 self._execute(self._splitter.source,False)
106 106 self._splitter.reset()
107 107 except KeyboardInterrupt:
108 108 print('\nKeyboardInterrupt\n')
109 109 pass
110 110
111 111
112 112 def start(self):
113 113 """ init a bucle that call interact method to get code.
114 114
115 115 """
116 116 while True:
117 117 try:
118 118 self.interact()
119 119 except KeyboardInterrupt:
120 120 print('\nKeyboardInterrupt\n')
121 121 pass
122 122 except EOFError:
123 123 answer = ''
124 124 while True:
125 125 answer = raw_input('\nDo you really want to exit ([y]/n)?')
126 126 if answer == 'y' or answer == '' :
127 127 self.km.shutdown_kernel()
128 128 sys.exit()
129 129 elif answer == 'n':
130 130 break
131 131
132 132 def _execute(self, source, hidden = True):
133 133 """ Execute 'source'. If 'hidden', do not show any output.
134 134
135 135 See parent class :meth:`execute` docstring for full details.
136 136 """
137 137 self.km.xreq_channel.execute(source, hidden)
138 138 self.handle_xreq_channel()
139 139 self.handle_rep_channel()
140 140
141 141 def handle_xreq_channel(self):
142 142 # Give the kernel up to 0.5s to respond
143 143 for i in range(5):
144 144 if self.km.xreq_channel.was_called():
145 145 self.msg_xreq = self.km.xreq_channel.get_msg()
146 146 if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"] :
147 147 if self.msg_xreq["content"]["status"] == 'ok' :
148 148 if self.msg_xreq["msg_type"] == "execute_reply" :
149 149 self.handle_sub_channel()
150 150 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
151 151
152 152 else:
153 153 etb = self.msg_xreq["content"]["traceback"]
154 154 print >> sys.stderr, etb[0]
155 155 print >> sys.stderr, etb[1]
156 156 print >> sys.stderr, etb[2]
157 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
157 158 break
158 159 time.sleep(0.1)
159 160
160 161
161 162
162 163 def handle_sub_channel(self):
163 164 """ Method to procces subscribe channel's messages
164 165
165 166 this method read a message and procces the content
166 167 in differents outputs like stdout, stderr, pyout
167 168 and status
168 169
169 170 Arguments:
170 171 sub_msg: message receive from kernel in the sub socket channel
171 172 capture by kernel manager.
172 173
173 174 """
174 175 while self.km.sub_channel.was_called():
175 176 sub_msg = self.km.sub_channel.get_msg()
176 177 if self.msg_header["username"] == sub_msg['parent_header']['username'] and self.km.session.session == sub_msg['parent_header']['session']:
177 178 if sub_msg['msg_type'] == 'status' :
178 179 if sub_msg["content"]["execution_state"] == "busy" :
179 180 pass
180 181
181 182 if sub_msg['msg_type'] == 'stream' :
182 183 if sub_msg["content"]["name"] == "stdout":
183 184 print >> sys.stdout,sub_msg["content"]["data"]
184 185 sys.stdout.flush()
185 186 if sub_msg["content"]["name"] == "stderr" :
186 187 print >> sys.stderr,sub_msg["content"]["data"]
187 188 sys.stderr.flush()
188 189
189 190 if sub_msg['msg_type'] == 'pyout' :
190 191 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
191 192 sys.stdout.flush()
192 193
193 194 def handle_rep_channel(self):
194 195 """ Method to capture raw_input
195 196 """
196 197 if self.km.rep_channel.was_called() :
197 198 self.msg_rep = self.km.rep_channel.get_msg()
198 199 if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
199 200 raw_data = raw_input(self.msg_rep["content"]["prompt"])
200 201 self.km.rep_channel.input(raw_data)
201 202
202 203
203 204
204 205
205 206 def start_frontend():
206 207 """ Entry point for application.
207 208
208 209 """
209 210 # Parse command line arguments.
210 211 parser = ArgumentParser()
211 212 kgroup = parser.add_argument_group('kernel options')
212 213 kgroup.add_argument('-e', '--existing', action='store_true',
213 214 help='connect to an existing kernel')
214 215 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
215 216 help=\
216 217 "set the kernel\'s IP address [default localhost].\
217 218 If the IP address is something other than localhost, then \
218 219 Consoles on other machines will be able to connect\
219 220 to the Kernel, so be careful!")
220 221 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
221 222 help='set the XREQ channel port [default random]')
222 223 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
223 224 help='set the SUB channel port [default random]')
224 225 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
225 226 help='set the REP channel port [default random]')
226 227 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
227 228 help='set the heartbeat port [default random]')
228 229
229 230 egroup = kgroup.add_mutually_exclusive_group()
230 231 egroup.add_argument('--pure', action='store_true', help = \
231 232 'use a pure Python kernel instead of an IPython kernel')
232 233 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
233 234 const='auto', help = \
234 235 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
235 236 given, the GUI backend is matplotlib's, otherwise use one of: \
236 237 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
237 238 egroup.add_argument('--colors', type=str,
238 239 help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
239 240 based on the pygments style if not set.")
240 241
241 242 args = parser.parse_args()
242 243
243 244 # parse the colors arg down to current known labels
244 245 if args.colors:
245 246 colors=args.colors.lower()
246 247 if colors in ('lightbg', 'light'):
247 248 colors='lightbg'
248 249 elif colors in ('dark', 'linux'):
249 250 colors='linux'
250 251 else:
251 252 colors='nocolor'
252 253 else:
253 254 colors=None
254 255
255 256 # Create a KernelManager and start a kernel.
256 257 kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
257 258 sub_address=(args.ip, args.sub),
258 259 rep_address=(args.ip, args.rep),
259 260 hb_address=(args.ip, args.hb))
260 261 if not args.existing:
261 262 # if not args.ip in LOCAL_IPS+ALL_ALIAS:
262 263 # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
263 264
264 265 kwargs = dict(ip=args.ip)
265 266 if args.pure:
266 267 kwargs['ipython']=False
267 268 else:
268 269 kwargs['colors']=colors
269 270 if args.pylab:
270 271 kwargs['pylab']=args.pylab
271 272 kernel_manager.start_kernel(**kwargs)
272 273
273 274
274 275 kernel_manager.start_channels()
275 276 time.sleep(4)
276 277
277 278 frontend=Frontend(kernel_manager)
278 279 return frontend
279 280
280 281 if __name__ == "__main__" :
281 282 frontend=start_frontend()
282 283 frontend.start() No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now