DebugClients/Python3/DebugClientBase.py

branch
jsonrpc
changeset 5129
e4ab234cf071
parent 5128
b6cbdba69967
child 5131
889ed5ff7a68
equal deleted inserted replaced
5128:b6cbdba69967 5129:e4ab234cf071
18 import re 18 import re
19 import atexit 19 import atexit
20 import signal 20 import signal
21 21
22 22
23 ##import DebugProtocol
24 import DebugClientCapabilities 23 import DebugClientCapabilities
25 from DebugBase import setRecursionLimit, printerr # __IGNORE_WARNING__ 24 from DebugBase import setRecursionLimit, printerr # __IGNORE_WARNING__
26 from AsyncFile import AsyncFile, AsyncPendingWrite 25 from AsyncFile import AsyncFile, AsyncPendingWrite
27 from DebugConfig import ConfigVarTypeStrings 26 from DebugConfig import ConfigVarTypeStrings
28 from FlexCompleter import Completer 27 from FlexCompleter import Completer
29 from DebugUtilities import getargvalues, formatargvalues 28 from DebugUtilities import getargvalues, formatargvalues, prepareJsonCommand
30 29
31 30
32 DebugClientInstance = None 31 DebugClientInstance = None
33 32
34 ############################################################################### 33 ###############################################################################
187 186
188 # The list of regexp objects to filter variables against 187 # The list of regexp objects to filter variables against
189 self.globalsFilterObjects = [] 188 self.globalsFilterObjects = []
190 self.localsFilterObjects = [] 189 self.localsFilterObjects = []
191 190
192 ## self.pendingResponse = DebugProtocol.ResponseOK
193 self._fncache = {} 191 self._fncache = {}
194 self.dircache = [] 192 self.dircache = []
195 ## self.inRawMode = False
196 self.mainProcStr = None # used for the passive mode 193 self.mainProcStr = None # used for the passive mode
197 self.passive = False # used to indicate the passive mode 194 self.passive = False # used to indicate the passive mode
198 self.running = None 195 self.running = None
199 self.test = None 196 self.test = None
200 self.tracePython = False 197 self.tracePython = False
301 d["broken"] = self.isBroken() 298 d["broken"] = self.isBroken()
302 else: 299 else:
303 d["broken"] = False 300 d["broken"] = False
304 threadList.append(d) 301 threadList.append(d)
305 302
306 ## self.write("{0}{1!r}\n".format(DebugProtocol.ResponseThreadList,
307 ## (currentId, threadList)))
308 self.sendJsonCommand("ResponseThreadList", { 303 self.sendJsonCommand("ResponseThreadList", {
309 "currentID": currentId, 304 "currentID": currentId,
310 "threadList": threadList, 305 "threadList": threadList,
311 }) 306 })
312 307
316 311
317 @param prompt the prompt to be shown (string) 312 @param prompt the prompt to be shown (string)
318 @param echo Flag indicating echoing of the input (boolean) 313 @param echo Flag indicating echoing of the input (boolean)
319 @return the entered string 314 @return the entered string
320 """ 315 """
321 ## self.write("{0}{1!r}\n".format(
322 ## DebugProtocol.ResponseRaw, (prompt, echo)))
323 self.sendJsonCommand("RequestRaw", { 316 self.sendJsonCommand("RequestRaw", {
324 "prompt": prompt, 317 "prompt": prompt,
325 "echo": echo, 318 "echo": echo,
326 }) 319 })
327 ## self.inRawMode = True
328 self.eventLoop(True) 320 self.eventLoop(True)
329 return self.rawLine 321 return self.rawLine
330 322
331 ## def __exceptionRaised(self):
332 ## """
333 ## Private method called in the case of an exception.
334 ##
335 ## It ensures that the debug server is informed of the raised exception.
336 ## """
337 #### self.pendingResponse = DebugProtocol.ResponseException
338 ## self.sendJsonCommand("ResponseException", {})
339 ##
340 def sessionClose(self, exit=True): 323 def sessionClose(self, exit=True):
341 """ 324 """
342 Public method to close the session with the debugger and optionally 325 Public method to close the session with the debugger and optionally
343 terminate. 326 terminate.
344 327
347 try: 330 try:
348 self.set_quit() 331 self.set_quit()
349 except Exception: 332 except Exception:
350 pass 333 pass
351 334
352 ## # clean up asyncio.
353 ## self.disconnect()
354 self.debugging = False 335 self.debugging = False
355 336
356 # make sure we close down our end of the socket 337 # make sure we close down our end of the socket
357 # might be overkill as normally stdin, stdout and stderr 338 # might be overkill as normally stdin, stdout and stderr
358 # SHOULD be closed on exit, but it does not hurt to do it here 339 # SHOULD be closed on exit, but it does not hurt to do it here
407 if line[-1] == '\n': 388 if line[-1] == '\n':
408 line = line[:-1] 389 line = line[:-1]
409 390
410 ## printerr(line) ##debug 391 ## printerr(line) ##debug
411 392
412 if line.startswith("{") and "jsonrpc" in line: 393 self.handleJsonCommand(line)
413 return self.handleJsonCommand(line)
414 ##
415 ## eoc = line.find('<')
416 ##
417 ## if eoc >= 0 and line[0] == '>':
418 ## # Get the command part and any argument.
419 ## cmd = line[:eoc + 1]
420 ## arg = line[eoc + 1:]
421 ##
422 ## if cmd == DebugProtocol.RequestVariables:
423 ## frmnr, scope, filter = eval(arg.replace("u'", "'"))
424 ## self.__dumpVariables(int(frmnr), int(scope), filter)
425 ## return
426 ##
427 ## if cmd == DebugProtocol.RequestVariable:
428 ## var, frmnr, scope, filter = eval(arg.replace("u'", "'"))
429 ## self.__dumpVariable(var, int(frmnr), int(scope), filter)
430 ## return
431 ##
432 ## if cmd == DebugProtocol.RequestThreadList:
433 ## self.__dumpThreadList()
434 ## return
435 ##
436 ## if cmd == DebugProtocol.RequestThreadSet:
437 ## tid = eval(arg)
438 ## if tid in self.threads:
439 ## self.setCurrentThread(tid)
440 ## self.write(DebugProtocol.ResponseThreadSet + '\n')
441 ## stack = self.currentThread.getStack()
442 ## self.write('{0}{1!r}\n'.format(
443 ## DebugProtocol.ResponseStack, stack))
444 ## return
445 ##
446 ## if cmd == DebugProtocol.RequestStep:
447 ## self.currentThread.step(True)
448 ## self.eventExit = True
449 ## return
450 ##
451 ## if cmd == DebugProtocol.RequestStepOver:
452 ## self.currentThread.step(False)
453 ## self.eventExit = True
454 ## return
455 ##
456 ## if cmd == DebugProtocol.RequestStepOut:
457 ## self.currentThread.stepOut()
458 ## self.eventExit = True
459 ## return
460 ##
461 ## if cmd == DebugProtocol.RequestStepQuit:
462 ## if self.passive:
463 ## self.progTerminated(42)
464 ## else:
465 ## self.set_quit()
466 ## self.eventExit = True
467 ## return
468 ##
469 ## if cmd == DebugProtocol.RequestContinue:
470 ## special = int(arg)
471 ## self.currentThread.go(special)
472 ## self.eventExit = True
473 ## return
474 ##
475 ## if cmd == DebugProtocol.RequestOK:
476 ## self.write(self.pendingResponse + '\n')
477 ## self.pendingResponse = DebugProtocol.ResponseOK
478 ## return
479 ##
480 ## if cmd == DebugProtocol.RequestCallTrace:
481 ## if arg.strip().lower() == "on":
482 ## callTraceEnabled = True
483 ## else:
484 ## callTraceEnabled = False
485 ## if self.debugging:
486 ## self.callTraceEnabled = callTraceEnabled
487 ## else:
488 ## self.__newCallTraceEnabled = callTraceEnabled
489 ## # remember for later
490 ## return
491 ##
492 ## if cmd == DebugProtocol.RequestEnv:
493 ## env = eval(arg.replace("u'", "'"))
494 ## for key, value in env.items():
495 ## if key.endswith("+"):
496 ## if key[:-1] in os.environ:
497 ## os.environ[key[:-1]] += value
498 ## else:
499 ## os.environ[key[:-1]] = value
500 ## else:
501 ## os.environ[key] = value
502 ## return
503 ##
504 ## if cmd == DebugProtocol.RequestLoad:
505 ## self._fncache = {}
506 ## self.dircache = []
507 ## sys.argv = []
508 ## wd, fn, args, tracePython = arg.split('|')
509 ## self.__setCoding(fn)
510 ## sys.argv.append(fn)
511 ## sys.argv.extend(eval(args))
512 ## sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
513 ## if wd == '':
514 ## os.chdir(sys.path[1])
515 ## else:
516 ## os.chdir(wd)
517 ## tracePython = int(tracePython)
518 ## self.running = sys.argv[0]
519 ## self.mainFrame = None
520 ## self.inRawMode = False
521 ## self.debugging = True
522 ##
523 ## self.threads.clear()
524 ## self.attachThread(mainThread=True)
525 ##
526 ## # set the system exception handling function to ensure, that
527 ## # we report on all unhandled exceptions
528 ## sys.excepthook = self.__unhandled_exception
529 ## self.__interceptSignals()
530 ##
531 ## # clear all old breakpoints, they'll get set after we have
532 ## # started
533 ## self.mainThread.clear_all_breaks()
534 ##
535 ## self.mainThread.tracePython = tracePython
536 ##
537 ## # This will eventually enter a local event loop.
538 ## self.debugMod.__dict__['__file__'] = self.running
539 ## sys.modules['__main__'] = self.debugMod
540 ## code = self.__compileFileSource(self.running)
541 ## if code:
542 ## self.callTraceEnabled = self.__newCallTraceEnabled
543 ## res = self.mainThread.run(code, self.debugMod.__dict__)
544 ## self.progTerminated(res)
545 ## return
546 ##
547 ## if cmd == DebugProtocol.RequestRun:
548 ## sys.argv = []
549 ## wd, fn, args = arg.split('|')
550 ## self.__setCoding(fn)
551 ## sys.argv.append(fn)
552 ## sys.argv.extend(eval(args))
553 ## sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
554 ## if wd == '':
555 ## os.chdir(sys.path[1])
556 ## else:
557 ## os.chdir(wd)
558 ##
559 ## self.running = sys.argv[0]
560 ## self.mainFrame = None
561 ## self.botframe = None
562 ## self.inRawMode = False
563 ##
564 ## self.threads.clear()
565 ## self.attachThread(mainThread=True)
566 ##
567 ## # set the system exception handling function to ensure, that
568 ## # we report on all unhandled exceptions
569 ## sys.excepthook = self.__unhandled_exception
570 ## self.__interceptSignals()
571 ##
572 ## self.mainThread.tracePython = False
573 ##
574 ## self.debugMod.__dict__['__file__'] = sys.argv[0]
575 ## sys.modules['__main__'] = self.debugMod
576 ## res = 0
577 ## code = self.__compileFileSource(self.running)
578 ## if code:
579 ## try:
580 ## exec(code, self.debugMod.__dict__)
581 ## except SystemExit as exc:
582 ## res = exc.code
583 ## atexit._run_exitfuncs()
584 ## self.writestream.flush()
585 ## self.progTerminated(res)
586 ## return
587 ##
588 ## if cmd == DebugProtocol.RequestProfile:
589 ## sys.setprofile(None)
590 ## import PyProfile
591 ## sys.argv = []
592 ## wd, fn, args, erase = arg.split('|')
593 ## self.__setCoding(fn)
594 ## sys.argv.append(fn)
595 ## sys.argv.extend(eval(args))
596 ## sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
597 ## if wd == '':
598 ## os.chdir(sys.path[1])
599 ## else:
600 ## os.chdir(wd)
601 ##
602 ## # set the system exception handling function to ensure, that
603 ## # we report on all unhandled exceptions
604 ## sys.excepthook = self.__unhandled_exception
605 ## self.__interceptSignals()
606 ##
607 ## # generate a profile object
608 ## self.prof = PyProfile.PyProfile(sys.argv[0])
609 ##
610 ## if int(erase):
611 ## self.prof.erase()
612 ## self.debugMod.__dict__['__file__'] = sys.argv[0]
613 ## sys.modules['__main__'] = self.debugMod
614 ## fp = open(sys.argv[0], encoding=self.__coding)
615 ## try:
616 ## script = fp.read()
617 ## finally:
618 ## fp.close()
619 ## if script:
620 ## if not script.endswith('\n'):
621 ## script += '\n'
622 ## self.running = sys.argv[0]
623 ## res = 0
624 ## try:
625 ## self.prof.run(script)
626 ## except SystemExit as exc:
627 ## res = exc.code
628 ## atexit._run_exitfuncs()
629 ## self.prof.save()
630 ## self.writestream.flush()
631 ## self.progTerminated(res)
632 ## return
633 ##
634 ## if cmd == DebugProtocol.RequestCoverage:
635 ## from coverage import coverage
636 ## sys.argv = []
637 ## wd, fn, args, erase = arg.split('@@')
638 ## self.__setCoding(fn)
639 ## sys.argv.append(fn)
640 ## sys.argv.extend(eval(args))
641 ## sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
642 ## if wd == '':
643 ## os.chdir(sys.path[1])
644 ## else:
645 ## os.chdir(wd)
646 ##
647 ## # set the system exception handling function to ensure, that
648 ## # we report on all unhandled exceptions
649 ## sys.excepthook = self.__unhandled_exception
650 ## self.__interceptSignals()
651 ##
652 ## # generate a coverage object
653 ## self.cover = coverage(
654 ## auto_data=True,
655 ## data_file="{0}.coverage".format(
656 ## os.path.splitext(sys.argv[0])[0]))
657 ##
658 ## if int(erase):
659 ## self.cover.erase()
660 ## sys.modules['__main__'] = self.debugMod
661 ## self.debugMod.__dict__['__file__'] = sys.argv[0]
662 ## fp = open(sys.argv[0], encoding=self.__coding)
663 ## try:
664 ## script = fp.read()
665 ## finally:
666 ## fp.close()
667 ## if script:
668 ## if not script.endswith('\n'):
669 ## script += '\n'
670 ## code = compile(script, sys.argv[0], 'exec')
671 ## self.running = sys.argv[0]
672 ## res = 0
673 ## self.cover.start()
674 ## try:
675 ## exec(code, self.debugMod.__dict__)
676 ## except SystemExit as exc:
677 ## res = exc.code
678 ## atexit._run_exitfuncs()
679 ## self.cover.stop()
680 ## self.cover.save()
681 ## self.writestream.flush()
682 ## self.progTerminated(res)
683 ## return
684 ##
685 ## if cmd == DebugProtocol.RequestShutdown:
686 ## self.sessionClose()
687 ## return
688 ##
689 ## if cmd == DebugProtocol.RequestBreak:
690 ## fn, line, temporary, set, cond = arg.split('@@')
691 ## line = int(line)
692 ## set = int(set)
693 ## temporary = int(temporary)
694 ##
695 ## if set:
696 ## if cond == 'None' or cond == '':
697 ## cond = None
698 ## else:
699 ## try:
700 ## compile(cond, '<string>', 'eval')
701 ## except SyntaxError:
702 ## self.write('{0}{1},{2:d}\n'.format(
703 ## DebugProtocol.ResponseBPConditionError,
704 ## fn, line))
705 ## return
706 ## self.mainThread.set_break(fn, line, temporary, cond)
707 ## else:
708 ## self.mainThread.clear_break(fn, line)
709 ##
710 ## return
711 ##
712 ## if cmd == DebugProtocol.RequestBreakEnable:
713 ## fn, line, enable = arg.split(',')
714 ## line = int(line)
715 ## enable = int(enable)
716 ##
717 ## bp = self.mainThread.get_break(fn, line)
718 ## if bp is not None:
719 ## if enable:
720 ## bp.enable()
721 ## else:
722 ## bp.disable()
723 ##
724 ## return
725 ##
726 ## if cmd == DebugProtocol.RequestBreakIgnore:
727 ## fn, line, count = arg.split(',')
728 ## line = int(line)
729 ## count = int(count)
730 ##
731 ## bp = self.mainThread.get_break(fn, line)
732 ## if bp is not None:
733 ## bp.ignore = count
734 ##
735 ## return
736 ##
737 ## if cmd == DebugProtocol.RequestWatch:
738 ## cond, temporary, set = arg.split('@@')
739 ## set = int(set)
740 ## temporary = int(temporary)
741 ##
742 ## if set:
743 ## if not cond.endswith('??created??') and \
744 ## not cond.endswith('??changed??'):
745 ## try:
746 ## compile(cond, '<string>', 'eval')
747 ## except SyntaxError:
748 ## self.write('{0}{1}\n'.format(
749 ## DebugProtocol.ResponseWPConditionError, cond))
750 ## return
751 ## self.mainThread.set_watch(cond, temporary)
752 ## else:
753 ## self.mainThread.clear_watch(cond)
754 ##
755 ## return
756 ##
757 ## if cmd == DebugProtocol.RequestWatchEnable:
758 ## cond, enable = arg.split(',')
759 ## enable = int(enable)
760 ##
761 ## bp = self.mainThread.get_watch(cond)
762 ## if bp is not None:
763 ## if enable:
764 ## bp.enable()
765 ## else:
766 ## bp.disable()
767 ##
768 ## return
769 ##
770 ## if cmd == DebugProtocol.RequestWatchIgnore:
771 ## cond, count = arg.split(',')
772 ## count = int(count)
773 ##
774 ## bp = self.mainThread.get_watch(cond)
775 ## if bp is not None:
776 ## bp.ignore = count
777 ##
778 ## return
779 ##
780 ## if cmd == DebugProtocol.RequestEval:
781 ## try:
782 ## value = eval(
783 ## arg,
784 ## self.currentThread.getCurrentFrame().f_globals,
785 ## self.currentThread.getFrameLocals(self.framenr))
786 ## self.currentThread.storeFrameLocals(self.framenr)
787 ## except Exception:
788 ## # Report the exception and the traceback
789 ## try:
790 ## type, value, tb = sys.exc_info()
791 ## sys.last_type = type
792 ## sys.last_value = value
793 ## sys.last_traceback = tb
794 ## tblist = traceback.extract_tb(tb)
795 ## del tblist[:1]
796 ## list = traceback.format_list(tblist)
797 ## if list:
798 ## list.insert(0, "Traceback (innermost last):\n")
799 ## list[len(list):] = \
800 ## traceback.format_exception_only(type, value)
801 ## finally:
802 ## tblist = tb = None
803 ##
804 ## for l in list:
805 ## self.write(l)
806 ##
807 ## self.write(DebugProtocol.ResponseException + '\n')
808 ##
809 ## else:
810 ## self.write(str(value) + '\n')
811 ## self.write(DebugProtocol.ResponseOK + '\n')
812 ##
813 ## return
814 ##
815 ## if cmd == DebugProtocol.RequestExec:
816 ## _globals = self.currentThread.getCurrentFrame().f_globals
817 ## _locals = self.currentThread.getFrameLocals(self.framenr)
818 ## try:
819 ## code = compile(arg + '\n', '<stdin>', 'single')
820 ## exec(code, _globals, _locals)
821 ## self.currentThread.storeFrameLocals(self.framenr)
822 ## except Exception:
823 ## # Report the exception and the traceback
824 ## try:
825 ## type, value, tb = sys.exc_info()
826 ## sys.last_type = type
827 ## sys.last_value = value
828 ## sys.last_traceback = tb
829 ## tblist = traceback.extract_tb(tb)
830 ## del tblist[:1]
831 ## list = traceback.format_list(tblist)
832 ## if list:
833 ## list.insert(0, "Traceback (innermost last):\n")
834 ## list[len(list):] = \
835 ## traceback.format_exception_only(type, value)
836 ## finally:
837 ## tblist = tb = None
838 ##
839 ## for l in list:
840 ## self.write(l)
841 ##
842 ## self.write(DebugProtocol.ResponseException + '\n')
843 ##
844 ## return
845 ##
846 ## if cmd == DebugProtocol.RequestBanner:
847 ## self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
848 ## str(("Python {0}".format(sys.version),
849 ## socket.gethostname(), self.variant))))
850 ## return
851 ##
852 ## if cmd == DebugProtocol.RequestCapabilities:
853 ## self.write('{0}{1:d}, "Python3"\n'.format(
854 ## DebugProtocol.ResponseCapabilities,
855 ## self.__clientCapabilities()))
856 ## return
857 ##
858 ## if cmd == DebugProtocol.RequestCompletion:
859 ## self.__completionList(arg.replace("u'", "'"))
860 ## return
861 ##
862 ## if cmd == DebugProtocol.RequestSetFilter:
863 ## scope, filterString = eval(arg.replace("u'", "'"))
864 ## self.__generateFilterObjects(int(scope), filterString)
865 ## return
866 ##
867 ## if cmd == DebugProtocol.RequestUTPrepare:
868 ## fn, tn, tfn, failed, cov, covname, erase = arg.split('|')
869 ## sys.path.insert(0, os.path.dirname(os.path.abspath(fn)))
870 ## os.chdir(sys.path[0])
871 ## failed = eval(failed)
872 ##
873 ## # set the system exception handling function to ensure, that
874 ## # we report on all unhandled exceptions
875 ## sys.excepthook = self.__unhandled_exception
876 ## self.__interceptSignals()
877 ##
878 ## try:
879 ## import unittest
880 ## utModule = imp.load_source(tn, fn)
881 ## try:
882 ## if failed:
883 ## self.test = unittest.defaultTestLoader\
884 ## .loadTestsFromNames(failed, utModule)
885 ## else:
886 ## self.test = unittest.defaultTestLoader\
887 ## .loadTestsFromName(tfn, utModule)
888 ## except AttributeError:
889 ## self.test = unittest.defaultTestLoader\
890 ## .loadTestsFromModule(utModule)
891 ## except Exception:
892 ## exc_type, exc_value, exc_tb = sys.exc_info()
893 ## self.write('{0}{1}\n'.format(
894 ## DebugProtocol.ResponseUTPrepared,
895 ## str((0, str(exc_type), str(exc_value)))))
896 ## self.__exceptionRaised()
897 ## return
898 ##
899 ## # generate a coverage object
900 ## if int(cov):
901 ## from coverage import coverage
902 ## self.cover = coverage(
903 ## auto_data=True,
904 ## data_file="{0}.coverage".format(
905 ## os.path.splitext(covname)[0]))
906 ## if int(erase):
907 ## self.cover.erase()
908 ## else:
909 ## self.cover = None
910 ##
911 ## self.write('{0}{1}\n'.format(
912 ## DebugProtocol.ResponseUTPrepared,
913 ## str((self.test.countTestCases(), "", ""))))
914 ## return
915 ##
916 ## if cmd == DebugProtocol.RequestUTRun:
917 ## from DCTestResult import DCTestResult
918 ## self.testResult = DCTestResult(self)
919 ## if self.cover:
920 ## self.cover.start()
921 ## self.test.run(self.testResult)
922 ## if self.cover:
923 ## self.cover.stop()
924 ## self.cover.save()
925 ## self.write('{0}\n'.format(DebugProtocol.ResponseUTFinished))
926 ## return
927 ##
928 ## if cmd == DebugProtocol.RequestUTStop:
929 ## self.testResult.stop()
930 ## return
931 ##
932 ## if cmd == DebugProtocol.ResponseForkTo:
933 ## # this results from a separate event loop
934 ## self.fork_child = (arg == 'child')
935 ## self.eventExit = True
936 ## return
937 ##
938 ## if cmd == DebugProtocol.RequestForkMode:
939 ## self.fork_auto, self.fork_child = eval(arg)
940 ## return
941 ##
942 ## # If we are handling raw mode input then reset the mode and break out
943 ## # of the current event loop.
944 ## if self.inRawMode:
945 ## self.inRawMode = False
946 ## self.rawLine = line
947 ## self.eventExit = True
948 ## return
949 ##
950 ## if self.buffer:
951 ## self.buffer = self.buffer + '\n' + line
952 ## else:
953 ## self.buffer = line
954 ##
955 ## try:
956 ## code = self.compile_command(self.buffer, self.readstream.name)
957 ## except (OverflowError, SyntaxError, ValueError):
958 ## # Report the exception
959 ## sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
960 ## for l in traceback.format_exception_only(
961 ## sys.last_type, sys.last_value):
962 ## self.write(l)
963 ## self.buffer = ''
964 ## else:
965 ## if code is None:
966 ## self.pendingResponse = DebugProtocol.ResponseContinue
967 ## else:
968 ## self.buffer = ''
969 ##
970 ## try:
971 ## if self.running is None:
972 ## exec(code, self.debugMod.__dict__)
973 ## else:
974 ## if self.currentThread is None:
975 ## # program has terminated
976 ## self.running = None
977 ## _globals = self.debugMod.__dict__
978 ## _locals = _globals
979 ## else:
980 ## cf = self.currentThread.getCurrentFrame()
981 ## # program has terminated
982 ## if cf is None:
983 ## self.running = None
984 ## _globals = self.debugMod.__dict__
985 ## _locals = _globals
986 ## else:
987 ## frmnr = self.framenr
988 ## while cf is not None and frmnr > 0:
989 ## cf = cf.f_back
990 ## frmnr -= 1
991 ## _globals = cf.f_globals
992 ## _locals = \
993 ## self.currentThread.getFrameLocals(
994 ## self.framenr)
995 ## # reset sys.stdout to our redirector (unconditionally)
996 ## if "sys" in _globals:
997 ## __stdout = _globals["sys"].stdout
998 ## _globals["sys"].stdout = self.writestream
999 ## exec(code, _globals, _locals)
1000 ## _globals["sys"].stdout = __stdout
1001 ## elif "sys" in _locals:
1002 ## __stdout = _locals["sys"].stdout
1003 ## _locals["sys"].stdout = self.writestream
1004 ## exec(code, _globals, _locals)
1005 ## _locals["sys"].stdout = __stdout
1006 ## else:
1007 ## exec(code, _globals, _locals)
1008 ##
1009 ## self.currentThread.storeFrameLocals(self.framenr)
1010 ## except SystemExit as exc:
1011 ## self.progTerminated(exc.code)
1012 ## except Exception:
1013 ## # Report the exception and the traceback
1014 ## try:
1015 ## exc_type, exc_value, exc_tb = sys.exc_info()
1016 ## sys.last_type = exc_type
1017 ## sys.last_value = exc_value
1018 ## sys.last_traceback = exc_tb
1019 ## tblist = traceback.extract_tb(exc_tb)
1020 ## del tblist[:1]
1021 ## list = traceback.format_list(tblist)
1022 ## if list:
1023 ## list.insert(0, "Traceback (innermost last):\n")
1024 ## list[len(list):] = traceback.format_exception_only(
1025 ## exc_type, exc_value)
1026 ## finally:
1027 ## tblist = exc_tb = None
1028 ##
1029 ## for l in list:
1030 ## self.write(l)
1031 394
1032 def handleJsonCommand(self, jsonStr): 395 def handleJsonCommand(self, jsonStr):
1033 """ 396 """
1034 Public method to handle a command serialized as a JSON string. 397 Public method to handle a command serialized as a JSON string.
398
399 @param jsonStr string containing the command received from the IDE
400 @type str
1035 """ 401 """
1036 import json 402 import json
1037 403
1038 try: 404 try:
1039 commandDict = json.loads(jsonStr.strip()) 405 commandDict = json.loads(jsonStr.strip())
1111 else: 477 else:
1112 os.chdir(params["workdir"]) 478 os.chdir(params["workdir"])
1113 479
1114 self.running = sys.argv[0] 480 self.running = sys.argv[0]
1115 self.mainFrame = None 481 self.mainFrame = None
1116 ## self.inRawMode = False
1117 self.debugging = True 482 self.debugging = True
1118 483
1119 self.fork_auto = params["autofork"] 484 self.fork_auto = params["autofork"]
1120 self.fork_child = params["forkChild"] 485 self.fork_child = params["forkChild"]
1121 486
1154 os.chdir(params["workdir"]) 519 os.chdir(params["workdir"])
1155 520
1156 self.running = sys.argv[0] 521 self.running = sys.argv[0]
1157 self.mainFrame = None 522 self.mainFrame = None
1158 self.botframe = None 523 self.botframe = None
1159 ## self.inRawMode = False
1160 524
1161 self.fork_auto = params["autofork"] 525 self.fork_auto = params["autofork"]
1162 self.fork_child = params["forkChild"] 526 self.fork_child = params["forkChild"]
1163 527
1164 self.threads.clear() 528 self.threads.clear()
1287 code = self.compile_command(self.buffer, self.readstream.name) 651 code = self.compile_command(self.buffer, self.readstream.name)
1288 except (OverflowError, SyntaxError, ValueError): 652 except (OverflowError, SyntaxError, ValueError):
1289 # Report the exception 653 # Report the exception
1290 sys.last_type, sys.last_value, sys.last_traceback = \ 654 sys.last_type, sys.last_value, sys.last_traceback = \
1291 sys.exc_info() 655 sys.exc_info()
1292 ## for l in traceback.format_exception_only(
1293 ## sys.last_type, sys.last_value):
1294 ## self.write(l)
1295 self.sendJsonCommand("ClientOutput", { 656 self.sendJsonCommand("ClientOutput", {
1296 "text": "".join(traceback.format_exception_only( 657 "text": "".join(traceback.format_exception_only(
1297 sys.last_type, sys.last_value)) 658 sys.last_type, sys.last_value))
1298 }) 659 })
1299 self.buffer = '' 660 self.buffer = ''
1365 traceback.format_exception_only( 726 traceback.format_exception_only(
1366 exc_type, exc_value) 727 exc_type, exc_value)
1367 finally: 728 finally:
1368 tblist = exc_tb = None 729 tblist = exc_tb = None
1369 730
1370 ## for l in list:
1371 ## self.write(l)
1372 self.sendJsonCommand("ClientOutput", { 731 self.sendJsonCommand("ClientOutput", {
1373 "text": "".join(tlist) 732 "text": "".join(tlist)
1374 }) 733 })
1375 734
1376 self.sendJsonCommand("ResponseOK", {}) 735 self.sendJsonCommand("ResponseOK", {})
1498 self.sendJsonCommand("ResponseUTPrepared", { 857 self.sendJsonCommand("ResponseUTPrepared", {
1499 "count": 0, 858 "count": 0,
1500 "exception": exc_type.__name__, 859 "exception": exc_type.__name__,
1501 "message": str(exc_value), 860 "message": str(exc_value),
1502 }) 861 })
1503 ## self.__exceptionRaised()
1504 return 862 return
1505 863
1506 # generate a coverage object 864 # generate a coverage object
1507 if params["coverage"]: 865 if params["coverage"]:
1508 from coverage import coverage 866 from coverage import coverage
1538 elif method == "ResponseForkTo": 896 elif method == "ResponseForkTo":
1539 # this results from a separate event loop 897 # this results from a separate event loop
1540 self.fork_child = (params["target"] == 'child') 898 self.fork_child = (params["target"] == 'child')
1541 self.eventExit = True 899 self.eventExit = True
1542 900
1543 def sendJsonCommand(self, command, params): 901 def sendJsonCommand(self, method, params):
1544 """ 902 """
1545 Public method to send a single command to the client. 903 Public method to send a single command or response to the IDE.
1546 904
1547 @param command command name to be sent 905 @param method command or response command name to be sent
1548 @type str 906 @type str
1549 @param params dictionary of named parameters for the command 907 @param params dictionary of named parameters for the command or
908 response
1550 @type dict 909 @type dict
1551 """ 910 """
1552 import json 911 cmd = prepareJsonCommand(method, params)
1553
1554 commandDict = {
1555 "jsonrpc": "2.0",
1556 "method": command,
1557 "params": params,
1558 }
1559 cmd = json.dumps(commandDict) + '\n'
1560 912
1561 self.writestream.write_p(cmd) 913 self.writestream.write_p(cmd)
1562 self.writestream.flush() 914 self.writestream.flush()
1563 915
1564 def sendClearTemporaryBreakpoint(self, filename, lineno): 916 def sendClearTemporaryBreakpoint(self, filename, lineno):
1601 """ 953 """
1602 Public method to send a call trace entry. 954 Public method to send a call trace entry.
1603 955
1604 @param event trace event (call or return) 956 @param event trace event (call or return)
1605 @type str 957 @type str
1606 @param fromstr pre-formatted origin info 958 @param fromStr pre-formatted origin info
1607 @type str 959 @type str
1608 @param toStr pre-formatted target info 960 @param toStr pre-formatted target info
1609 @type str 961 @type str
1610 """ 962 """
1611 self.sendJsonCommand("CallTrace", { 963 self.sendJsonCommand("CallTrace", {
1621 @param exceptionType type of exception raised 973 @param exceptionType type of exception raised
1622 @type str 974 @type str
1623 @param exceptionMessage message of the exception 975 @param exceptionMessage message of the exception
1624 @type str 976 @type str
1625 @param stack stack trace information 977 @param stack stack trace information
1626 @param list 978 @type list
1627 """ 979 """
1628 self.sendJsonCommand("ResponseException", { 980 self.sendJsonCommand("ResponseException", {
1629 "type": exceptionType, 981 "type": exceptionType,
1630 "message": exceptionMessage, 982 "message": exceptionMessage,
1631 "stack": stack, 983 "stack": stack,
1680 return self.clientCapabilities 1032 return self.clientCapabilities
1681 except ImportError: 1033 except ImportError:
1682 return ( 1034 return (
1683 self.clientCapabilities & ~DebugClientCapabilities.HasProfiler) 1035 self.clientCapabilities & ~DebugClientCapabilities.HasProfiler)
1684 1036
1685 ## def write(self, s):
1686 ## """
1687 ## Public method to write data to the output stream.
1688 ##
1689 ## @param s data to be written (string)
1690 ## """
1691 ## self.writestream.write_p(s)
1692 ## self.writestream.flush()
1693 ##
1694 def readReady(self, stream): 1037 def readReady(self, stream):
1695 """ 1038 """
1696 Public method called when there is data ready to be read. 1039 Public method called when there is data ready to be read.
1697 1040
1698 @param fd file descriptor of the file that has data to be read (int) 1041 @param stream file like object that has data to be written
1699 """ 1042 """
1700 try: 1043 try:
1701 got = stream.readline_p() 1044 got = stream.readline_p()
1702 except Exception: 1045 except Exception:
1703 return 1046 return
1718 1061
1719 def writeReady(self, stream): 1062 def writeReady(self, stream):
1720 """ 1063 """
1721 Public method called when we are ready to write data. 1064 Public method called when we are ready to write data.
1722 1065
1723 @param fd file descriptor of the file that has data to be written (int) 1066 @param stream file like object that has data to be written
1724 """ 1067 """
1725 stream.write_p("") 1068 stream.write_p("")
1726 stream.flush() 1069 stream.flush()
1727 1070
1728 def __interact(self): 1071 def __interact(self):
1729 """ 1072 """
1730 Private method to interact with the debugger. 1073 Private method to interact with the debugger.
1731 """ 1074 """
1732 global DebugClientInstance 1075 global DebugClientInstance
1733 1076
1734 ## self.setDescriptors(self.readstream, self.writestream)
1735 DebugClientInstance = self 1077 DebugClientInstance = self
1736 self.__receiveBuffer = "" 1078 self.__receiveBuffer = ""
1737 1079
1738 if not self.passive: 1080 if not self.passive:
1739 # At this point simulate an event loop. 1081 # At this point simulate an event loop.
1909 except Exception: 1251 except Exception:
1910 fargs = "" 1252 fargs = ""
1911 else: 1253 else:
1912 fargs = "" 1254 fargs = ""
1913 1255
1914 ## siglist = [message, [filename, linenr, ffunc, fargs]]
1915 ##
1916 ## self.write("{0}{1}".format(DebugProtocol.ResponseSignal, str(siglist)))
1917 self.sendJsonCommand("ResponseSignal", { 1256 self.sendJsonCommand("ResponseSignal", {
1918 "message": message, 1257 "message": message,
1919 "filename": filename, 1258 "filename": filename,
1920 "linenumber": linenr, 1259 "linenumber": linenr,
1921 "function": ffunc, 1260 "function": ffunc,
1922 "arguments": fargs, 1261 "arguments": fargs,
1923 }) 1262 })
1924 1263
1925 def absPath(self, fn): 1264 def absPath(self, fn):
1926 """ 1265 """
2013 status = 1 1352 status = 1
2014 1353
2015 if self.running: 1354 if self.running:
2016 self.set_quit() 1355 self.set_quit()
2017 self.running = None 1356 self.running = None
2018 ## self.write('{0}{1:d}\n'.format(DebugProtocol.ResponseExit, status))
2019 self.sendJsonCommand("ResponseExit", { 1357 self.sendJsonCommand("ResponseExit", {
2020 "status": status, 1358 "status": status,
2021 "message": message, 1359 "message": message,
2022 }) 1360 })
2023 1361
2064 keylist = dict.keys() 1402 keylist = dict.keys()
2065 1403
2066 vlist = self.__formatVariablesList(keylist, dict, scope, filter) 1404 vlist = self.__formatVariablesList(keylist, dict, scope, filter)
2067 varlist.extend(vlist) 1405 varlist.extend(vlist)
2068 1406
2069 ## self.write('{0}{1}\n'.format(
2070 ## DebugProtocol.ResponseVariables, str(varlist)))
2071 self.sendJsonCommand("ResponseVariables", { 1407 self.sendJsonCommand("ResponseVariables", {
2072 "scope": scope, 1408 "scope": scope,
2073 "variables": varlist, 1409 "variables": varlist,
2074 }) 1410 })
2075 1411
2353 varlist.append( 1689 varlist.append(
2354 ('...', 'tuple', "{0:d}".format(len(obj)))) 1690 ('...', 'tuple', "{0:d}".format(len(obj))))
2355 except Exception: 1691 except Exception:
2356 pass 1692 pass
2357 1693
2358 ## self.write('{0}{1}\n'.format(
2359 ## DebugProtocol.ResponseVariable, str(varlist)))
2360 self.sendJsonCommand("ResponseVariable", { 1694 self.sendJsonCommand("ResponseVariable", {
2361 "scope": scope, 1695 "scope": scope,
2362 "variable": var, 1696 "variable": var,
2363 "variables": varlist, 1697 "variables": varlist,
2364 }) 1698 })
2655 self.__getCompletionList(text, localCompleter, completions) 1989 self.__getCompletionList(text, localCompleter, completions)
2656 except AttributeError: 1990 except AttributeError:
2657 pass 1991 pass
2658 self.__getCompletionList(text, self.complete, completions) 1992 self.__getCompletionList(text, self.complete, completions)
2659 1993
2660 ## self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion,
2661 ## str(list(completions)), text))
2662 self.sendJsonCommand("ResponseCompletion", { 1994 self.sendJsonCommand("ResponseCompletion", {
2663 "completions": list(completions), 1995 "completions": list(completions),
2664 "text": text, 1996 "text": text,
2665 }) 1997 })
2666 1998
2667 def __getCompletionList(self, text, completer, completions): 1999 def __getCompletionList(self, text, completer, completions):
2668 """ 2000 """
2669 Private method to create a completions list. 2001 Private method to create a completions list.
2725 2057
2726 # setup the debugger variables 2058 # setup the debugger variables
2727 self._fncache = {} 2059 self._fncache = {}
2728 self.dircache = [] 2060 self.dircache = []
2729 self.mainFrame = None 2061 self.mainFrame = None
2730 ## self.inRawMode = False
2731 self.debugging = True 2062 self.debugging = True
2732 2063
2733 self.attachThread(mainThread=True) 2064 self.attachThread(mainThread=True)
2734 self.mainThread.tracePython = tracePython 2065 self.mainThread.tracePython = tracePython
2735 2066
2778 else: 2109 else:
2779 os.chdir(wd) 2110 os.chdir(wd)
2780 self.running = sys.argv[0] 2111 self.running = sys.argv[0]
2781 self.__setCoding(self.running) 2112 self.__setCoding(self.running)
2782 self.mainFrame = None 2113 self.mainFrame = None
2783 ## self.inRawMode = False
2784 self.debugging = True 2114 self.debugging = True
2785 2115
2786 self.passive = True 2116 self.passive = True
2787 self.sendPassiveStartup(self.running, exceptions) 2117 self.sendPassiveStartup(self.running, exceptions)
2788 ## self.write("{0}{1}|{2:d}\n".format(
2789 ## DebugProtocol.PassiveStartup, self.running, exceptions))
2790 self.__interact() 2118 self.__interact()
2791 2119
2792 self.attachThread(mainThread=True) 2120 self.attachThread(mainThread=True)
2793 self.mainThread.tracePython = tracePython 2121 self.mainThread.tracePython = tracePython
2794 2122
2941 to follow. 2269 to follow.
2942 2270
2943 @return process ID (integer) 2271 @return process ID (integer)
2944 """ 2272 """
2945 if not self.fork_auto: 2273 if not self.fork_auto:
2946 ## self.write(DebugProtocol.RequestForkTo + '\n')
2947 self.sendJsonCommand("RequestForkTo", {}) 2274 self.sendJsonCommand("RequestForkTo", {})
2948 self.eventLoop(True) 2275 self.eventLoop(True)
2949 pid = DebugClientOrigFork() 2276 pid = DebugClientOrigFork()
2950 if pid == 0: 2277 if pid == 0:
2951 # child 2278 # child

eric ide

mercurial