1''' 2Entry point module to start the interactive console. 3''' 4from _pydev_imps._pydev_saved_modules import thread 5from _pydevd_bundle.pydevd_constants import IS_JYTHON, dict_iter_items 6start_new_thread = thread.start_new_thread 7 8try: 9 from code import InteractiveConsole 10except ImportError: 11 from _pydevd_bundle.pydevconsole_code_for_ironpython import InteractiveConsole 12 13from code import compile_command 14from code import InteractiveInterpreter 15 16import os 17import sys 18 19from _pydev_imps._pydev_saved_modules import threading 20from _pydevd_bundle.pydevd_constants import INTERACTIVE_MODE_AVAILABLE, dict_keys 21 22import traceback 23from _pydev_bundle import pydev_log 24 25from _pydevd_bundle import pydevd_vars, pydevd_save_locals 26 27from _pydev_bundle.pydev_imports import Exec, _queue 28 29try: 30 import __builtin__ 31except: 32 import builtins as __builtin__ # @UnresolvedImport 33 34from _pydev_bundle.pydev_console_utils import BaseInterpreterInterface, BaseStdIn 35from _pydev_bundle.pydev_console_utils import CodeFragment 36 37IS_PYTHON_3_ONWARDS = sys.version_info[0] >= 3 38IS_PY24 = sys.version_info[0] == 2 and sys.version_info[1] == 4 39 40 41class Command: 42 43 def __init__(self, interpreter, code_fragment): 44 """ 45 :type code_fragment: CodeFragment 46 :type interpreter: InteractiveConsole 47 """ 48 self.interpreter = interpreter 49 self.code_fragment = code_fragment 50 self.more = None 51 52 def symbol_for_fragment(code_fragment): 53 if code_fragment.is_single_line: 54 symbol = 'single' 55 else: 56 if IS_JYTHON: 57 symbol = 'single' # Jython doesn't support exec 58 else: 59 symbol = 'exec' 60 return symbol 61 62 symbol_for_fragment = staticmethod(symbol_for_fragment) 63 64 def run(self): 65 text = self.code_fragment.text 66 symbol = self.symbol_for_fragment(self.code_fragment) 67 68 self.more = self.interpreter.runsource(text, '<input>', symbol) 69 70 71try: 72 try: 73 execfile # Not in Py3k 74 except NameError: 75 from _pydev_bundle.pydev_imports import execfile 76 77 __builtin__.execfile = execfile 78except: 79 pass 80 81# Pull in runfile, the interface to UMD that wraps execfile 82from _pydev_bundle.pydev_umd import runfile, _set_globals_function 83if sys.version_info[0] >= 3: 84 import builtins # @UnresolvedImport 85 builtins.runfile = runfile 86else: 87 import __builtin__ 88 __builtin__.runfile = runfile 89 90 91#======================================================================================================================= 92# InterpreterInterface 93#======================================================================================================================= 94class InterpreterInterface(BaseInterpreterInterface): 95 ''' 96 The methods in this class should be registered in the xml-rpc server. 97 ''' 98 99 def __init__(self, host, client_port, mainThread, connect_status_queue=None): 100 BaseInterpreterInterface.__init__(self, mainThread, connect_status_queue) 101 self.client_port = client_port 102 self.host = host 103 self.namespace = {} 104 self.interpreter = InteractiveConsole(self.namespace) 105 self._input_error_printed = False 106 107 def do_add_exec(self, codeFragment): 108 command = Command(self.interpreter, codeFragment) 109 command.run() 110 return command.more 111 112 def get_namespace(self): 113 return self.namespace 114 115 def getCompletions(self, text, act_tok): 116 try: 117 from _pydev_bundle._pydev_completer import Completer 118 119 completer = Completer(self.namespace, None) 120 return completer.complete(act_tok) 121 except: 122 pydev_log.exception() 123 return [] 124 125 def close(self): 126 sys.exit(0) 127 128 def get_greeting_msg(self): 129 return 'PyDev console: starting.\n' 130 131 132class _ProcessExecQueueHelper: 133 _debug_hook = None 134 _return_control_osc = False 135 136 137def set_debug_hook(debug_hook): 138 _ProcessExecQueueHelper._debug_hook = debug_hook 139 140 141def activate_mpl_if_already_imported(interpreter): 142 if interpreter.mpl_modules_for_patching: 143 for module in dict_keys(interpreter.mpl_modules_for_patching): 144 if module in sys.modules: 145 activate_function = interpreter.mpl_modules_for_patching.pop(module) 146 activate_function() 147 148 149def init_set_return_control_back(interpreter): 150 from pydev_ipython.inputhook import set_return_control_callback 151 152 def return_control(): 153 ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find 154 out if they should cede control and return ''' 155 if _ProcessExecQueueHelper._debug_hook: 156 # Some of the input hooks check return control without doing 157 # a single operation, so we don't return True on every 158 # call when the debug hook is in place to allow the GUI to run 159 # XXX: Eventually the inputhook code will have diverged enough 160 # from the IPython source that it will be worthwhile rewriting 161 # it rather than pretending to maintain the old API 162 _ProcessExecQueueHelper._return_control_osc = not _ProcessExecQueueHelper._return_control_osc 163 if _ProcessExecQueueHelper._return_control_osc: 164 return True 165 166 if not interpreter.exec_queue.empty(): 167 return True 168 return False 169 170 set_return_control_callback(return_control) 171 172 173def init_mpl_in_console(interpreter): 174 init_set_return_control_back(interpreter) 175 176 if not INTERACTIVE_MODE_AVAILABLE: 177 return 178 179 activate_mpl_if_already_imported(interpreter) 180 from _pydev_bundle.pydev_import_hook import import_hook_manager 181 for mod in dict_keys(interpreter.mpl_modules_for_patching): 182 import_hook_manager.add_module_name(mod, interpreter.mpl_modules_for_patching.pop(mod)) 183 184 185if sys.platform != 'win32': 186 187 if not hasattr(os, 'kill'): # Jython may not have it. 188 189 def pid_exists(pid): 190 return True 191 192 else: 193 194 def pid_exists(pid): 195 # Note that this function in the face of errors will conservatively consider that 196 # the pid is still running (because we'll exit the current process when it's 197 # no longer running, so, we need to be 100% sure it actually exited). 198 199 import errno 200 if pid == 0: 201 # According to "man 2 kill" PID 0 has a special meaning: 202 # it refers to <<every process in the process group of the 203 # calling process>> so we don't want to go any further. 204 # If we get here it means this UNIX platform *does* have 205 # a process with id 0. 206 return True 207 try: 208 os.kill(pid, 0) 209 except OSError as err: 210 if err.errno == errno.ESRCH: 211 # ESRCH == No such process 212 return False 213 elif err.errno == errno.EPERM: 214 # EPERM clearly means there's a process to deny access to 215 return True 216 else: 217 # According to "man 2 kill" possible error values are 218 # (EINVAL, EPERM, ESRCH) therefore we should never get 219 # here. If we do, although it's an error, consider it 220 # exists (see first comment in this function). 221 return True 222 else: 223 return True 224 225else: 226 227 def pid_exists(pid): 228 # Note that this function in the face of errors will conservatively consider that 229 # the pid is still running (because we'll exit the current process when it's 230 # no longer running, so, we need to be 100% sure it actually exited). 231 import ctypes 232 kernel32 = ctypes.windll.kernel32 233 234 PROCESS_QUERY_INFORMATION = 0x0400 235 PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 236 ERROR_INVALID_PARAMETER = 0x57 237 STILL_ACTIVE = 259 238 239 process = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, 0, pid) 240 if not process: 241 err = kernel32.GetLastError() 242 if err == ERROR_INVALID_PARAMETER: 243 # Means it doesn't exist (pid parameter is wrong). 244 return False 245 246 # There was some unexpected error (such as access denied), so 247 # consider it exists (although it could be something else, but we don't want 248 # to raise any errors -- so, just consider it exists). 249 return True 250 251 try: 252 zero = ctypes.c_int(0) 253 exit_code = ctypes.pointer(zero) 254 255 exit_code_suceeded = kernel32.GetExitCodeProcess(process, exit_code) 256 if not exit_code_suceeded: 257 # There was some unexpected error (such as access denied), so 258 # consider it exists (although it could be something else, but we don't want 259 # to raise any errors -- so, just consider it exists). 260 return True 261 262 elif bool(exit_code.contents.value) and int(exit_code.contents.value) != STILL_ACTIVE: 263 return False 264 finally: 265 kernel32.CloseHandle(process) 266 267 return True 268 269 270def process_exec_queue(interpreter): 271 init_mpl_in_console(interpreter) 272 from pydev_ipython.inputhook import get_inputhook 273 try: 274 kill_if_pid_not_alive = int(os.environ.get('PYDEV_ECLIPSE_PID', '-1')) 275 except: 276 kill_if_pid_not_alive = -1 277 278 while 1: 279 if kill_if_pid_not_alive != -1: 280 if not pid_exists(kill_if_pid_not_alive): 281 exit() 282 283 # Running the request may have changed the inputhook in use 284 inputhook = get_inputhook() 285 286 if _ProcessExecQueueHelper._debug_hook: 287 _ProcessExecQueueHelper._debug_hook() 288 289 if inputhook: 290 try: 291 # Note: it'll block here until return_control returns True. 292 inputhook() 293 except: 294 pydev_log.exception() 295 try: 296 try: 297 code_fragment = interpreter.exec_queue.get(block=True, timeout=1 / 20.) # 20 calls/second 298 except _queue.Empty: 299 continue 300 301 if callable(code_fragment): 302 # It can be a callable (i.e.: something that must run in the main 303 # thread can be put in the queue for later execution). 304 code_fragment() 305 else: 306 more = interpreter.add_exec(code_fragment) 307 except KeyboardInterrupt: 308 interpreter.buffer = None 309 continue 310 except SystemExit: 311 raise 312 except: 313 pydev_log.exception('Error processing queue on pydevconsole.') 314 exit() 315 316 317if 'IPYTHONENABLE' in os.environ: 318 IPYTHON = os.environ['IPYTHONENABLE'] == 'True' 319else: 320 # By default, don't use IPython because occasionally changes 321 # in IPython break pydevd. 322 IPYTHON = False 323 324try: 325 try: 326 exitfunc = sys.exitfunc 327 except AttributeError: 328 exitfunc = None 329 330 if IPYTHON: 331 from _pydev_bundle.pydev_ipython_console import InterpreterInterface 332 if exitfunc is not None: 333 sys.exitfunc = exitfunc 334 else: 335 try: 336 delattr(sys, 'exitfunc') 337 except: 338 pass 339except: 340 IPYTHON = False 341 pass 342 343 344#======================================================================================================================= 345# _DoExit 346#======================================================================================================================= 347def do_exit(*args): 348 ''' 349 We have to override the exit because calling sys.exit will only actually exit the main thread, 350 and as we're in a Xml-rpc server, that won't work. 351 ''' 352 353 try: 354 import java.lang.System 355 356 java.lang.System.exit(1) 357 except ImportError: 358 if len(args) == 1: 359 os._exit(args[0]) 360 else: 361 os._exit(0) 362 363 364#======================================================================================================================= 365# start_console_server 366#======================================================================================================================= 367def start_console_server(host, port, interpreter): 368 try: 369 if port == 0: 370 host = '' 371 372 # I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse. 373 from _pydev_bundle.pydev_imports import SimpleXMLRPCServer as XMLRPCServer # @Reimport 374 375 try: 376 if IS_PY24: 377 server = XMLRPCServer((host, port), logRequests=False) 378 else: 379 server = XMLRPCServer((host, port), logRequests=False, allow_none=True) 380 381 except: 382 sys.stderr.write('Error starting server with host: "%s", port: "%s", client_port: "%s"\n' % (host, port, interpreter.client_port)) 383 sys.stderr.flush() 384 raise 385 386 # Tell UMD the proper default namespace 387 _set_globals_function(interpreter.get_namespace) 388 389 server.register_function(interpreter.execLine) 390 server.register_function(interpreter.execMultipleLines) 391 server.register_function(interpreter.getCompletions) 392 server.register_function(interpreter.getFrame) 393 server.register_function(interpreter.getVariable) 394 server.register_function(interpreter.changeVariable) 395 server.register_function(interpreter.getDescription) 396 server.register_function(interpreter.close) 397 server.register_function(interpreter.interrupt) 398 server.register_function(interpreter.handshake) 399 server.register_function(interpreter.connectToDebugger) 400 server.register_function(interpreter.hello) 401 server.register_function(interpreter.getArray) 402 server.register_function(interpreter.evaluate) 403 server.register_function(interpreter.ShowConsole) 404 server.register_function(interpreter.loadFullValue) 405 406 # Functions for GUI main loop integration 407 server.register_function(interpreter.enableGui) 408 409 if port == 0: 410 (h, port) = server.socket.getsockname() 411 412 print(port) 413 print(interpreter.client_port) 414 415 while True: 416 try: 417 server.serve_forever() 418 except: 419 # Ugly code to be py2/3 compatible 420 # https://sw-brainwy.rhcloud.com/tracker/PyDev/534: 421 # Unhandled "interrupted system call" error in the pydevconsol.py 422 e = sys.exc_info()[1] 423 retry = False 424 try: 425 retry = e.args[0] == 4 # errno.EINTR 426 except: 427 pass 428 if not retry: 429 raise 430 # Otherwise, keep on going 431 return server 432 except: 433 pydev_log.exception() 434 # Notify about error to avoid long waiting 435 connection_queue = interpreter.get_connect_status_queue() 436 if connection_queue is not None: 437 connection_queue.put(False) 438 439 440def start_server(host, port, client_port): 441 # replace exit (see comments on method) 442 # note that this does not work in jython!!! (sys method can't be replaced). 443 sys.exit = do_exit 444 445 interpreter = InterpreterInterface(host, client_port, threading.currentThread()) 446 447 start_new_thread(start_console_server, (host, port, interpreter)) 448 449 process_exec_queue(interpreter) 450 451 452def get_ipython_hidden_vars(): 453 if IPYTHON and hasattr(__builtin__, 'interpreter'): 454 interpreter = get_interpreter() 455 return interpreter.get_ipython_hidden_vars_dict() 456 457 458def get_interpreter(): 459 try: 460 interpreterInterface = getattr(__builtin__, 'interpreter') 461 except AttributeError: 462 interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) 463 __builtin__.interpreter = interpreterInterface 464 sys.stderr.write(interpreterInterface.get_greeting_msg()) 465 sys.stderr.flush() 466 467 return interpreterInterface 468 469 470def get_completions(text, token, globals, locals): 471 interpreterInterface = get_interpreter() 472 473 interpreterInterface.interpreter.update(globals, locals) 474 475 return interpreterInterface.getCompletions(text, token) 476 477#=============================================================================== 478# Debugger integration 479#=============================================================================== 480 481 482def exec_code(code, globals, locals, debugger): 483 interpreterInterface = get_interpreter() 484 interpreterInterface.interpreter.update(globals, locals) 485 486 res = interpreterInterface.need_more(code) 487 488 if res: 489 return True 490 491 interpreterInterface.add_exec(code, debugger) 492 493 return False 494 495 496class ConsoleWriter(InteractiveInterpreter): 497 skip = 0 498 499 def __init__(self, locals=None): 500 InteractiveInterpreter.__init__(self, locals) 501 502 def write(self, data): 503 # if (data.find("global_vars") == -1 and data.find("pydevd") == -1): 504 if self.skip > 0: 505 self.skip -= 1 506 else: 507 if data == "Traceback (most recent call last):\n": 508 self.skip = 1 509 sys.stderr.write(data) 510 511 def showsyntaxerror(self, filename=None): 512 """Display the syntax error that just occurred.""" 513 # Override for avoid using sys.excepthook PY-12600 514 type, value, tb = sys.exc_info() 515 sys.last_type = type 516 sys.last_value = value 517 sys.last_traceback = tb 518 if filename and type is SyntaxError: 519 # Work hard to stuff the correct filename in the exception 520 try: 521 msg, (dummy_filename, lineno, offset, line) = value.args 522 except ValueError: 523 # Not the format we expect; leave it alone 524 pass 525 else: 526 # Stuff in the right filename 527 value = SyntaxError(msg, (filename, lineno, offset, line)) 528 sys.last_value = value 529 list = traceback.format_exception_only(type, value) 530 sys.stderr.write(''.join(list)) 531 532 def showtraceback(self, *args, **kwargs): 533 """Display the exception that just occurred.""" 534 # Override for avoid using sys.excepthook PY-12600 535 try: 536 type, value, tb = sys.exc_info() 537 sys.last_type = type 538 sys.last_value = value 539 sys.last_traceback = tb 540 tblist = traceback.extract_tb(tb) 541 del tblist[:1] 542 lines = traceback.format_list(tblist) 543 if lines: 544 lines.insert(0, "Traceback (most recent call last):\n") 545 lines.extend(traceback.format_exception_only(type, value)) 546 finally: 547 tblist = tb = None 548 sys.stderr.write(''.join(lines)) 549 550 551def console_exec(thread_id, frame_id, expression, dbg): 552 """returns 'False' in case expression is partially correct 553 """ 554 frame = dbg.find_frame(thread_id, frame_id) 555 556 is_multiline = expression.count('@LINE@') > 1 557 expression = str(expression.replace('@LINE@', '\n')) 558 559 # Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329 560 # (Names not resolved in generator expression in method) 561 # See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html 562 updated_globals = {} 563 updated_globals.update(frame.f_globals) 564 updated_globals.update(frame.f_locals) # locals later because it has precedence over the actual globals 565 566 if IPYTHON: 567 need_more = exec_code(CodeFragment(expression), updated_globals, frame.f_locals, dbg) 568 if not need_more: 569 pydevd_save_locals.save_locals(frame) 570 return need_more 571 572 interpreter = ConsoleWriter() 573 574 if not is_multiline: 575 try: 576 code = compile_command(expression) 577 except (OverflowError, SyntaxError, ValueError): 578 # Case 1 579 interpreter.showsyntaxerror() 580 return False 581 if code is None: 582 # Case 2 583 return True 584 else: 585 code = expression 586 587 # Case 3 588 589 try: 590 Exec(code, updated_globals, frame.f_locals) 591 592 except SystemExit: 593 raise 594 except: 595 interpreter.showtraceback() 596 else: 597 pydevd_save_locals.save_locals(frame) 598 return False 599 600 601#======================================================================================================================= 602# main 603#======================================================================================================================= 604if __name__ == '__main__': 605 # Important: don't use this module directly as the __main__ module, rather, import itself as pydevconsole 606 # so that we don't get multiple pydevconsole modules if it's executed directly (otherwise we'd have multiple 607 # representations of its classes). 608 # See: https://sw-brainwy.rhcloud.com/tracker/PyDev/446: 609 # 'Variables' and 'Expressions' views stopped working when debugging interactive console 610 import pydevconsole 611 sys.stdin = pydevconsole.BaseStdIn(sys.stdin) 612 port, client_port = sys.argv[1:3] 613 from _pydev_bundle import pydev_localhost 614 615 if int(port) == 0 and int(client_port) == 0: 616 (h, p) = pydev_localhost.get_socket_name() 617 618 client_port = p 619 620 pydevconsole.start_server(pydev_localhost.get_localhost(), int(port), int(client_port)) 621