blob: 7edf089d526cd7bb53042dca8fecb38b6b417f57 [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 Norbye8668e1b2013-12-20 09:14:04 -080013from pydevd_constants import IS_JYTHON
Tor Norbye3a2425a2013-11-04 10:16:08 -080014
15if USE_LIB_COPY:
16 import _pydev_threading as threading
17else:
18 import threading
19
20import traceback
21import fix_getpass
22fix_getpass.fixGetpass()
23
24import pydevd_vars
25
Tor Norbyec667c1f2014-05-28 17:06:51 -070026from pydev_imports import Exec
Tor Norbye3a2425a2013-11-04 10:16:08 -080027
28try:
29 if USE_LIB_COPY:
30 import _pydev_Queue as _queue
31 else:
32 import Queue as _queue
33except:
34 import queue as _queue
35
36try:
37 import __builtin__
38except:
39 import builtins as __builtin__
40
41try:
42 False
43 True
44except NameError: # version < 2.3 -- didn't have the True/False builtins
45 import __builtin__
46
47 setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax
48 setattr(__builtin__, 'False', 0)
49
50from pydev_console_utils import BaseInterpreterInterface
Tor Norbye8668e1b2013-12-20 09:14:04 -080051from pydev_console_utils import CodeFragment
Tor Norbye3a2425a2013-11-04 10:16:08 -080052
53IS_PYTHON_3K = False
54
55try:
56 if sys.version_info[0] == 3:
57 IS_PYTHON_3K = True
58except:
59 #That's OK, not all versions of python have sys.version_info
60 pass
61
62try:
63 try:
64 if USE_LIB_COPY:
65 import _pydev_xmlrpclib as xmlrpclib
66 else:
67 import xmlrpclib
68 except ImportError:
69 import xmlrpc.client as xmlrpclib
70except ImportError:
71 import _pydev_xmlrpclib as xmlrpclib
72
Tor Norbye3a2425a2013-11-04 10:16:08 -080073
Tor Norbye8668e1b2013-12-20 09:14:04 -080074class Command:
75 def __init__(self, interpreter, code_fragment):
76 """
77 :type code_fragment: CodeFragment
78 :type interpreter: InteractiveConsole
79 """
80 self.interpreter = interpreter
81 self.code_fragment = code_fragment
82 self.more = None
Tor Norbye3a2425a2013-11-04 10:16:08 -080083
Tor Norbye8668e1b2013-12-20 09:14:04 -080084 @staticmethod
85 def symbol_for_fragment(code_fragment):
86 if code_fragment.is_single_line:
87 symbol = 'single'
Tor Norbye3a2425a2013-11-04 10:16:08 -080088 else:
Tor Norbye8668e1b2013-12-20 09:14:04 -080089 symbol = 'exec' # Jython doesn't support this
90 return symbol
Tor Norbye3a2425a2013-11-04 10:16:08 -080091
Tor Norbye8668e1b2013-12-20 09:14:04 -080092 def run(self):
93 text = self.code_fragment.text
94 symbol = self.symbol_for_fragment(self.code_fragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -080095
Tor Norbye8668e1b2013-12-20 09:14:04 -080096 self.more = self.interpreter.runsource(text, '<input>', symbol)
Tor Norbye3a2425a2013-11-04 10:16:08 -080097
98try:
99 try:
100 execfile #Not in Py3k
101 except NameError:
102 from pydev_imports import execfile
103
104 __builtin__.execfile = execfile
105
106except:
107 pass
108
109
110#=======================================================================================================================
111# InterpreterInterface
112#=======================================================================================================================
113class InterpreterInterface(BaseInterpreterInterface):
114 '''
115 The methods in this class should be registered in the xml-rpc server.
116 '''
117
118 def __init__(self, host, client_port, mainThread):
119 BaseInterpreterInterface.__init__(self, mainThread)
120 self.client_port = client_port
121 self.host = host
122 self.namespace = {}
123 self.interpreter = InteractiveConsole(self.namespace)
124 self._input_error_printed = False
125
126
Tor Norbye8668e1b2013-12-20 09:14:04 -0800127 def doAddExec(self, codeFragment):
128 command = Command(self.interpreter, codeFragment)
129 command.run()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800130 return command.more
131
132
133 def getNamespace(self):
134 return self.namespace
135
136
137 def getCompletions(self, text, act_tok):
138 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700139 from _pydev_completer import Completer
Tor Norbye3a2425a2013-11-04 10:16:08 -0800140
141 completer = Completer(self.namespace, None)
142 return completer.complete(act_tok)
143 except:
144 import traceback
145
146 traceback.print_exc()
147 return []
148
149 def close(self):
150 sys.exit(0)
151
152 def get_greeting_msg(self):
Tor Norbyec667c1f2014-05-28 17:06:51 -0700153 return 'PyDev console: starting.'
Tor Norbye3a2425a2013-11-04 10:16:08 -0800154
155
156def process_exec_queue(interpreter):
157 while 1:
158 try:
159 try:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800160 codeFragment = interpreter.exec_queue.get(block=True, timeout=0.05)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800161 except _queue.Empty:
162 continue
163
Tor Norbye8668e1b2013-12-20 09:14:04 -0800164 more = interpreter.addExec(codeFragment)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800165 except KeyboardInterrupt:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800166 interpreter.buffer = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800167 continue
168 except SystemExit:
169 raise
170 except:
171 type, value, tb = sys.exc_info()
172 traceback.print_exception(type, value, tb, file=sys.__stderr__)
173 exit()
174
175
Tor Norbyec667c1f2014-05-28 17:06:51 -0700176if 'IPYTHONENABLE' in os.environ:
177 IPYTHON = os.environ['IPYTHONENABLE'] == 'True'
178else:
179 IPYTHON = True
180
Tor Norbye3a2425a2013-11-04 10:16:08 -0800181try:
182 try:
183 exitfunc = sys.exitfunc
184 except AttributeError:
185 exitfunc = None
Tor Norbye3a2425a2013-11-04 10:16:08 -0800186
Tor Norbyec667c1f2014-05-28 17:06:51 -0700187 if IPYTHON:
188 from pydev_ipython_console import InterpreterInterface
189 if exitfunc is not None:
190 sys.exitfunc = exitfunc
191 else:
192 try:
193 delattr(sys, 'exitfunc')
194 except:
195 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800196except:
197 IPYTHON = False
Tor Norbyec667c1f2014-05-28 17:06:51 -0700198 pass
Tor Norbye3a2425a2013-11-04 10:16:08 -0800199
200#=======================================================================================================================
201# _DoExit
202#=======================================================================================================================
203def _DoExit(*args):
204 '''
205 We have to override the exit because calling sys.exit will only actually exit the main thread,
206 and as we're in a Xml-rpc server, that won't work.
207 '''
208
209 try:
210 import java.lang.System
211
212 java.lang.System.exit(1)
213 except ImportError:
214 if len(args) == 1:
215 os._exit(args[0])
216 else:
217 os._exit(0)
218
219
220def handshake():
221 return "PyCharm"
222
223
224def ipython_editor(interpreter):
225 def editor(file, line):
226 if file is None:
227 file = ""
228 if line is None:
229 line = "-1"
230 interpreter.ipython_editor(file, line)
231
232 return editor
233
234#=======================================================================================================================
235# StartServer
236#=======================================================================================================================
237def start_server(host, port, interpreter):
238 if port == 0:
239 host = ''
240
Tor Norbyec667c1f2014-05-28 17:06:51 -0700241 try:
242 from _pydev_xmlrpc_hook import InputHookedXMLRPCServer as XMLRPCServer #@UnusedImport
243 except:
244 #I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse.
245 from pydev_imports import SimpleXMLRPCServer as XMLRPCServer #@Reimport
Tor Norbye3a2425a2013-11-04 10:16:08 -0800246
247 try:
Tor Norbyec667c1f2014-05-28 17:06:51 -0700248 server = XMLRPCServer((host, port), logRequests=False, allow_none=True)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800249
250 except:
251 sys.stderr.write('Error starting server with host: %s, port: %s, client_port: %s\n' % (host, port, client_port))
252 raise
253
254 server.register_function(interpreter.execLine)
Tor Norbye8668e1b2013-12-20 09:14:04 -0800255 server.register_function(interpreter.execMultipleLines)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800256 server.register_function(interpreter.getCompletions)
257 server.register_function(interpreter.getFrame)
258 server.register_function(interpreter.getVariable)
259 server.register_function(interpreter.changeVariable)
260 server.register_function(interpreter.getDescription)
261 server.register_function(interpreter.close)
262 server.register_function(interpreter.interrupt)
263 server.register_function(handshake)
Tor Norbyec667c1f2014-05-28 17:06:51 -0700264 server.register_function(interpreter.connectToDebugger)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800265
266 if IPYTHON:
267 try:
268 interpreter.interpreter.ipython.hooks.editor = ipython_editor(interpreter)
269 except:
270 pass
271
272 if port == 0:
273 (h, port) = server.socket.getsockname()
274
275 print(port)
276 print(client_port)
277
278
279 sys.stderr.write(interpreter.get_greeting_msg())
Tor Norbyec667c1f2014-05-28 17:06:51 -0700280 sys.stderr.flush()
Tor Norbye3a2425a2013-11-04 10:16:08 -0800281
Tor Norbyec667c1f2014-05-28 17:06:51 -0700282 interpreter.server = server
Tor Norbye3a2425a2013-11-04 10:16:08 -0800283 server.serve_forever()
284
285 return server
286
287
288def StartServer(host, port, client_port):
289 #replace exit (see comments on method)
290 #note that this does not work in jython!!! (sys method can't be replaced).
291 sys.exit = _DoExit
292
293 interpreter = InterpreterInterface(host, client_port, threading.currentThread())
294
295 server_thread = threading.Thread(target=start_server,
296 name='ServerThread',
297 args=(host, port, interpreter))
298 server_thread.setDaemon(True)
299 server_thread.start()
300
301 process_exec_queue(interpreter)
302
303
304def get_interpreter():
305 try:
306 interpreterInterface = getattr(__builtin__, 'interpreter')
307 except AttributeError:
308 interpreterInterface = InterpreterInterface(None, None, threading.currentThread())
309 setattr(__builtin__, 'interpreter', interpreterInterface)
310
311 return interpreterInterface
312
313
314def get_completions(text, token, globals, locals):
315 interpreterInterface = get_interpreter()
316
317 interpreterInterface.interpreter.update(globals, locals)
318
319 return interpreterInterface.getCompletions(text, token)
320
321def get_frame():
Tor Norbyec667c1f2014-05-28 17:06:51 -0700322 interpreterInterface = get_interpreter()
323
Tor Norbye3a2425a2013-11-04 10:16:08 -0800324 return interpreterInterface.getFrame()
325
Tor Norbye8668e1b2013-12-20 09:14:04 -0800326def exec_code(code, globals, locals):
Tor Norbye3a2425a2013-11-04 10:16:08 -0800327 interpreterInterface = get_interpreter()
328
329 interpreterInterface.interpreter.update(globals, locals)
330
Tor Norbye8668e1b2013-12-20 09:14:04 -0800331 res = interpreterInterface.needMore(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800332
333 if res:
334 return True
335
Tor Norbye8668e1b2013-12-20 09:14:04 -0800336 interpreterInterface.addExec(code)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800337
338 return False
339
340
341def read_line(s):
342 ret = ''
343
344 while True:
345 c = s.recv(1)
346
347 if c == '\n' or c == '':
348 break
349 else:
350 ret += c
351
352 return ret
353
354# Debugger integration
355
356class ConsoleWriter(InteractiveInterpreter):
357 skip = 0
358
359 def __init__(self, locals=None):
360 InteractiveInterpreter.__init__(self, locals)
361
362 def write(self, data):
363 #if (data.find("global_vars") == -1 and data.find("pydevd") == -1):
364 if self.skip > 0:
365 self.skip -= 1
366 else:
367 if data == "Traceback (most recent call last):\n":
368 self.skip = 1
369 sys.stderr.write(data)
370
371def consoleExec(thread_id, frame_id, expression):
372 """returns 'False' in case expression is partialy correct
373 """
374 frame = pydevd_vars.findFrame(thread_id, frame_id)
375
376 expression = str(expression.replace('@LINE@', '\n'))
377
378 #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329
379 #(Names not resolved in generator expression in method)
380 #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html
381 updated_globals = {}
382 updated_globals.update(frame.f_globals)
383 updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
384
385 if IPYTHON:
Tor Norbye8668e1b2013-12-20 09:14:04 -0800386 return exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
Tor Norbye3a2425a2013-11-04 10:16:08 -0800387
388 interpreter = ConsoleWriter()
389
390 try:
391 code = compile_command(expression)
392 except (OverflowError, SyntaxError, ValueError):
393 # Case 1
394 interpreter.showsyntaxerror()
395 return False
396
397 if code is None:
398 # Case 2
399 return True
400
401 #Case 3
402
403 try:
404 Exec(code, updated_globals, frame.f_locals)
405
406 except SystemExit:
407 raise
408 except:
409 interpreter.showtraceback()
410
411 return False
412
413#=======================================================================================================================
414# main
415#=======================================================================================================================
416
417
418if __name__ == '__main__':
419 port, client_port = sys.argv[1:3]
420 import pydev_localhost
421
422 if int(port) == 0 and int(client_port) == 0:
423 (h, p) = pydev_localhost.get_socket_name()
424
425 client_port = p
426
427 StartServer(pydev_localhost.get_localhost(), int(port), int(client_port))