''' Entry point module to start the interactive console. ''' from _pydev_imps._pydev_saved_modules import thread from _pydevd_bundle.pydevd_constants import IS_JYTHON, dict_iter_items start_new_thread = thread.start_new_thread try: from code import InteractiveConsole except ImportError: from _pydevd_bundle.pydevconsole_code_for_ironpython import InteractiveConsole from code import compile_command from code import InteractiveInterpreter import os import sys from _pydev_imps._pydev_saved_modules import threading import traceback from _pydev_bundle import fix_getpass fix_getpass.fix_getpass() from _pydevd_bundle import pydevd_vars, pydevd_save_locals from _pydev_bundle.pydev_imports import Exec, _queue try: import __builtin__ except: import builtins as __builtin__ # @UnresolvedImport try: False True except NameError: # version < 2.3 -- didn't have the True/False builtins import __builtin__ setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax setattr(__builtin__, 'False', 0) from _pydev_bundle.pydev_console_utils import BaseInterpreterInterface, BaseStdIn from _pydev_bundle.pydev_console_utils import CodeFragment IS_PYTHON_3K = False IS_PY24 = False try: if sys.version_info[0] == 3: IS_PYTHON_3K = True elif sys.version_info[0] == 2 and sys.version_info[1] == 4: IS_PY24 = True except: #That's OK, not all versions of python have sys.version_info pass class Command: def __init__(self, interpreter, code_fragment): """ :type code_fragment: CodeFragment :type interpreter: InteractiveConsole """ self.interpreter = interpreter self.code_fragment = code_fragment self.more = None def symbol_for_fragment(code_fragment): if code_fragment.is_single_line: symbol = 'single' else: if IS_JYTHON: symbol = 'single' # Jython doesn't support exec else: symbol = 'exec' return symbol symbol_for_fragment = staticmethod(symbol_for_fragment) def run(self): text = self.code_fragment.text symbol = self.symbol_for_fragment(self.code_fragment) self.more = self.interpreter.runsource(text, '', symbol) try: try: execfile #Not in Py3k except NameError: from _pydev_bundle.pydev_imports import execfile __builtin__.execfile = execfile except: pass # Pull in runfile, the interface to UMD that wraps execfile from _pydev_bundle.pydev_umd import runfile, _set_globals_function try: import builtins # @UnresolvedImport builtins.runfile = runfile except: import __builtin__ __builtin__.runfile = runfile #======================================================================================================================= # InterpreterInterface #======================================================================================================================= class InterpreterInterface(BaseInterpreterInterface): ''' The methods in this class should be registered in the xml-rpc server. ''' def __init__(self, host, client_port, mainThread, show_banner=True): BaseInterpreterInterface.__init__(self, mainThread) self.client_port = client_port self.host = host self.namespace = {} self.interpreter = InteractiveConsole(self.namespace) self._input_error_printed = False def do_add_exec(self, codeFragment): command = Command(self.interpreter, codeFragment) command.run() return command.more def get_namespace(self): return self.namespace def getCompletions(self, text, act_tok): try: from _pydev_bundle._pydev_completer import Completer completer = Completer(self.namespace, None) return completer.complete(act_tok) except: import traceback traceback.print_exc() return [] def close(self): sys.exit(0) def get_greeting_msg(self): return 'PyDev console: starting.\n' class _ProcessExecQueueHelper: _debug_hook = None _return_control_osc = False def set_debug_hook(debug_hook): _ProcessExecQueueHelper._debug_hook = debug_hook def process_exec_queue(interpreter): from pydev_ipython.inputhook import get_inputhook, set_return_control_callback def return_control(): ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find out if they should cede control and return ''' if _ProcessExecQueueHelper._debug_hook: # Some of the input hooks check return control without doing # a single operation, so we don't return True on every # call when the debug hook is in place to allow the GUI to run # XXX: Eventually the inputhook code will have diverged enough # from the IPython source that it will be worthwhile rewriting # it rather than pretending to maintain the old API _ProcessExecQueueHelper._return_control_osc = not _ProcessExecQueueHelper._return_control_osc if _ProcessExecQueueHelper._return_control_osc: return True if not interpreter.exec_queue.empty(): return True return False set_return_control_callback(return_control) from _pydev_bundle.pydev_import_hook import import_hook_manager from pydev_ipython.matplotlibtools import activate_matplotlib, activate_pylab, activate_pyplot import_hook_manager.add_module_name("matplotlib", lambda: activate_matplotlib(interpreter.enableGui)) # enable_gui_function in activate_matplotlib should be called in main thread. That's why we call # interpreter.enableGui which put it into the interpreter's exec_queue and executes it in the main thread. import_hook_manager.add_module_name("pylab", activate_pylab) import_hook_manager.add_module_name("pyplot", activate_pyplot) while 1: # Running the request may have changed the inputhook in use inputhook = get_inputhook() if _ProcessExecQueueHelper._debug_hook: _ProcessExecQueueHelper._debug_hook() if inputhook: try: # Note: it'll block here until return_control returns True. inputhook() except: import traceback;traceback.print_exc() try: try: code_fragment = interpreter.exec_queue.get(block=True, timeout=1/20.) # 20 calls/second except _queue.Empty: continue if callable(code_fragment): # It can be a callable (i.e.: something that must run in the main # thread can be put in the queue for later execution). code_fragment() else: more = interpreter.add_exec(code_fragment) except KeyboardInterrupt: interpreter.buffer = None continue except SystemExit: raise except: type, value, tb = sys.exc_info() traceback.print_exception(type, value, tb, file=sys.__stderr__) exit() if 'IPYTHONENABLE' in os.environ: IPYTHON = os.environ['IPYTHONENABLE'] == 'True' else: IPYTHON = True try: try: exitfunc = sys.exitfunc except AttributeError: exitfunc = None if IPYTHON: from _pydev_bundle.pydev_ipython_console import InterpreterInterface if exitfunc is not None: sys.exitfunc = exitfunc else: try: delattr(sys, 'exitfunc') except: pass except: IPYTHON = False pass #======================================================================================================================= # _DoExit #======================================================================================================================= def do_exit(*args): ''' We have to override the exit because calling sys.exit will only actually exit the main thread, and as we're in a Xml-rpc server, that won't work. ''' try: import java.lang.System java.lang.System.exit(1) except ImportError: if len(args) == 1: os._exit(args[0]) else: os._exit(0) def handshake(): return "PyCharm" #======================================================================================================================= # start_console_server #======================================================================================================================= def start_console_server(host, port, interpreter): if port == 0: host = '' #I.e.: supporting the internal Jython version in PyDev to create a Jython interactive console inside Eclipse. from _pydev_bundle.pydev_imports import SimpleXMLRPCServer as XMLRPCServer #@Reimport try: if IS_PY24: server = XMLRPCServer((host, port), logRequests=False) else: server = XMLRPCServer((host, port), logRequests=False, allow_none=True) except: sys.stderr.write('Error starting server with host: "%s", port: "%s", client_port: "%s"\n' % (host, port, interpreter.client_port)) sys.stderr.flush() raise # Tell UMD the proper default namespace _set_globals_function(interpreter.get_namespace) server.register_function(interpreter.execLine) server.register_function(interpreter.execMultipleLines) server.register_function(interpreter.getCompletions) server.register_function(interpreter.getFrame) server.register_function(interpreter.getVariable) server.register_function(interpreter.changeVariable) server.register_function(interpreter.getDescription) server.register_function(interpreter.close) server.register_function(interpreter.interrupt) server.register_function(handshake) server.register_function(interpreter.connectToDebugger) server.register_function(interpreter.hello) server.register_function(interpreter.getArray) server.register_function(interpreter.evaluate) # Functions for GUI main loop integration server.register_function(interpreter.enableGui) if port == 0: (h, port) = server.socket.getsockname() print(port) print(interpreter.client_port) sys.stderr.write(interpreter.get_greeting_msg()) sys.stderr.flush() while True: try: server.serve_forever() except: # Ugly code to be py2/3 compatible # https://sw-brainwy.rhcloud.com/tracker/PyDev/534: # Unhandled "interrupted system call" error in the pydevconsol.py e = sys.exc_info()[1] retry = False try: retry = e.args[0] == 4 #errno.EINTR except: pass if not retry: raise # Otherwise, keep on going return server def start_server(host, port, client_port): #replace exit (see comments on method) #note that this does not work in jython!!! (sys method can't be replaced). sys.exit = do_exit interpreter = InterpreterInterface(host, client_port, threading.currentThread()) start_new_thread(start_console_server,(host, port, interpreter)) process_exec_queue(interpreter) def get_ipython_hidden_vars_dict(): useful_ipython_vars = ['_', '__'] try: if IPYTHON and hasattr(__builtin__, 'interpreter'): pydev_interpreter = get_interpreter().interpreter if hasattr(pydev_interpreter, 'ipython') and hasattr(pydev_interpreter.ipython, 'user_ns_hidden'): user_ns_hidden = pydev_interpreter.ipython.user_ns_hidden if isinstance(user_ns_hidden, dict): # Since IPython 2 dict `user_ns_hidden` contains hidden variables and values user_hidden_dict = user_ns_hidden else: # In IPython 1.x `user_ns_hidden` used to be a set with names of hidden variables user_hidden_dict = dict([(key, val) for key, val in dict_iter_items(pydev_interpreter.ipython.user_ns) if key in user_ns_hidden]) return dict([(key, val) for key, val in dict_iter_items(user_hidden_dict) if key not in useful_ipython_vars]) return None except Exception: traceback.print_exc() return None def get_interpreter(): try: interpreterInterface = getattr(__builtin__, 'interpreter') except AttributeError: interpreterInterface = InterpreterInterface(None, None, threading.currentThread()) setattr(__builtin__, 'interpreter', interpreterInterface) sys.stderr.write(interpreterInterface.get_greeting_msg()) sys.stderr.flush() return interpreterInterface def get_completions(text, token, globals, locals): interpreterInterface = get_interpreter() interpreterInterface.interpreter.update(globals, locals) return interpreterInterface.getCompletions(text, token) #=============================================================================== # Debugger integration #=============================================================================== def exec_code(code, globals, locals, debugger): interpreterInterface = get_interpreter() interpreterInterface.interpreter.update(globals, locals) res = interpreterInterface.need_more(code) if res: return True interpreterInterface.add_exec(code, debugger) return False class ConsoleWriter(InteractiveInterpreter): skip = 0 def __init__(self, locals=None): InteractiveInterpreter.__init__(self, locals) def write(self, data): #if (data.find("global_vars") == -1 and data.find("pydevd") == -1): if self.skip > 0: self.skip -= 1 else: if data == "Traceback (most recent call last):\n": self.skip = 1 sys.stderr.write(data) def showsyntaxerror(self, filename=None): """Display the syntax error that just occurred.""" #Override for avoid using sys.excepthook PY-12600 type, value, tb = sys.exc_info() sys.last_type = type sys.last_value = value sys.last_traceback = tb if filename and type is SyntaxError: # Work hard to stuff the correct filename in the exception try: msg, (dummy_filename, lineno, offset, line) = value.args except ValueError: # Not the format we expect; leave it alone pass else: # Stuff in the right filename value = SyntaxError(msg, (filename, lineno, offset, line)) sys.last_value = value list = traceback.format_exception_only(type, value) sys.stderr.write(''.join(list)) def showtraceback(self): """Display the exception that just occurred.""" #Override for avoid using sys.excepthook PY-12600 try: type, value, tb = sys.exc_info() sys.last_type = type sys.last_value = value sys.last_traceback = tb tblist = traceback.extract_tb(tb) del tblist[:1] lines = traceback.format_list(tblist) if lines: lines.insert(0, "Traceback (most recent call last):\n") lines.extend(traceback.format_exception_only(type, value)) finally: tblist = tb = None sys.stderr.write(''.join(lines)) def console_exec(thread_id, frame_id, expression, dbg): """returns 'False' in case expression is partially correct """ frame = pydevd_vars.find_frame(thread_id, frame_id) expression = str(expression.replace('@LINE@', '\n')) #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329 #(Names not resolved in generator expression in method) #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html updated_globals = {} updated_globals.update(frame.f_globals) updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals if IPYTHON: need_more = exec_code(CodeFragment(expression), updated_globals, frame.f_locals, dbg) if not need_more: pydevd_save_locals.save_locals(frame) return need_more interpreter = ConsoleWriter() try: code = compile_command(expression) except (OverflowError, SyntaxError, ValueError): # Case 1 interpreter.showsyntaxerror() return False if code is None: # Case 2 return True #Case 3 try: Exec(code, updated_globals, frame.f_locals) except SystemExit: raise except: interpreter.showtraceback() else: pydevd_save_locals.save_locals(frame) return False #======================================================================================================================= # main #======================================================================================================================= if __name__ == '__main__': #Important: don't use this module directly as the __main__ module, rather, import itself as pydevconsole #so that we don't get multiple pydevconsole modules if it's executed directly (otherwise we'd have multiple #representations of its classes). #See: https://sw-brainwy.rhcloud.com/tracker/PyDev/446: #'Variables' and 'Expressions' views stopped working when debugging interactive console import pydevconsole sys.stdin = pydevconsole.BaseStdIn(sys.stdin) port, client_port = sys.argv[1:3] from _pydev_bundle import pydev_localhost if int(port) == 0 and int(client_port) == 0: (h, p) = pydev_localhost.get_socket_name() client_port = p pydevconsole.start_server(pydev_localhost.get_localhost(), int(port), int(client_port))