1import os 2import sys 3import traceback 4from _pydev_bundle.pydev_imports import xmlrpclib, _queue, Exec 5from _pydev_bundle._pydev_calltip_util import get_description 6from _pydev_imps._pydev_saved_modules import thread 7from _pydevd_bundle import pydevd_vars 8from _pydevd_bundle import pydevd_xml 9from _pydevd_bundle.pydevd_constants import IS_JYTHON, dict_iter_items 10from _pydevd_bundle.pydevd_utils import to_string 11 12 13# ======================================================================================================================= 14# Null 15# ======================================================================================================================= 16class Null: 17 """ 18 Gotten from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68205 19 """ 20 21 def __init__(self, *args, **kwargs): 22 return None 23 24 def __call__(self, *args, **kwargs): 25 return self 26 27 def __getattr__(self, mname): 28 return self 29 30 def __setattr__(self, name, value): 31 return self 32 33 def __delattr__(self, name): 34 return self 35 36 def __repr__(self): 37 return "<Null>" 38 39 def __str__(self): 40 return "Null" 41 42 def __len__(self): 43 return 0 44 45 def __getitem__(self): 46 return self 47 48 def __setitem__(self, *args, **kwargs): 49 pass 50 51 def write(self, *args, **kwargs): 52 pass 53 54 def __nonzero__(self): 55 return 0 56 57 58# ======================================================================================================================= 59# BaseStdIn 60# ======================================================================================================================= 61class BaseStdIn: 62 def __init__(self, original_stdin=sys.stdin, *args, **kwargs): 63 try: 64 self.encoding = sys.stdin.encoding 65 except: 66 # Not sure if it's available in all Python versions... 67 pass 68 self.original_stdin = original_stdin 69 70 try: 71 self.errors = sys.stdin.errors # Who knew? sys streams have an errors attribute! 72 except: 73 #Not sure if it's available in all Python versions... 74 pass 75 76 def readline(self, *args, **kwargs): 77 # sys.stderr.write('Cannot readline out of the console evaluation\n') -- don't show anything 78 # This could happen if the user had done input('enter number).<-- upon entering this, that message would appear, 79 # which is not something we want. 80 return '\n' 81 82 def write(self, *args, **kwargs): 83 pass # not available StdIn (but it can be expected to be in the stream interface) 84 85 def flush(self, *args, **kwargs): 86 pass # not available StdIn (but it can be expected to be in the stream interface) 87 88 def read(self, *args, **kwargs): 89 # in the interactive interpreter, a read and a readline are the same. 90 return self.readline() 91 92 def close(self, *args, **kwargs): 93 pass # expected in StdIn 94 95 def __getattr__(self, item): 96 # it's called if the attribute wasn't found 97 if hasattr(self.original_stdin, item): 98 return getattr(self.original_stdin, item) 99 raise AttributeError("%s has no attribute %s" % (self.original_stdin, item)) 100 101 102# ======================================================================================================================= 103# StdIn 104# ======================================================================================================================= 105class StdIn(BaseStdIn): 106 ''' 107 Object to be added to stdin (to emulate it as non-blocking while the next line arrives) 108 ''' 109 110 def __init__(self, interpreter, host, client_port, original_stdin=sys.stdin): 111 BaseStdIn.__init__(self, original_stdin) 112 self.interpreter = interpreter 113 self.client_port = client_port 114 self.host = host 115 116 def readline(self, *args, **kwargs): 117 # Ok, callback into the client to get the new input 118 try: 119 server = xmlrpclib.Server('http://%s:%s' % (self.host, self.client_port)) 120 requested_input = server.RequestInput() 121 if not requested_input: 122 return '\n' #Yes, a readline must return something (otherwise we can get an EOFError on the input() call). 123 else: 124 # readline should end with '\n' (not doing so makes IPython 5 remove the last *valid* character). 125 requested_input += '\n' 126 return requested_input 127 except: 128 return '\n' 129 130 def close(self, *args, **kwargs): 131 pass # expected in StdIn 132 133#======================================================================================================================= 134# DebugConsoleStdIn 135#======================================================================================================================= 136class DebugConsoleStdIn(BaseStdIn): 137 ''' 138 Object to be added to stdin (to emulate it as non-blocking while the next line arrives) 139 ''' 140 141 def __init__(self, dbg, original_stdin): 142 BaseStdIn.__init__(self, original_stdin) 143 self.debugger = dbg 144 145 def __pydev_run_command(self, is_started): 146 try: 147 cmd = self.debugger.cmd_factory.make_input_requested_message(is_started) 148 self.debugger.writer.add_command(cmd) 149 except Exception: 150 import traceback 151 traceback.print_exc() 152 return '\n' 153 154 def readline(self, *args, **kwargs): 155 # Notify Java side about input and call original function 156 self.__pydev_run_command(True) 157 result = self.original_stdin.readline(*args, **kwargs) 158 self.__pydev_run_command(False) 159 return result 160 161 162class CodeFragment: 163 def __init__(self, text, is_single_line=True): 164 self.text = text 165 self.is_single_line = is_single_line 166 167 def append(self, code_fragment): 168 self.text = self.text + "\n" + code_fragment.text 169 if not code_fragment.is_single_line: 170 self.is_single_line = False 171 172 173# ======================================================================================================================= 174# BaseInterpreterInterface 175# ======================================================================================================================= 176class BaseInterpreterInterface: 177 def __init__(self, mainThread): 178 self.mainThread = mainThread 179 self.interruptable = False 180 self.exec_queue = _queue.Queue(0) 181 self.buffer = None 182 183 def need_more_for_code(self, source): 184 # PyDev-502: PyDev 3.9 F2 doesn't support backslash continuations 185 186 # Strangely even the IPython console is_complete said it was complete 187 # even with a continuation char at the end. 188 if source.endswith('\\'): 189 return True 190 191 if hasattr(self.interpreter, 'is_complete'): 192 return not self.interpreter.is_complete(source) 193 try: 194 # At this point, it should always be single. 195 # If we don't do this, things as: 196 # 197 # for i in range(10): print(i) 198 # 199 # (in a single line) don't work. 200 # Note that it won't give an error and code will be None (so, it'll 201 # use execMultipleLines in the next call in this case). 202 symbol = 'single' 203 code = self.interpreter.compile(source, '<input>', symbol) 204 except (OverflowError, SyntaxError, ValueError): 205 # Case 1 206 return False 207 if code is None: 208 # Case 2 209 return True 210 211 # Case 3 212 return False 213 214 def need_more(self, code_fragment): 215 if self.buffer is None: 216 self.buffer = code_fragment 217 else: 218 self.buffer.append(code_fragment) 219 220 return self.need_more_for_code(self.buffer.text) 221 222 def create_std_in(self, debugger=None, original_std_in=None): 223 if debugger is None: 224 return StdIn(self, self.host, self.client_port, original_stdin=original_std_in) 225 else: 226 return DebugConsoleStdIn(dbg=debugger, original_stdin=original_std_in) 227 228 def add_exec(self, code_fragment, debugger=None): 229 original_in = sys.stdin 230 try: 231 help = None 232 if 'pydoc' in sys.modules: 233 pydoc = sys.modules['pydoc'] # Don't import it if it still is not there. 234 235 if hasattr(pydoc, 'help'): 236 # You never know how will the API be changed, so, let's code defensively here 237 help = pydoc.help 238 if not hasattr(help, 'input'): 239 help = None 240 except: 241 # Just ignore any error here 242 pass 243 244 more = False 245 try: 246 sys.stdin = self.create_std_in(debugger, original_in) 247 try: 248 if help is not None: 249 # This will enable the help() function to work. 250 try: 251 try: 252 help.input = sys.stdin 253 except AttributeError: 254 help._input = sys.stdin 255 except: 256 help = None 257 if not self._input_error_printed: 258 self._input_error_printed = True 259 sys.stderr.write('\nError when trying to update pydoc.help.input\n') 260 sys.stderr.write('(help() may not work -- please report this as a bug in the pydev bugtracker).\n\n') 261 traceback.print_exc() 262 263 try: 264 self.start_exec() 265 if hasattr(self, 'debugger'): 266 import pydevd_tracing 267 pydevd_tracing.SetTrace(self.debugger.trace_dispatch) 268 269 more = self.do_add_exec(code_fragment) 270 271 if hasattr(self, 'debugger'): 272 import pydevd_tracing 273 pydevd_tracing.SetTrace(None) 274 275 self.finish_exec(more) 276 finally: 277 if help is not None: 278 try: 279 try: 280 help.input = original_in 281 except AttributeError: 282 help._input = original_in 283 except: 284 pass 285 286 finally: 287 sys.stdin = original_in 288 except SystemExit: 289 raise 290 except: 291 traceback.print_exc() 292 293 return more 294 295 def do_add_exec(self, codeFragment): 296 ''' 297 Subclasses should override. 298 299 @return: more (True if more input is needed to complete the statement and False if the statement is complete). 300 ''' 301 raise NotImplementedError() 302 303 def get_namespace(self): 304 ''' 305 Subclasses should override. 306 307 @return: dict with namespace. 308 ''' 309 raise NotImplementedError() 310 311 def __resolve_reference__(self, text): 312 """ 313 314 :type text: str 315 """ 316 obj = None 317 if '.' not in text: 318 try: 319 obj = self.get_namespace()[text] 320 except KeyError: 321 pass 322 323 if obj is None: 324 try: 325 obj = self.get_namespace()['__builtins__'][text] 326 except: 327 pass 328 329 if obj is None: 330 try: 331 obj = getattr(self.get_namespace()['__builtins__'], text, None) 332 except: 333 pass 334 335 else: 336 try: 337 last_dot = text.rindex('.') 338 parent_context = text[0:last_dot] 339 res = pydevd_vars.eval_in_context(parent_context, self.get_namespace(), self.get_namespace()) 340 obj = getattr(res, text[last_dot + 1:]) 341 except: 342 pass 343 return obj 344 345 def getDescription(self, text): 346 try: 347 obj = self.__resolve_reference__(text) 348 if obj is None: 349 return '' 350 return get_description(obj) 351 except: 352 return '' 353 354 def do_exec_code(self, code, is_single_line): 355 try: 356 code_fragment = CodeFragment(code, is_single_line) 357 more = self.need_more(code_fragment) 358 if not more: 359 code_fragment = self.buffer 360 self.buffer = None 361 self.exec_queue.put(code_fragment) 362 363 return more 364 except: 365 traceback.print_exc() 366 return False 367 368 def execLine(self, line): 369 return self.do_exec_code(line, True) 370 371 def execMultipleLines(self, lines): 372 if IS_JYTHON: 373 more = False 374 for line in lines.split('\n'): 375 more = self.do_exec_code(line, True) 376 return more 377 else: 378 return self.do_exec_code(lines, False) 379 380 def interrupt(self): 381 self.buffer = None # Also clear the buffer when it's interrupted. 382 try: 383 if self.interruptable: 384 called = False 385 try: 386 # Fix for #PyDev-500: Console interrupt can't interrupt on sleep 387 import os 388 import signal 389 if os.name == 'posix': 390 # On Linux we can't interrupt 0 as in Windows because it's 391 # actually owned by a process -- on the good side, signals 392 # work much better on Linux! 393 os.kill(os.getpid(), signal.SIGINT) 394 called = True 395 396 elif os.name == 'nt': 397 # Stupid windows: sending a Ctrl+C to a process given its pid 398 # is absurdly difficult. 399 # There are utilities to make it work such as 400 # http://www.latenighthacking.com/projects/2003/sendSignal/ 401 # but fortunately for us, it seems Python does allow a CTRL_C_EVENT 402 # for the current process in Windows if pid 0 is passed... if we needed 403 # to send a signal to another process the approach would be 404 # much more difficult. 405 # Still, note that CTRL_C_EVENT is only Python 2.7 onwards... 406 # Also, this doesn't seem to be documented anywhere!? (stumbled 407 # upon it by chance after digging quite a lot). 408 os.kill(0, signal.CTRL_C_EVENT) 409 called = True 410 except: 411 # Many things to go wrong (from CTRL_C_EVENT not being there 412 # to failing import signal)... if that's the case, ask for 413 # forgiveness and go on to the approach which will interrupt 414 # the main thread (but it'll only work when it's executing some Python 415 # code -- not on sleep() for instance). 416 pass 417 418 if not called: 419 if hasattr(thread, 'interrupt_main'): # Jython doesn't have it 420 thread.interrupt_main() 421 else: 422 self.mainThread._thread.interrupt() # Jython 423 self.finish_exec(False) 424 return True 425 except: 426 traceback.print_exc() 427 return False 428 429 def close(self): 430 sys.exit(0) 431 432 def start_exec(self): 433 self.interruptable = True 434 435 def get_server(self): 436 if getattr(self, 'host', None) is not None: 437 return xmlrpclib.Server('http://%s:%s' % (self.host, self.client_port)) 438 else: 439 return None 440 441 server = property(get_server) 442 443 def ShowConsole(self): 444 server = self.get_server() 445 if server is not None: 446 server.ShowConsole() 447 448 def finish_exec(self, more): 449 self.interruptable = False 450 451 server = self.get_server() 452 453 if server is not None: 454 return server.NotifyFinished(more) 455 else: 456 return True 457 458 def getFrame(self): 459 hidden_ns = self.get_ipython_hidden_vars_dict() 460 xml = "<xml>" 461 xml += pydevd_xml.frame_vars_to_xml(self.get_namespace(), hidden_ns) 462 xml += "</xml>" 463 464 return xml 465 466 def getVariable(self, attributes): 467 xml = "<xml>" 468 valDict = pydevd_vars.resolve_var(self.get_namespace(), attributes) 469 if valDict is None: 470 valDict = {} 471 472 keys = valDict.keys() 473 474 for k in keys: 475 xml += pydevd_vars.var_to_xml(valDict[k], to_string(k)) 476 477 xml += "</xml>" 478 479 return xml 480 481 def getArray(self, attr, roffset, coffset, rows, cols, format): 482 name = attr.split("\t")[-1] 483 array = pydevd_vars.eval_in_context(name, self.get_namespace(), self.get_namespace()) 484 return pydevd_vars.table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format) 485 486 def evaluate(self, expression): 487 xml = "<xml>" 488 result = pydevd_vars.eval_in_context(expression, self.get_namespace(), self.get_namespace()) 489 490 xml += pydevd_vars.var_to_xml(result, expression) 491 492 xml += "</xml>" 493 494 return xml 495 496 def changeVariable(self, attr, value): 497 def do_change_variable(): 498 Exec('%s=%s' % (attr, value), self.get_namespace(), self.get_namespace()) 499 500 # Important: it has to be really enabled in the main thread, so, schedule 501 # it to run in the main thread. 502 self.exec_queue.put(do_change_variable) 503 504 def _findFrame(self, thread_id, frame_id): 505 ''' 506 Used to show console with variables connection. 507 Always return a frame where the locals map to our internal namespace. 508 ''' 509 VIRTUAL_FRAME_ID = "1" # matches PyStackFrameConsole.java 510 VIRTUAL_CONSOLE_ID = "console_main" # matches PyThreadConsole.java 511 if thread_id == VIRTUAL_CONSOLE_ID and frame_id == VIRTUAL_FRAME_ID: 512 f = FakeFrame() 513 f.f_globals = {} # As globals=locals here, let's simply let it empty (and save a bit of network traffic). 514 f.f_locals = self.get_namespace() 515 return f 516 else: 517 return self.orig_find_frame(thread_id, frame_id) 518 519 def connectToDebugger(self, debuggerPort, debugger_options=None): 520 ''' 521 Used to show console with variables connection. 522 Mainly, monkey-patches things in the debugger structure so that the debugger protocol works. 523 ''' 524 525 if debugger_options is None: 526 debugger_options = {} 527 env_key = "PYDEVD_EXTRA_ENVS" 528 if env_key in debugger_options: 529 for (env_name, value) in dict_iter_items(debugger_options[env_key]): 530 os.environ[env_name] = value 531 del debugger_options[env_key] 532 def do_connect_to_debugger(): 533 try: 534 # Try to import the packages needed to attach the debugger 535 import pydevd 536 from _pydev_imps._pydev_saved_modules import threading 537 538 except: 539 # This happens on Jython embedded in host eclipse 540 traceback.print_exc() 541 sys.stderr.write('pydevd is not available, cannot connect\n', ) 542 543 from _pydev_bundle import pydev_localhost 544 threading.currentThread().__pydevd_id__ = "console_main" 545 546 self.orig_find_frame = pydevd_vars.find_frame 547 pydevd_vars.find_frame = self._findFrame 548 549 self.debugger = pydevd.PyDB() 550 try: 551 pydevd.apply_debugger_options(debugger_options) 552 self.debugger.connect(pydev_localhost.get_localhost(), debuggerPort) 553 self.debugger.prepare_to_run() 554 import pydevd_tracing 555 pydevd_tracing.SetTrace(None) 556 except: 557 traceback.print_exc() 558 sys.stderr.write('Failed to connect to target debugger.\n') 559 560 # Register to process commands when idle 561 self.debugrunning = False 562 try: 563 import pydevconsole 564 pydevconsole.set_debug_hook(self.debugger.process_internal_commands) 565 except: 566 traceback.print_exc() 567 sys.stderr.write('Version of Python does not support debuggable Interactive Console.\n') 568 569 # Important: it has to be really enabled in the main thread, so, schedule 570 # it to run in the main thread. 571 self.exec_queue.put(do_connect_to_debugger) 572 573 return ('connect complete',) 574 575 def hello(self, input_str): 576 # Don't care what the input string is 577 return ("Hello eclipse",) 578 579 def enableGui(self, guiname): 580 ''' Enable the GUI specified in guiname (see inputhook for list). 581 As with IPython, enabling multiple GUIs isn't an error, but 582 only the last one's main loop runs and it may not work 583 ''' 584 def do_enable_gui(): 585 from _pydev_bundle.pydev_versioncheck import versionok_for_gui 586 if versionok_for_gui(): 587 try: 588 from pydev_ipython.inputhook import enable_gui 589 enable_gui(guiname) 590 except: 591 sys.stderr.write("Failed to enable GUI event loop integration for '%s'\n" % guiname) 592 traceback.print_exc() 593 elif guiname not in ['none', '', None]: 594 # Only print a warning if the guiname was going to do something 595 sys.stderr.write("PyDev console: Python version does not support GUI event loop integration for '%s'\n" % guiname) 596 # Return value does not matter, so return back what was sent 597 return guiname 598 599 # Important: it has to be really enabled in the main thread, so, schedule 600 # it to run in the main thread. 601 self.exec_queue.put(do_enable_gui) 602 603 def get_ipython_hidden_vars_dict(self): 604 return None 605 606 607# ======================================================================================================================= 608# FakeFrame 609# ======================================================================================================================= 610class FakeFrame: 611 ''' 612 Used to show console with variables connection. 613 A class to be used as a mock of a frame. 614 ''' 615