blob: 2f07a826aa7db5d37f81bca01703e7f245d0d607 [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001try:
2 from code import InteractiveConsole
3except ImportError:
4 from pydevconsole_code_for_ironpython import InteractiveConsole
5
6from code import compile_command
7from code import InteractiveInterpreter
8
9import os
10import sys
11
12from pydevd_constants import USE_LIB_COPY
Tor Norbye3a2425a2013-11-04 10:16:08 -080013
14if USE_LIB_COPY:
15 import _pydev_threading as threading
16else:
17 import threading
18
19import traceback
20import fix_getpass
21fix_getpass.fixGetpass()
22
23import pydevd_vars
24
Tor Norbye1aa2e092014-08-20 17:01:23 -070025from pydev_imports import Exec, _queue
Tor Norbye3a2425a2013-11-04 10:16:08 -080026
27try:
28 import __builtin__
29except:
30 import builtins as __builtin__
31
32try:
33 False
34 True
35except NameError: # version < 2.3 -- didn't have the True/False builtins
36 import __builtin__
37
38 setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax
39 setattr(__builtin__, 'False', 0)
40
Tor Norbye1aa2e092014-08-20 17:01:23 -070041from pydev_console_utils import BaseInterpreterInterface, BaseStdIn
Tor Norbye8668e1b2013-12-20 09:14:04 -080042from pydev_console_utils import CodeFragment
Tor Norbye3a2425a2013-11-04 10:16:08 -080043
44IS_PYTHON_3K = False
45
46try:
47 if sys.version_info[0] == 3:
48 IS_PYTHON_3K = True
49except:
50 #That's OK, not all versions of python have sys.version_info
51 pass
52
Tor Norbye3a2425a2013-11-04 10:16:08 -080053
Tor Norbye8668e1b2013-12-20 09:14:04 -080054class Command:
55 def __init__(self, interpreter, code_fragment):
56 """
57 :type code_fragment: CodeFragment
58 :type interpreter: InteractiveConsole
59 """
60 self.interpreter = interpreter
61 self.code_fragment = code_fragment
62 self.more = None
Tor Norbye3a2425a2013-11-04 10:16:08 -080063
Tor Norbye8668e1b2013-12-20 09:14:04 -080064 @staticmethod
65 def symbol_for_fragment(code_fragment):
66 if code_fragment.is_single_line:
67 symbol = 'single'
Tor Norbye3a2425a2013-11-04 10:16:08 -080068 else:
Tor Norbye8668e1b2013-12-20 09:14:04 -080069 symbol = 'exec' # Jython doesn't support this
70 return symbol
Tor Norbye3a2425a2013-11-04 10:16:08 -080071
Tor Norbye8668e1b2013-12-20 09:14:04 -080072 def run(self):
73 text = self.code_fragment.text
74 symbol = self.symbol_for_fragment(self.code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -080075
Tor Norbye8668e1b2013-12-20 09:14:04 -080076 self.more = self.interpreter.runsource(text, '<input>', symbol)
Tor Norbye3a2425a2013-11-04 10:16:08 -080077
78try:
79 try:
80 execfile #Not in Py3k
81 except NameError:
82 from pydev_imports import execfile
83
84 __builtin__.execfile = execfile
85
86except:
87 pass
88
89
90#=======================================================================================================================
91# InterpreterInterface
92#=======================================================================================================================
93class InterpreterInterface(BaseInterpreterInterface):
94 '''
95 The methods in this class should be registered in the xml-rpc server.
96 '''
97
98 def __init__(self, host, client_port, mainThread):
99 BaseInterpreterInterface.__init__(self, mainThread)
100 self.client_port = client_port
101 self.host = host
102 self.namespace = {}
103 self.interpreter = InteractiveConsole(self.namespace)
104 self._input_error_printed = False
105
106
Tor Norbye8668e1b2013-12-20 09:14:04 -0800107 def doAddExec(self, codeFragment):
108 command = Command(self.interpreter, codeFragment)
109 command.run()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800110 return command.more
111
112
113 def getNamespace(self):
114 return self.namespace
115
116
117 def getCompletions(self, text, act_tok):
118 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700119 from _pydev_completer import Completer
Tor Norbye3a2425a2013-11-04 10:16:08 -0800120
121 completer = Completer(self.namespace, None)
122 return completer.complete(act_tok)
123 except:
124 import traceback
125
126 traceback.print_exc()
127 return []
Tor Norbye1aa2e092014-08-20 17:01:23 -0700128
Tor Norbye3a2425a2013-11-04 10:16:08 -0800129 def close(self):
130 sys.exit(0)
131
132 def get_greeting_msg(self):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700133 return 'PyDev console: starting.\n'
134
135
136class _ProcessExecQueueHelper:
137 _debug_hook = None
138 _return_control_osc = False
139
140def set_debug_hook(debug_hook):
141 _ProcessExecQueueHelper._debug_hook = debug_hook
Tor Norbye3a2425a2013-11-04 10:16:08 -0800142
143
144def process_exec_queue(interpreter):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700145
146 from pydev_ipython.inputhook import get_inputhook, set_return_control_callback
147
148 def return_control():
149 ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find
150 out if they should cede control and return '''
151 if _ProcessExecQueueHelper._debug_hook:
152 # Some of the input hooks check return control without doing
153 # a single operation, so we don't return True on every
154 # call when the debug hook is in place to allow the GUI to run
155 # XXX: Eventually the inputhook code will have diverged enough
156 # from the IPython source that it will be worthwhile rewriting
157 # it rather than pretending to maintain the old API
158 _ProcessExecQueueHelper._return_control_osc = not _ProcessExecQueueHelper._return_control_osc
159 if _ProcessExecQueueHelper._return_control_osc:
160 return True
161
162 if not interpreter.exec_queue.empty():
163 return True
164 return False
165
166 set_return_control_callback(return_control)
167
Tor Norbye3a2425a2013-11-04 10:16:08 -0800168 while 1:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700169 # Running the request may have changed the inputhook in use
170 inputhook = get_inputhook()
171
172 if _ProcessExecQueueHelper._debug_hook:
173 _ProcessExecQueueHelper._debug_hook()
174
175 if inputhook:
176 try:
177 # Note: it'll block here until return_control returns True.
178 inputhook()
179 except:
180 import traceback;traceback.print_exc()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800181 try:
182 try:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700183 code_fragment = interpreter.exec_queue.get(block=True, timeout=1/20.) # 20 calls/second
Tor Norbye3a2425a2013-11-04 10:16:08 -0800184 except _queue.Empty:
185 continue
186
Tor Norbye1aa2e092014-08-20 17:01:23 -0700187 if callable(code_fragment):
188 # It can be a callable (i.e.: something that must run in the main
189 # thread can be put in the queue for later execution).
190 code_fragment()
191 else:
192 more = interpreter.addExec(code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800193 except KeyboardInterrupt:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800194 interpreter.buffer = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800195 continue
196 except SystemExit:
197 raise
198 except:
199 type, value, tb = sys.exc_info()
200 traceback.print_exception(type, value, tb, file=sys.__stderr__)
201 exit()
202
203
Tor Norbyec667c1f2014-05-28 17:06:51 -0700204if 'IPYTHONENABLE' in os.environ:
205 IPYTHON = os.environ['IPYTHONENABLE'] == 'True'
206else:
207 IPYTHON = True
208
Tor Norbye3a2425a2013-11-04 10:16:08 -0800209try:
210 try:
211 exitfunc = sys.exitfunc
212 except AttributeError:
213 exitfunc = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800214
Tor Norbyec667c1f2014-05-28 17:06:51 -0700215 if IPYTHON:
216 from pydev_ipython_console import InterpreterInterface
217 if exitfunc is not None:
218 sys.exitfunc = exitfunc
219 else:
220 try:
221 delattr(sys, 'exitfunc')
222 except:
223 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800224except:
225 IPYTHON = False
Tor Norbyec667c1f2014-05-28 17:06:51 -0700226 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800227
228#=======================================================================================================================
229# _DoExit
230#=======================================================================================================================
231def _DoExit(*args):
232 '''
233 We have to override the exit because calling sys.exit will only actually exit the main thread,
234 and as we're in a Xml-rpc server, that won't work.
235 '''
236
237 try:
238 import java.lang.System
239
240 java.lang.System.exit(1)
241 except ImportError:
242 if len(args) == 1:
243 os._exit(args[0])
244 else:
245 os._exit(0)
246
247
248def handshake():
249 return "PyCharm"
250
251
Tor Norbye3a2425a2013-11-04 10:16:08 -0800252#=======================================================================================================================
253# StartServer
254#=======================================================================================================================
255def start_server(host, port, interpreter):
256 if port == 0:
257 host = ''
258
Tor Norbye1aa2e092014-08-20 17:01:23 -0700259 #I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse.
260 from pydev_imports import SimpleXMLRPCServer as XMLRPCServer #@Reimport
Tor Norbye3a2425a2013-11-04 10:16:08 -0800261
262 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700263 server = XMLRPCServer((host, port), logRequests=False, allow_none=True)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800264
265 except:
266 sys.stderr.write('Error starting server with host: %s, port: %s, client_port: %s\n' % (host, port, client_port))
267 raise
268
269 server.register_function(interpreter.execLine)
Tor Norbye8668e1b2013-12-20 09:14:04 -0800270 server.register_function(interpreter.execMultipleLines)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800271 server.register_function(interpreter.getCompletions)
272 server.register_function(interpreter.getFrame)
273 server.register_function(interpreter.getVariable)
274 server.register_function(interpreter.changeVariable)
275 server.register_function(interpreter.getDescription)
276 server.register_function(interpreter.close)
277 server.register_function(interpreter.interrupt)
278 server.register_function(handshake)
Tor Norbyec667c1f2014-05-28 17:06:51 -0700279 server.register_function(interpreter.connectToDebugger)
Tor Norbye1aa2e092014-08-20 17:01:23 -0700280 server.register_function(interpreter.hello)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800281
Tor Norbye1aa2e092014-08-20 17:01:23 -0700282 # Functions for GUI main loop integration
283 server.register_function(interpreter.enableGui)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800284
285 if port == 0:
286 (h, port) = server.socket.getsockname()
287
288 print(port)
289 print(client_port)
290
291
292 sys.stderr.write(interpreter.get_greeting_msg())
Tor Norbyec667c1f2014-05-28 17:06:51 -0700293 sys.stderr.flush()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800294
295 server.serve_forever()
296
297 return server
298
299
300def StartServer(host, port, client_port):
301 #replace exit (see comments on method)
302 #note that this does not work in jython!!! (sys method can't be replaced).
303 sys.exit = _DoExit
304
305 interpreter = InterpreterInterface(host, client_port, threading.currentThread())
306
307 server_thread = threading.Thread(target=start_server,
308 name='ServerThread',
309 args=(host, port, interpreter))
310 server_thread.setDaemon(True)
311 server_thread.start()
312
313 process_exec_queue(interpreter)
314
315
316def get_interpreter():
317 try:
318 interpreterInterface = getattr(__builtin__, 'interpreter')
319 except AttributeError:
320 interpreterInterface = InterpreterInterface(None, None, threading.currentThread())
321 setattr(__builtin__, 'interpreter', interpreterInterface)
322
323 return interpreterInterface
324
325
326def get_completions(text, token, globals, locals):
327 interpreterInterface = get_interpreter()
328
329 interpreterInterface.interpreter.update(globals, locals)
330
331 return interpreterInterface.getCompletions(text, token)
332
Tor Norbye1aa2e092014-08-20 17:01:23 -0700333#===============================================================================
334# Debugger integration
335#===============================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800336
Tor Norbye8668e1b2013-12-20 09:14:04 -0800337def exec_code(code, globals, locals):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800338 interpreterInterface = get_interpreter()
339
340 interpreterInterface.interpreter.update(globals, locals)
341
Tor Norbye8668e1b2013-12-20 09:14:04 -0800342 res = interpreterInterface.needMore(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800343
344 if res:
345 return True
346
Tor Norbye8668e1b2013-12-20 09:14:04 -0800347 interpreterInterface.addExec(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800348
349 return False
350
351
Tor Norbye3a2425a2013-11-04 10:16:08 -0800352
353class ConsoleWriter(InteractiveInterpreter):
354 skip = 0
355
356 def __init__(self, locals=None):
357 InteractiveInterpreter.__init__(self, locals)
358
359 def write(self, data):
360 #if (data.find("global_vars") == -1 and data.find("pydevd") == -1):
361 if self.skip > 0:
362 self.skip -= 1
363 else:
364 if data == "Traceback (most recent call last):\n":
365 self.skip = 1
366 sys.stderr.write(data)
367
Tor Norbye9ea67222014-06-10 18:12:50 -0700368 def showsyntaxerror(self, filename=None):
369 """Display the syntax error that just occurred."""
370 #Override for avoid using sys.excepthook PY-12600
371 type, value, tb = sys.exc_info()
372 sys.last_type = type
373 sys.last_value = value
374 sys.last_traceback = tb
375 if filename and type is SyntaxError:
376 # Work hard to stuff the correct filename in the exception
377 try:
378 msg, (dummy_filename, lineno, offset, line) = value.args
379 except ValueError:
380 # Not the format we expect; leave it alone
381 pass
382 else:
383 # Stuff in the right filename
384 value = SyntaxError(msg, (filename, lineno, offset, line))
385 sys.last_value = value
386 list = traceback.format_exception_only(type, value)
387 sys.stderr.write(''.join(list))
388
389 def showtraceback(self):
390 """Display the exception that just occurred."""
391 #Override for avoid using sys.excepthook PY-12600
392 try:
393 type, value, tb = sys.exc_info()
394 sys.last_type = type
395 sys.last_value = value
396 sys.last_traceback = tb
397 tblist = traceback.extract_tb(tb)
398 del tblist[:1]
399 lines = traceback.format_list(tblist)
400 if lines:
401 lines.insert(0, "Traceback (most recent call last):\n")
402 lines.extend(traceback.format_exception_only(type, value))
403 finally:
404 tblist = tb = None
405 sys.stderr.write(''.join(lines))
406
Tor Norbye3a2425a2013-11-04 10:16:08 -0800407def consoleExec(thread_id, frame_id, expression):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700408 """returns 'False' in case expression is partially correct
Tor Norbye3a2425a2013-11-04 10:16:08 -0800409 """
410 frame = pydevd_vars.findFrame(thread_id, frame_id)
411
412 expression = str(expression.replace('@LINE@', '\n'))
413
414 #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329
415 #(Names not resolved in generator expression in method)
416 #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html
417 updated_globals = {}
418 updated_globals.update(frame.f_globals)
419 updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
420
421 if IPYTHON:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800422 return exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800423
424 interpreter = ConsoleWriter()
425
426 try:
427 code = compile_command(expression)
428 except (OverflowError, SyntaxError, ValueError):
429 # Case 1
430 interpreter.showsyntaxerror()
431 return False
432
433 if code is None:
434 # Case 2
435 return True
436
437 #Case 3
438
439 try:
440 Exec(code, updated_globals, frame.f_locals)
441
442 except SystemExit:
443 raise
444 except:
445 interpreter.showtraceback()
446
447 return False
448
449#=======================================================================================================================
450# main
451#=======================================================================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800452if __name__ == '__main__':
Tor Norbye1aa2e092014-08-20 17:01:23 -0700453 sys.stdin = BaseStdIn()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800454 port, client_port = sys.argv[1:3]
455 import pydev_localhost
456
457 if int(port) == 0 and int(client_port) == 0:
458 (h, p) = pydev_localhost.get_socket_name()
459
460 client_port = p
461
462 StartServer(pydev_localhost.get_localhost(), int(port), int(client_port))