blob: 444aa2d1c48b0ac98bb7e8475b17f5bc51e2cb71 [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
Tor Norbye3a2425a2013-11-04 10:16:08 -080083except:
84 pass
85
Tor Norbyee782c572014-09-18 11:43:07 -070086# Pull in runfile, the interface to UMD that wraps execfile
87from pydev_umd import runfile, _set_globals_function
88try:
89 import builtins
90 builtins.runfile = runfile
91except:
92 import __builtin__
93 __builtin__.runfile = runfile
94
Tor Norbye3a2425a2013-11-04 10:16:08 -080095
96#=======================================================================================================================
97# InterpreterInterface
98#=======================================================================================================================
99class InterpreterInterface(BaseInterpreterInterface):
100 '''
101 The methods in this class should be registered in the xml-rpc server.
102 '''
103
104 def __init__(self, host, client_port, mainThread):
105 BaseInterpreterInterface.__init__(self, mainThread)
106 self.client_port = client_port
107 self.host = host
108 self.namespace = {}
109 self.interpreter = InteractiveConsole(self.namespace)
110 self._input_error_printed = False
111
112
Tor Norbye8668e1b2013-12-20 09:14:04 -0800113 def doAddExec(self, codeFragment):
114 command = Command(self.interpreter, codeFragment)
115 command.run()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800116 return command.more
117
118
119 def getNamespace(self):
120 return self.namespace
121
122
123 def getCompletions(self, text, act_tok):
124 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700125 from _pydev_completer import Completer
Tor Norbye3a2425a2013-11-04 10:16:08 -0800126
127 completer = Completer(self.namespace, None)
128 return completer.complete(act_tok)
129 except:
130 import traceback
131
132 traceback.print_exc()
133 return []
Tor Norbye1aa2e092014-08-20 17:01:23 -0700134
Tor Norbye3a2425a2013-11-04 10:16:08 -0800135 def close(self):
136 sys.exit(0)
137
138 def get_greeting_msg(self):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700139 return 'PyDev console: starting.\n'
140
141
142class _ProcessExecQueueHelper:
143 _debug_hook = None
144 _return_control_osc = False
145
146def set_debug_hook(debug_hook):
147 _ProcessExecQueueHelper._debug_hook = debug_hook
Tor Norbye3a2425a2013-11-04 10:16:08 -0800148
149
150def process_exec_queue(interpreter):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700151
152 from pydev_ipython.inputhook import get_inputhook, set_return_control_callback
153
154 def return_control():
155 ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find
156 out if they should cede control and return '''
157 if _ProcessExecQueueHelper._debug_hook:
158 # Some of the input hooks check return control without doing
159 # a single operation, so we don't return True on every
160 # call when the debug hook is in place to allow the GUI to run
161 # XXX: Eventually the inputhook code will have diverged enough
162 # from the IPython source that it will be worthwhile rewriting
163 # it rather than pretending to maintain the old API
164 _ProcessExecQueueHelper._return_control_osc = not _ProcessExecQueueHelper._return_control_osc
165 if _ProcessExecQueueHelper._return_control_osc:
166 return True
167
168 if not interpreter.exec_queue.empty():
169 return True
170 return False
171
172 set_return_control_callback(return_control)
173
Tor Norbye3a2425a2013-11-04 10:16:08 -0800174 while 1:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700175 # Running the request may have changed the inputhook in use
176 inputhook = get_inputhook()
177
178 if _ProcessExecQueueHelper._debug_hook:
179 _ProcessExecQueueHelper._debug_hook()
180
181 if inputhook:
182 try:
183 # Note: it'll block here until return_control returns True.
184 inputhook()
185 except:
186 import traceback;traceback.print_exc()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800187 try:
188 try:
Tor Norbye1aa2e092014-08-20 17:01:23 -0700189 code_fragment = interpreter.exec_queue.get(block=True, timeout=1/20.) # 20 calls/second
Tor Norbye3a2425a2013-11-04 10:16:08 -0800190 except _queue.Empty:
191 continue
192
Tor Norbye1aa2e092014-08-20 17:01:23 -0700193 if callable(code_fragment):
194 # It can be a callable (i.e.: something that must run in the main
195 # thread can be put in the queue for later execution).
196 code_fragment()
197 else:
198 more = interpreter.addExec(code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800199 except KeyboardInterrupt:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800200 interpreter.buffer = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800201 continue
202 except SystemExit:
203 raise
204 except:
205 type, value, tb = sys.exc_info()
206 traceback.print_exception(type, value, tb, file=sys.__stderr__)
207 exit()
208
209
Tor Norbyec667c1f2014-05-28 17:06:51 -0700210if 'IPYTHONENABLE' in os.environ:
211 IPYTHON = os.environ['IPYTHONENABLE'] == 'True'
212else:
213 IPYTHON = True
214
Tor Norbye3a2425a2013-11-04 10:16:08 -0800215try:
216 try:
217 exitfunc = sys.exitfunc
218 except AttributeError:
219 exitfunc = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800220
Tor Norbyec667c1f2014-05-28 17:06:51 -0700221 if IPYTHON:
222 from pydev_ipython_console import InterpreterInterface
223 if exitfunc is not None:
224 sys.exitfunc = exitfunc
225 else:
226 try:
227 delattr(sys, 'exitfunc')
228 except:
229 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800230except:
231 IPYTHON = False
Tor Norbyec667c1f2014-05-28 17:06:51 -0700232 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800233
234#=======================================================================================================================
235# _DoExit
236#=======================================================================================================================
Tor Norbyec3d3a902014-09-04 13:24:04 -0700237def DoExit(*args):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800238 '''
239 We have to override the exit because calling sys.exit will only actually exit the main thread,
240 and as we're in a Xml-rpc server, that won't work.
241 '''
242
243 try:
244 import java.lang.System
245
246 java.lang.System.exit(1)
247 except ImportError:
248 if len(args) == 1:
249 os._exit(args[0])
250 else:
251 os._exit(0)
252
253
254def handshake():
255 return "PyCharm"
256
257
Tor Norbye3a2425a2013-11-04 10:16:08 -0800258#=======================================================================================================================
259# StartServer
260#=======================================================================================================================
261def start_server(host, port, interpreter):
262 if port == 0:
263 host = ''
264
Tor Norbye1aa2e092014-08-20 17:01:23 -0700265 #I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse.
266 from pydev_imports import SimpleXMLRPCServer as XMLRPCServer #@Reimport
Tor Norbye3a2425a2013-11-04 10:16:08 -0800267
268 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700269 server = XMLRPCServer((host, port), logRequests=False, allow_none=True)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800270
271 except:
272 sys.stderr.write('Error starting server with host: %s, port: %s, client_port: %s\n' % (host, port, client_port))
273 raise
274
Tor Norbyee782c572014-09-18 11:43:07 -0700275 # Tell UMD the proper default namespace
276 _set_globals_function(interpreter.getNamespace)
277
Tor Norbye3a2425a2013-11-04 10:16:08 -0800278 server.register_function(interpreter.execLine)
Tor Norbye8668e1b2013-12-20 09:14:04 -0800279 server.register_function(interpreter.execMultipleLines)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800280 server.register_function(interpreter.getCompletions)
281 server.register_function(interpreter.getFrame)
282 server.register_function(interpreter.getVariable)
283 server.register_function(interpreter.changeVariable)
284 server.register_function(interpreter.getDescription)
285 server.register_function(interpreter.close)
286 server.register_function(interpreter.interrupt)
287 server.register_function(handshake)
Tor Norbyec667c1f2014-05-28 17:06:51 -0700288 server.register_function(interpreter.connectToDebugger)
Tor Norbye1aa2e092014-08-20 17:01:23 -0700289 server.register_function(interpreter.hello)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800290
Tor Norbye1aa2e092014-08-20 17:01:23 -0700291 # Functions for GUI main loop integration
292 server.register_function(interpreter.enableGui)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800293
294 if port == 0:
295 (h, port) = server.socket.getsockname()
296
297 print(port)
298 print(client_port)
299
300
301 sys.stderr.write(interpreter.get_greeting_msg())
Tor Norbyec667c1f2014-05-28 17:06:51 -0700302 sys.stderr.flush()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800303
304 server.serve_forever()
305
306 return server
307
308
309def StartServer(host, port, client_port):
310 #replace exit (see comments on method)
311 #note that this does not work in jython!!! (sys method can't be replaced).
Tor Norbyec3d3a902014-09-04 13:24:04 -0700312 sys.exit = DoExit
Tor Norbye3a2425a2013-11-04 10:16:08 -0800313
314 interpreter = InterpreterInterface(host, client_port, threading.currentThread())
315
Tor Norbyec3d3a902014-09-04 13:24:04 -0700316 start_new_thread(start_server,(host, port, interpreter))
Tor Norbye3a2425a2013-11-04 10:16:08 -0800317
318 process_exec_queue(interpreter)
319
320
321def get_interpreter():
322 try:
323 interpreterInterface = getattr(__builtin__, 'interpreter')
324 except AttributeError:
325 interpreterInterface = InterpreterInterface(None, None, threading.currentThread())
326 setattr(__builtin__, 'interpreter', interpreterInterface)
327
328 return interpreterInterface
329
330
331def get_completions(text, token, globals, locals):
332 interpreterInterface = get_interpreter()
333
334 interpreterInterface.interpreter.update(globals, locals)
335
336 return interpreterInterface.getCompletions(text, token)
337
Tor Norbye1aa2e092014-08-20 17:01:23 -0700338#===============================================================================
339# Debugger integration
340#===============================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800341
Tor Norbye8668e1b2013-12-20 09:14:04 -0800342def exec_code(code, globals, locals):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800343 interpreterInterface = get_interpreter()
344
345 interpreterInterface.interpreter.update(globals, locals)
346
Tor Norbye8668e1b2013-12-20 09:14:04 -0800347 res = interpreterInterface.needMore(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800348
349 if res:
350 return True
351
Tor Norbye8668e1b2013-12-20 09:14:04 -0800352 interpreterInterface.addExec(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800353
354 return False
355
356
Tor Norbye3a2425a2013-11-04 10:16:08 -0800357
358class ConsoleWriter(InteractiveInterpreter):
359 skip = 0
360
361 def __init__(self, locals=None):
362 InteractiveInterpreter.__init__(self, locals)
363
364 def write(self, data):
365 #if (data.find("global_vars") == -1 and data.find("pydevd") == -1):
366 if self.skip > 0:
367 self.skip -= 1
368 else:
369 if data == "Traceback (most recent call last):\n":
370 self.skip = 1
371 sys.stderr.write(data)
372
Tor Norbye9ea67222014-06-10 18:12:50 -0700373 def showsyntaxerror(self, filename=None):
374 """Display the syntax error that just occurred."""
375 #Override for avoid using sys.excepthook PY-12600
376 type, value, tb = sys.exc_info()
377 sys.last_type = type
378 sys.last_value = value
379 sys.last_traceback = tb
380 if filename and type is SyntaxError:
381 # Work hard to stuff the correct filename in the exception
382 try:
383 msg, (dummy_filename, lineno, offset, line) = value.args
384 except ValueError:
385 # Not the format we expect; leave it alone
386 pass
387 else:
388 # Stuff in the right filename
389 value = SyntaxError(msg, (filename, lineno, offset, line))
390 sys.last_value = value
391 list = traceback.format_exception_only(type, value)
392 sys.stderr.write(''.join(list))
393
394 def showtraceback(self):
395 """Display the exception that just occurred."""
396 #Override for avoid using sys.excepthook PY-12600
397 try:
398 type, value, tb = sys.exc_info()
399 sys.last_type = type
400 sys.last_value = value
401 sys.last_traceback = tb
402 tblist = traceback.extract_tb(tb)
403 del tblist[:1]
404 lines = traceback.format_list(tblist)
405 if lines:
406 lines.insert(0, "Traceback (most recent call last):\n")
407 lines.extend(traceback.format_exception_only(type, value))
408 finally:
409 tblist = tb = None
410 sys.stderr.write(''.join(lines))
411
Tor Norbye3a2425a2013-11-04 10:16:08 -0800412def consoleExec(thread_id, frame_id, expression):
Tor Norbye1aa2e092014-08-20 17:01:23 -0700413 """returns 'False' in case expression is partially correct
Tor Norbye3a2425a2013-11-04 10:16:08 -0800414 """
415 frame = pydevd_vars.findFrame(thread_id, frame_id)
416
417 expression = str(expression.replace('@LINE@', '\n'))
418
419 #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329
420 #(Names not resolved in generator expression in method)
421 #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html
422 updated_globals = {}
423 updated_globals.update(frame.f_globals)
424 updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
425
426 if IPYTHON:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800427 return exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800428
429 interpreter = ConsoleWriter()
430
431 try:
432 code = compile_command(expression)
433 except (OverflowError, SyntaxError, ValueError):
434 # Case 1
435 interpreter.showsyntaxerror()
436 return False
437
438 if code is None:
439 # Case 2
440 return True
441
442 #Case 3
443
444 try:
445 Exec(code, updated_globals, frame.f_locals)
446
447 except SystemExit:
448 raise
449 except:
450 interpreter.showtraceback()
451
452 return False
453
454#=======================================================================================================================
455# main
456#=======================================================================================================================
Tor Norbye3a2425a2013-11-04 10:16:08 -0800457if __name__ == '__main__':
Tor Norbye1aa2e092014-08-20 17:01:23 -0700458 sys.stdin = BaseStdIn()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800459 port, client_port = sys.argv[1:3]
460 import pydev_localhost
461
462 if int(port) == 0 and int(client_port) == 0:
463 (h, p) = pydev_localhost.get_socket_name()
464
465 client_port = p
466
467 StartServer(pydev_localhost.get_localhost(), int(port), int(client_port))