blob: 8d4375f5a5aa8877628f21f89ab2f65d7104dffe [file] [log] [blame]
Tor Norbyec3d3a902014-09-04 13:24:04 -07001from _pydev_imps._pydev_thread import start_new_thread
2
Tor Norbye3a2425a2013-11-04 10:16:08 -08003try:
4 from code import InteractiveConsole
5except ImportError:
6 from pydevconsole_code_for_ironpython import InteractiveConsole
7
8from code import compile_command
9from code import InteractiveInterpreter
10
11import os
12import sys
13
Tor Norbyec3d3a902014-09-04 13:24:04 -070014import _pydev_threading as threading
Tor Norbye3a2425a2013-11-04 10:16:08 -080015
16import traceback
17import fix_getpass
18fix_getpass.fixGetpass()
19
20import pydevd_vars
21
Tor Norbye1aa2e092014-08-20 17:01:23 -070022from pydev_imports import Exec, _queue
Tor Norbye3a2425a2013-11-04 10:16:08 -080023
24try:
25 import __builtin__
26except:
27 import builtins as __builtin__
28
29try:
30 False
31 True
32except NameError: # version < 2.3 -- didn't have the True/False builtins
33 import __builtin__
34
35 setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax
36 setattr(__builtin__, 'False', 0)
37
Tor Norbye1aa2e092014-08-20 17:01:23 -070038from pydev_console_utils import BaseInterpreterInterface, BaseStdIn
Tor Norbye8668e1b2013-12-20 09:14:04 -080039from pydev_console_utils import CodeFragment
Tor Norbye3a2425a2013-11-04 10:16:08 -080040
41IS_PYTHON_3K = False
42
43try:
44 if sys.version_info[0] == 3:
45 IS_PYTHON_3K = True
46except:
47 #That's OK, not all versions of python have sys.version_info
48 pass
49
Tor Norbye3a2425a2013-11-04 10:16:08 -080050
Tor Norbye8668e1b2013-12-20 09:14:04 -080051class Command:
52 def __init__(self, interpreter, code_fragment):
53 """
54 :type code_fragment: CodeFragment
55 :type interpreter: InteractiveConsole
56 """
57 self.interpreter = interpreter
58 self.code_fragment = code_fragment
59 self.more = None
Tor Norbye3a2425a2013-11-04 10:16:08 -080060
Tor Norbyec3d3a902014-09-04 13:24:04 -070061
Tor Norbye8668e1b2013-12-20 09:14:04 -080062 def symbol_for_fragment(code_fragment):
63 if code_fragment.is_single_line:
64 symbol = 'single'
Tor Norbye3a2425a2013-11-04 10:16:08 -080065 else:
Tor Norbye8668e1b2013-12-20 09:14:04 -080066 symbol = 'exec' # Jython doesn't support this
67 return symbol
Tor Norbyec3d3a902014-09-04 13:24:04 -070068 symbol_for_fragment = staticmethod(symbol_for_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -080069
Tor Norbye8668e1b2013-12-20 09:14:04 -080070 def run(self):
71 text = self.code_fragment.text
72 symbol = self.symbol_for_fragment(self.code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -080073
Tor Norbye8668e1b2013-12-20 09:14:04 -080074 self.more = self.interpreter.runsource(text, '<input>', symbol)
Tor Norbye3a2425a2013-11-04 10:16:08 -080075
76try:
77 try:
78 execfile #Not in Py3k
79 except NameError:
80 from pydev_imports import execfile
81
82 __builtin__.execfile = execfile
83
84except:
85 pass
86
87
88#=======================================================================================================================
89# InterpreterInterface
90#=======================================================================================================================
91class InterpreterInterface(BaseInterpreterInterface):
92 '''
93 The methods in this class should be registered in the xml-rpc server.
94 '''
95
96 def __init__(self, host, client_port, mainThread):
97 BaseInterpreterInterface.__init__(self, mainThread)
98 self.client_port = client_port
99 self.host = host
100 self.namespace = {}
101 self.interpreter = InteractiveConsole(self.namespace)
102 self._input_error_printed = False
103
104
Tor Norbye8668e1b2013-12-20 09:14:04 -0800105 def doAddExec(self, codeFragment):
106 command = Command(self.interpreter, codeFragment)
107 command.run()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800108 return command.more
109
110
111 def getNamespace(self):
112 return self.namespace
113
114
115 def getCompletions(self, text, act_tok):
116 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700117 from _pydev_completer import Completer
Tor Norbye3a2425a2013-11-04 10:16:08 -0800118
119 completer = Completer(self.namespace, None)
120 return completer.complete(act_tok)
121 except:
122 import traceback
123
124 traceback.print_exc()
125 return []
Tor Norbye1aa2e092014-08-20 17:01:23 -0700126
Tor Norbye3a2425a2013-11-04 10:16:08 -0800127 def close(self):
128 sys.exit(0)
129
130 def get_greeting_msg(self):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700131 return 'PyDev console: starting.\n'
132
133
134class _ProcessExecQueueHelper:
135 _debug_hook = None
136 _return_control_osc = False
137
138def set_debug_hook(debug_hook):
139 _ProcessExecQueueHelper._debug_hook = debug_hook
Tor Norbye3a2425a2013-11-04 10:16:08 -0800140
141
142def process_exec_queue(interpreter):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700143
144 from pydev_ipython.inputhook import get_inputhook, set_return_control_callback
145
146 def return_control():
147 ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find
148 out if they should cede control and return '''
149 if _ProcessExecQueueHelper._debug_hook:
150 # Some of the input hooks check return control without doing
151 # a single operation, so we don't return True on every
152 # call when the debug hook is in place to allow the GUI to run
153 # XXX: Eventually the inputhook code will have diverged enough
154 # from the IPython source that it will be worthwhile rewriting
155 # it rather than pretending to maintain the old API
156 _ProcessExecQueueHelper._return_control_osc = not _ProcessExecQueueHelper._return_control_osc
157 if _ProcessExecQueueHelper._return_control_osc:
158 return True
159
160 if not interpreter.exec_queue.empty():
161 return True
162 return False
163
164 set_return_control_callback(return_control)
165
Tor Norbye3a2425a2013-11-04 10:16:08 -0800166 while 1:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700167 # Running the request may have changed the inputhook in use
168 inputhook = get_inputhook()
169
170 if _ProcessExecQueueHelper._debug_hook:
171 _ProcessExecQueueHelper._debug_hook()
172
173 if inputhook:
174 try:
175 # Note: it'll block here until return_control returns True.
176 inputhook()
177 except:
178 import traceback;traceback.print_exc()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800179 try:
180 try:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700181 code_fragment = interpreter.exec_queue.get(block=True, timeout=1/20.) # 20 calls/second
Tor Norbye3a2425a2013-11-04 10:16:08 -0800182 except _queue.Empty:
183 continue
184
Tor Norbye1aa2e092014-08-20 17:01:23 -0700185 if callable(code_fragment):
186 # It can be a callable (i.e.: something that must run in the main
187 # thread can be put in the queue for later execution).
188 code_fragment()
189 else:
190 more = interpreter.addExec(code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800191 except KeyboardInterrupt:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800192 interpreter.buffer = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800193 continue
194 except SystemExit:
195 raise
196 except:
197 type, value, tb = sys.exc_info()
198 traceback.print_exception(type, value, tb, file=sys.__stderr__)
199 exit()
200
201
Tor Norbyec667c1f2014-05-28 17:06:51 -0700202if 'IPYTHONENABLE' in os.environ:
203 IPYTHON = os.environ['IPYTHONENABLE'] == 'True'
204else:
205 IPYTHON = True
206
Tor Norbye3a2425a2013-11-04 10:16:08 -0800207try:
208 try:
209 exitfunc = sys.exitfunc
210 except AttributeError:
211 exitfunc = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800212
Tor Norbyec667c1f2014-05-28 17:06:51 -0700213 if IPYTHON:
214 from pydev_ipython_console import InterpreterInterface
215 if exitfunc is not None:
216 sys.exitfunc = exitfunc
217 else:
218 try:
219 delattr(sys, 'exitfunc')
220 except:
221 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800222except:
223 IPYTHON = False
Tor Norbyec667c1f2014-05-28 17:06:51 -0700224 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800225
226#=======================================================================================================================
227# _DoExit
228#=======================================================================================================================
Tor Norbyec3d3a902014-09-04 13:24:04 -0700229def DoExit(*args):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800230 '''
231 We have to override the exit because calling sys.exit will only actually exit the main thread,
232 and as we're in a Xml-rpc server, that won't work.
233 '''
234
235 try:
236 import java.lang.System
237
238 java.lang.System.exit(1)
239 except ImportError:
240 if len(args) == 1:
241 os._exit(args[0])
242 else:
243 os._exit(0)
244
245
246def handshake():
247 return "PyCharm"
248
249
Tor Norbye3a2425a2013-11-04 10:16:08 -0800250#=======================================================================================================================
251# StartServer
252#=======================================================================================================================
253def start_server(host, port, interpreter):
254 if port == 0:
255 host = ''
256
Tor Norbye1aa2e092014-08-20 17:01:23 -0700257 #I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse.
258 from pydev_imports import SimpleXMLRPCServer as XMLRPCServer #@Reimport
Tor Norbye3a2425a2013-11-04 10:16:08 -0800259
260 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700261 server = XMLRPCServer((host, port), logRequests=False, allow_none=True)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800262
263 except:
264 sys.stderr.write('Error starting server with host: %s, port: %s, client_port: %s\n' % (host, port, client_port))
265 raise
266
267 server.register_function(interpreter.execLine)
Tor Norbye8668e1b2013-12-20 09:14:04 -0800268 server.register_function(interpreter.execMultipleLines)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800269 server.register_function(interpreter.getCompletions)
270 server.register_function(interpreter.getFrame)
271 server.register_function(interpreter.getVariable)
272 server.register_function(interpreter.changeVariable)
273 server.register_function(interpreter.getDescription)
274 server.register_function(interpreter.close)
275 server.register_function(interpreter.interrupt)
276 server.register_function(handshake)
Tor Norbyec667c1f2014-05-28 17:06:51 -0700277 server.register_function(interpreter.connectToDebugger)
Tor Norbye1aa2e092014-08-20 17:01:23 -0700278 server.register_function(interpreter.hello)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800279
Tor Norbye1aa2e092014-08-20 17:01:23 -0700280 # Functions for GUI main loop integration
281 server.register_function(interpreter.enableGui)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800282
283 if port == 0:
284 (h, port) = server.socket.getsockname()
285
286 print(port)
287 print(client_port)
288
289
290 sys.stderr.write(interpreter.get_greeting_msg())
Tor Norbyec667c1f2014-05-28 17:06:51 -0700291 sys.stderr.flush()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800292
293 server.serve_forever()
294
295 return server
296
297
298def StartServer(host, port, client_port):
299 #replace exit (see comments on method)
300 #note that this does not work in jython!!! (sys method can't be replaced).
Tor Norbyec3d3a902014-09-04 13:24:04 -0700301 sys.exit = DoExit
Tor Norbye3a2425a2013-11-04 10:16:08 -0800302
303 interpreter = InterpreterInterface(host, client_port, threading.currentThread())
304
Tor Norbyec3d3a902014-09-04 13:24:04 -0700305 start_new_thread(start_server,(host, port, interpreter))
Tor Norbye3a2425a2013-11-04 10:16:08 -0800306
307 process_exec_queue(interpreter)
308
309
310def get_interpreter():
311 try:
312 interpreterInterface = getattr(__builtin__, 'interpreter')
313 except AttributeError:
314 interpreterInterface = InterpreterInterface(None, None, threading.currentThread())
315 setattr(__builtin__, 'interpreter', interpreterInterface)
316
317 return interpreterInterface
318
319
320def get_completions(text, token, globals, locals):
321 interpreterInterface = get_interpreter()
322
323 interpreterInterface.interpreter.update(globals, locals)
324
325 return interpreterInterface.getCompletions(text, token)
326
Tor Norbye1aa2e092014-08-20 17:01:23 -0700327#===============================================================================
328# Debugger integration
329#===============================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800330
Tor Norbye8668e1b2013-12-20 09:14:04 -0800331def exec_code(code, globals, locals):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800332 interpreterInterface = get_interpreter()
333
334 interpreterInterface.interpreter.update(globals, locals)
335
Tor Norbye8668e1b2013-12-20 09:14:04 -0800336 res = interpreterInterface.needMore(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800337
338 if res:
339 return True
340
Tor Norbye8668e1b2013-12-20 09:14:04 -0800341 interpreterInterface.addExec(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800342
343 return False
344
345
Tor Norbye3a2425a2013-11-04 10:16:08 -0800346
347class ConsoleWriter(InteractiveInterpreter):
348 skip = 0
349
350 def __init__(self, locals=None):
351 InteractiveInterpreter.__init__(self, locals)
352
353 def write(self, data):
354 #if (data.find("global_vars") == -1 and data.find("pydevd") == -1):
355 if self.skip > 0:
356 self.skip -= 1
357 else:
358 if data == "Traceback (most recent call last):\n":
359 self.skip = 1
360 sys.stderr.write(data)
361
Tor Norbye9ea67222014-06-10 18:12:50 -0700362 def showsyntaxerror(self, filename=None):
363 """Display the syntax error that just occurred."""
364 #Override for avoid using sys.excepthook PY-12600
365 type, value, tb = sys.exc_info()
366 sys.last_type = type
367 sys.last_value = value
368 sys.last_traceback = tb
369 if filename and type is SyntaxError:
370 # Work hard to stuff the correct filename in the exception
371 try:
372 msg, (dummy_filename, lineno, offset, line) = value.args
373 except ValueError:
374 # Not the format we expect; leave it alone
375 pass
376 else:
377 # Stuff in the right filename
378 value = SyntaxError(msg, (filename, lineno, offset, line))
379 sys.last_value = value
380 list = traceback.format_exception_only(type, value)
381 sys.stderr.write(''.join(list))
382
383 def showtraceback(self):
384 """Display the exception that just occurred."""
385 #Override for avoid using sys.excepthook PY-12600
386 try:
387 type, value, tb = sys.exc_info()
388 sys.last_type = type
389 sys.last_value = value
390 sys.last_traceback = tb
391 tblist = traceback.extract_tb(tb)
392 del tblist[:1]
393 lines = traceback.format_list(tblist)
394 if lines:
395 lines.insert(0, "Traceback (most recent call last):\n")
396 lines.extend(traceback.format_exception_only(type, value))
397 finally:
398 tblist = tb = None
399 sys.stderr.write(''.join(lines))
400
Tor Norbye3a2425a2013-11-04 10:16:08 -0800401def consoleExec(thread_id, frame_id, expression):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700402 """returns 'False' in case expression is partially correct
Tor Norbye3a2425a2013-11-04 10:16:08 -0800403 """
404 frame = pydevd_vars.findFrame(thread_id, frame_id)
405
406 expression = str(expression.replace('@LINE@', '\n'))
407
408 #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329
409 #(Names not resolved in generator expression in method)
410 #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html
411 updated_globals = {}
412 updated_globals.update(frame.f_globals)
413 updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
414
415 if IPYTHON:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800416 return exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800417
418 interpreter = ConsoleWriter()
419
420 try:
421 code = compile_command(expression)
422 except (OverflowError, SyntaxError, ValueError):
423 # Case 1
424 interpreter.showsyntaxerror()
425 return False
426
427 if code is None:
428 # Case 2
429 return True
430
431 #Case 3
432
433 try:
434 Exec(code, updated_globals, frame.f_locals)
435
436 except SystemExit:
437 raise
438 except:
439 interpreter.showtraceback()
440
441 return False
442
443#=======================================================================================================================
444# main
445#=======================================================================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800446if __name__ == '__main__':
Tor Norbye1aa2e092014-08-20 17:01:23 -0700447 sys.stdin = BaseStdIn()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800448 port, client_port = sys.argv[1:3]
449 import pydev_localhost
450
451 if int(port) == 0 and int(client_port) == 0:
452 (h, p) = pydev_localhost.get_socket_name()
453
454 client_port = p
455
456 StartServer(pydev_localhost.get_localhost(), int(port), int(client_port))