Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1''' pydevd - a debugging daemon 

2This is the daemon you launch for python remote debugging. 

3 

4Protocol: 

5each command has a format: 

6 id\tsequence-num\ttext 

7 id: protocol command number 

8 sequence-num: each request has a sequence number. Sequence numbers 

9 originating at the debugger are odd, sequence numbers originating 

10 at the daemon are even. Every response uses the same sequence number 

11 as the request. 

12 payload: it is protocol dependent. When response is a complex structure, it 

13 is returned as XML. Each attribute value is urlencoded, and then the whole 

14 payload is urlencoded again to prevent stray characters corrupting protocol/xml encodings 

15 

16 Commands: 

17 

18 NUMBER NAME FROM* ARGUMENTS RESPONSE NOTE 

19100 series: program execution 

20 101 RUN JAVA - - 

21 102 LIST_THREADS JAVA RETURN with XML listing of all threads 

22 103 THREAD_CREATE PYDB - XML with thread information 

23 104 THREAD_KILL JAVA id (or * to exit) kills the thread 

24 PYDB id nofies JAVA that thread was killed 

25 105 THREAD_SUSPEND JAVA XML of the stack, suspends the thread 

26 reason for suspension 

27 PYDB id notifies JAVA that thread was suspended 

28 

29 106 CMD_THREAD_RUN JAVA id resume the thread 

30 PYDB id \t reason notifies JAVA that thread was resumed 

31 

32 107 STEP_INTO JAVA thread_id 

33 108 STEP_OVER JAVA thread_id 

34 109 STEP_RETURN JAVA thread_id 

35 

36 110 GET_VARIABLE JAVA thread_id \t frame_id \t GET_VARIABLE with XML of var content 

37 FRAME|GLOBAL \t attributes* 

38 

39 111 SET_BREAK JAVA file/line of the breakpoint 

40 112 REMOVE_BREAK JAVA file/line of the return 

41 113 CMD_EVALUATE_EXPRESSION JAVA expression result of evaluating the expression 

42 114 CMD_GET_FRAME JAVA request for frame contents 

43 115 CMD_EXEC_EXPRESSION JAVA 

44 116 CMD_WRITE_TO_CONSOLE PYDB 

45 117 CMD_CHANGE_VARIABLE 

46 118 CMD_RUN_TO_LINE 

47 119 CMD_RELOAD_CODE 

48 120 CMD_GET_COMPLETIONS JAVA 

49 

50 200 CMD_REDIRECT_OUTPUT JAVA streams to redirect as string - 

51 'STDOUT' (redirect only STDOUT) 

52 'STDERR' (redirect only STDERR) 

53 'STDOUT STDERR' (redirect both streams) 

54 

55500 series diagnostics/ok 

56 501 VERSION either Version string (1.0) Currently just used at startup 

57 502 RETURN either Depends on caller - 

58 

59900 series: errors 

60 901 ERROR either - This is reserved for unexpected errors. 

61 

62 * JAVA - remote debugger, the java end 

63 * PYDB - pydevd, the python end 

64''' 

65 

66import itertools 

67 

68from _pydev_bundle.pydev_imports import _queue 

69from _pydev_imps._pydev_saved_modules import thread 

70from _pydev_imps._pydev_saved_modules import threading 

71from _pydev_imps._pydev_saved_modules import time 

72from _pydev_imps._pydev_saved_modules import socket 

73from socket import socket, AF_INET, SOCK_STREAM, SHUT_RD, SHUT_WR, SOL_SOCKET, SO_REUSEADDR, SHUT_RDWR, timeout 

74from _pydevd_bundle.pydevd_constants import DebugInfoHolder, get_thread_id, IS_JYTHON, IS_PY2, IS_PY3K, \ 

75 IS_PY36_OR_GREATER, STATE_RUN, dict_keys, ASYNC_EVAL_TIMEOUT_SEC, IS_IRONPYTHON, GlobalDebuggerHolder, \ 

76 get_global_debugger, GetGlobalDebugger, set_global_debugger # Keep for backward compatibility @UnusedImport 

77from _pydev_bundle.pydev_override import overrides 

78import json 

79import weakref 

80 

81try: 

82 from urllib import quote_plus, unquote, unquote_plus 

83except: 

84 from urllib.parse import quote_plus, unquote, unquote_plus #@Reimport @UnresolvedImport 

85 

86if IS_IRONPYTHON: 

87 # redefine `unquote` for IronPython, since we use it only for logging messages, but it leads to SOF with IronPython 

88 def unquote(s): 

89 return s 

90 

91from _pydevd_bundle import pydevd_console_integration 

92from _pydevd_bundle import pydevd_vars 

93import pydevd_tracing 

94from _pydevd_bundle import pydevd_xml 

95from _pydevd_bundle import pydevd_vm_type 

96from _pydevd_bundle import pydevd_bytecode_utils 

97from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame, norm_file_to_client, is_real_file 

98import pydevd_file_utils 

99import os 

100import sys 

101import inspect 

102import traceback 

103from _pydevd_bundle.pydevd_utils import quote_smart as quote, compare_object_attrs_key, to_string, \ 

104 get_non_pydevd_threads, is_pandas_container, is_numpy_container 

105from _pydev_bundle.pydev_is_thread_alive import is_thread_alive 

106from _pydev_bundle import pydev_log 

107from _pydev_bundle import _pydev_completer 

108 

109from pydevd_tracing import get_exception_traceback_str 

110from _pydevd_bundle import pydevd_console 

111from _pydev_bundle.pydev_monkey import disable_trace_thread_modules, enable_trace_thread_modules 

112 

113try: 

114 import cStringIO as StringIO #may not always be available @UnusedImport 

115except: 

116 try: 

117 import StringIO #@Reimport 

118 except: 

119 import io as StringIO 

120 

121from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE, PYDEV_FILE 

122get_file_type = DONT_TRACE.get 

123 

124 

125# CMD_XXX constants imported for backward compatibility 

126from _pydevd_bundle.pydevd_comm_constants import ( 

127 ID_TO_MEANING, CMD_RUN, CMD_LIST_THREADS, CMD_THREAD_CREATE, CMD_THREAD_KILL, 

128 CMD_THREAD_SUSPEND, CMD_THREAD_RUN, CMD_STEP_INTO, CMD_STEP_OVER, CMD_STEP_RETURN, CMD_GET_VARIABLE, 

129 CMD_SET_BREAK, CMD_REMOVE_BREAK, CMD_EVALUATE_EXPRESSION, CMD_GET_FRAME, 

130 CMD_EXEC_EXPRESSION, CMD_WRITE_TO_CONSOLE, CMD_CHANGE_VARIABLE, CMD_RUN_TO_LINE, 

131 CMD_RELOAD_CODE, CMD_GET_COMPLETIONS, CMD_CONSOLE_EXEC, CMD_ADD_EXCEPTION_BREAK, 

132 CMD_REMOVE_EXCEPTION_BREAK, CMD_LOAD_SOURCE, CMD_ADD_DJANGO_EXCEPTION_BREAK, 

133 CMD_REMOVE_DJANGO_EXCEPTION_BREAK, CMD_SET_NEXT_STATEMENT, CMD_SMART_STEP_INTO, 

134 CMD_EXIT, CMD_SIGNATURE_CALL_TRACE, CMD_SET_PY_EXCEPTION, CMD_GET_FILE_CONTENTS, 

135 CMD_SET_PROPERTY_TRACE, CMD_EVALUATE_CONSOLE_EXPRESSION, CMD_RUN_CUSTOM_OPERATION, 

136 CMD_GET_BREAKPOINT_EXCEPTION, CMD_STEP_CAUGHT_EXCEPTION, CMD_SEND_CURR_EXCEPTION_TRACE, 

137 CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED, CMD_IGNORE_THROWN_EXCEPTION_AT, CMD_ENABLE_DONT_TRACE, 

138 CMD_SHOW_CONSOLE, CMD_GET_ARRAY, CMD_STEP_INTO_MY_CODE, CMD_GET_CONCURRENCY_EVENT, 

139 CMD_SHOW_RETURN_VALUES, CMD_SET_UNIT_TEST_DEBUGGING_MODE, CMD_INPUT_REQUESTED, CMD_GET_DESCRIPTION, CMD_PROCESS_CREATED, 

140 CMD_SHOW_CYTHON_WARNING, CMD_LOAD_FULL_VALUE, CMD_GET_THREAD_STACK, CMD_THREAD_DUMP_TO_STDERR, 

141 CMD_STOP_ON_START, CMD_GET_EXCEPTION_DETAILS, CMD_PROCESS_CREATED_MSG_RECEIVED, CMD_PYDEVD_JSON_CONFIG, 

142 CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, CMD_THREAD_RESUME_SINGLE_NOTIFICATION, 

143 CMD_REDIRECT_OUTPUT, CMD_GET_NEXT_STATEMENT_TARGETS, CMD_SET_PROJECT_ROOTS, CMD_VERSION, 

144 CMD_RETURN, CMD_SET_PROTOCOL, CMD_ERROR, CMD_GET_SMART_STEP_INTO_VARIANTS, CMD_DATAVIEWER_ACTION,) 

145MAX_IO_MSG_SIZE = 1000 #if the io is too big, we'll not send all (could make the debugger too non-responsive) 

146#this number can be changed if there's need to do so 

147 

148VERSION_STRING = "@@BUILD_NUMBER@@" 

149 

150from _pydev_bundle._pydev_filesystem_encoding import getfilesystemencoding 

151file_system_encoding = getfilesystemencoding() 

152filesystem_encoding_is_utf8 = file_system_encoding.lower() in ('utf-8', 'utf_8', 'utf8') 

153 

154 

155class CommunicationRole(object): 

156 """The class that contains the constants of roles that `PyDB` can play in 

157 the communication with the IDE. 

158 """ 

159 CLIENT = 0 

160 SERVER = 1 

161 

162 

163#--------------------------------------------------------------------------------------------------- UTILITIES 

164 

165#======================================================================================================================= 

166# pydevd_log 

167#======================================================================================================================= 

168def pydevd_log(level, *args): 

169 """ levels are: 

170 0 most serious warnings/errors 

171 1 warnings/significant events 

172 2 informational trace 

173 """ 

174 if level <= DebugInfoHolder.DEBUG_TRACE_LEVEL: 

175 #yes, we can have errors printing if the console of the program has been finished (and we're still trying to print something) 

176 try: 

177 sys.stderr.write('%s\n' % (args,)) 

178 except: 

179 pass 

180 

181 

182#------------------------------------------------------------------- ACTUAL COMM 

183 

184#======================================================================================================================= 

185# PyDBDaemonThread 

186#======================================================================================================================= 

187class PyDBDaemonThread(threading.Thread): 

188 created_pydb_daemon_threads = {} 

189 

190 def __init__(self, target_and_args=None): 

191 ''' 

192 :param target_and_args: 

193 tuple(func, args, kwargs) if this should be a function and args to run. 

194 -- Note: use through run_as_pydevd_daemon_thread(). 

195 ''' 

196 threading.Thread.__init__(self) 

197 self.killReceived = False 

198 mark_as_pydevd_daemon_thread(self) 

199 self._target_and_args = target_and_args 

200 

201 def run(self): 

202 created_pydb_daemon = self.created_pydb_daemon_threads 

203 created_pydb_daemon[self] = 1 

204 try: 

205 try: 

206 if IS_JYTHON and not isinstance(threading.currentThread(), threading._MainThread): 

207 # we shouldn't update sys.modules for the main thread, cause it leads to the second importing 'threading' 

208 # module, and the new instance of main thread is created 

209 import org.python.core as PyCore #@UnresolvedImport 

210 ss = PyCore.PySystemState() 

211 # Note: Py.setSystemState() affects only the current thread. 

212 PyCore.Py.setSystemState(ss) 

213 

214 self._stop_trace() 

215 self._warn_pydevd_thread_is_traced() 

216 self._on_run() 

217 except: 

218 if sys is not None and traceback is not None: 

219 traceback.print_exc() 

220 finally: 

221 del created_pydb_daemon[self] 

222 

223 def _on_run(self): 

224 if self._target_and_args is not None: 

225 target, args, kwargs = self._target_and_args 

226 target(*args, **kwargs) 

227 else: 

228 raise NotImplementedError('Should be reimplemented by: %s' % self.__class__) 

229 

230 def do_kill_pydev_thread(self): 

231 self.killReceived = True 

232 

233 def _stop_trace(self): 

234 if self.pydev_do_not_trace: 

235 pydevd_tracing.SetTrace(None) # no debugging on this thread 

236 

237 def _warn_pydevd_thread_is_traced(self): 

238 if self.pydev_do_not_trace and sys.gettrace(): 

239 pydevd_log(1, "The debugger thread '%s' is traced which may lead to debugging performance issues." % self.__class__.__name__) 

240 

241 

242def mark_as_pydevd_daemon_thread(thread): 

243 thread.pydev_do_not_trace = True 

244 thread.is_pydev_daemon_thread = True 

245 thread.daemon = True 

246 

247 

248def run_as_pydevd_daemon_thread(func, *args, **kwargs): 

249 ''' 

250 Runs a function as a pydevd daemon thread (without any tracing in place). 

251 ''' 

252 t = PyDBDaemonThread(target_and_args=(func, args, kwargs)) 

253 t.name = '%s (pydevd daemon thread)' % (func.__name__,) 

254 t.start() 

255 return t 

256 

257 

258#======================================================================================================================= 

259# ReaderThread 

260#======================================================================================================================= 

261class ReaderThread(PyDBDaemonThread): 

262 """ reader thread reads and dispatches commands in an infinite loop """ 

263 

264 def __init__(self, sock): 

265 PyDBDaemonThread.__init__(self) 

266 self.sock = sock 

267 self.setName("pydevd.Reader") 

268 from _pydevd_bundle.pydevd_process_net_command import process_net_command 

269 self.process_net_command = process_net_command 

270 self.global_debugger_holder = GlobalDebuggerHolder 

271 

272 

273 

274 def do_kill_pydev_thread(self): 

275 #We must close the socket so that it doesn't stay halted there. 

276 self.killReceived = True 

277 try: 

278 self.sock.shutdown(SHUT_RD) #shutdown the socket for read 

279 except: 

280 #just ignore that 

281 pass 

282 

283 @overrides(PyDBDaemonThread._on_run) 

284 def _on_run(self): 

285 read_buffer = "" 

286 try: 

287 

288 while not self.killReceived: 

289 try: 

290 r = self.sock.recv(1024) 

291 except: 

292 if not self.killReceived: 

293 traceback.print_exc() 

294 self.handle_except() 

295 return #Finished communication. 

296 

297 #Note: the java backend is always expected to pass utf-8 encoded strings. We now work with unicode 

298 #internally and thus, we may need to convert to the actual encoding where needed (i.e.: filenames 

299 #on python 2 may need to be converted to the filesystem encoding). 

300 if hasattr(r, 'decode'): 

301 r = r.decode('utf-8') 

302 

303 read_buffer += r 

304 if DebugInfoHolder.DEBUG_RECORD_SOCKET_READS: 

305 sys.stderr.write(u'debugger: received >>%s<<\n' % (read_buffer,)) 

306 sys.stderr.flush() 

307 

308 if len(read_buffer) == 0: 

309 self.handle_except() 

310 break 

311 while read_buffer.find(u'\n') != -1: 

312 command, read_buffer = read_buffer.split(u'\n', 1) 

313 

314 args = command.split(u'\t', 2) 

315 try: 

316 cmd_id = int(args[0]) 

317 pydev_log.debug('Received command: %s %s\n' % (ID_TO_MEANING.get(str(cmd_id), '???'), command,)) 

318 self.process_command(cmd_id, int(args[1]), args[2]) 

319 except: 

320 traceback.print_exc() 

321 sys.stderr.write("Can't process net command: %s\n" % command) 

322 sys.stderr.flush() 

323 

324 except: 

325 traceback.print_exc() 

326 self.handle_except() 

327 

328 

329 def handle_except(self): 

330 self.global_debugger_holder.global_dbg.finish_debugging_session() 

331 

332 def process_command(self, cmd_id, seq, text): 

333 self.process_net_command(self.global_debugger_holder.global_dbg, cmd_id, seq, text) 

334 

335 

336#----------------------------------------------------------------------------------- SOCKET UTILITIES - WRITER 

337#======================================================================================================================= 

338# WriterThread 

339#======================================================================================================================= 

340class WriterThread(PyDBDaemonThread): 

341 """ writer thread writes out the commands in an infinite loop """ 

342 def __init__(self, sock): 

343 PyDBDaemonThread.__init__(self) 

344 self.sock = sock 

345 self.setName("pydevd.Writer") 

346 self.cmdQueue = _queue.Queue() 

347 if pydevd_vm_type.get_vm_type() == 'python': 

348 self.timeout = 0 

349 else: 

350 self.timeout = 0.1 

351 

352 def add_command(self, cmd): 

353 """ cmd is NetCommand """ 

354 if not self.killReceived: #we don't take new data after everybody die 

355 self.cmdQueue.put(cmd) 

356 

357 @overrides(PyDBDaemonThread._on_run) 

358 def _on_run(self): 

359 """ just loop and write responses """ 

360 

361 try: 

362 while True: 

363 try: 

364 try: 

365 cmd = self.cmdQueue.get(1, 0.1) 

366 except _queue.Empty: 

367 if self.killReceived: 

368 try: 

369 self.sock.shutdown(SHUT_WR) 

370 self.sock.close() 

371 except: 

372 pass 

373 

374 return #break if queue is empty and killReceived 

375 else: 

376 continue 

377 except: 

378 #pydevd_log(0, 'Finishing debug communication...(1)') 

379 #when liberating the thread here, we could have errors because we were shutting down 

380 #but the thread was still not liberated 

381 return 

382 cmd.send(self.sock) 

383 

384 if cmd.id == CMD_EXIT: 

385 break 

386 if time is None: 

387 break #interpreter shutdown 

388 time.sleep(self.timeout) 

389 except Exception: 

390 GlobalDebuggerHolder.global_dbg.finish_debugging_session() 

391 if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 0: 

392 traceback.print_exc() 

393 

394 def empty(self): 

395 return self.cmdQueue.empty() 

396 

397 

398 

399#--------------------------------------------------- CREATING THE SOCKET THREADS 

400 

401#======================================================================================================================= 

402# start_server 

403#======================================================================================================================= 

404def start_server(port): 

405 """ binds to a port, waits for the debugger to connect """ 

406 s = socket(AF_INET, SOCK_STREAM) 

407 s.settimeout(None) 

408 

409 try: 

410 from socket import SO_REUSEPORT 

411 s.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) 

412 except ImportError: 

413 s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 

414 

415 s.bind(('', port)) 

416 pydevd_log(1, "Bound to port ", str(port)) 

417 

418 try: 

419 s.listen(1) 

420 newSock, _addr = s.accept() 

421 pydevd_log(1, "Connection accepted") 

422 # closing server socket is not necessary but we don't need it 

423 s.shutdown(SHUT_RDWR) 

424 s.close() 

425 return newSock 

426 

427 except: 

428 sys.stderr.write("Could not bind to port: %s\n" % (port,)) 

429 sys.stderr.flush() 

430 traceback.print_exc() 

431 

432#======================================================================================================================= 

433# start_client 

434#======================================================================================================================= 

435def start_client(host, port): 

436 """ connects to a host/port """ 

437 pydevd_log(1, "Connecting to ", host, ":", str(port)) 

438 

439 s = socket(AF_INET, SOCK_STREAM) 

440 

441 # Set TCP keepalive on an open socket. 

442 # It activates after 1 second (TCP_KEEPIDLE,) of idleness, 

443 # then sends a keepalive ping once every 3 seconds (TCP_KEEPINTVL), 

444 # and closes the connection after 5 failed ping (TCP_KEEPCNT), or 15 seconds 

445 try: 

446 from socket import IPPROTO_TCP, SO_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT 

447 s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1) 

448 s.setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, 1) 

449 s.setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, 3) 

450 s.setsockopt(IPPROTO_TCP, TCP_KEEPCNT, 5) 

451 except ImportError: 

452 pass # May not be available everywhere. 

453 

454 try: 

455 s.settimeout(10) # 10 seconds timeout 

456 s.connect((host, port)) 

457 s.settimeout(None) # no timeout after connected 

458 pydevd_log(1, "Connected.") 

459 return s 

460 except: 

461 sys.stderr.write("Could not connect to %s: %s\n" % (host, port)) 

462 sys.stderr.flush() 

463 traceback.print_exc() 

464 raise 

465 

466 

467 

468 

469#------------------------------------------------------------------------------------ MANY COMMUNICATION STUFF 

470 

471#======================================================================================================================= 

472# NetCommand 

473#======================================================================================================================= 

474class NetCommand: 

475 """ Commands received/sent over the network. 

476 

477 Command can represent command received from the debugger, 

478 or one to be sent by daemon. 

479 """ 

480 next_seq = 0 # sequence numbers 

481 

482 # Protocol where each line is a new message (text is quoted to prevent new lines). 

483 QUOTED_LINE_PROTOCOL = 'quoted-line' 

484 

485 # Uses http protocol to provide a new message. 

486 # i.e.: Content-Length:xxx\r\n\r\npayload 

487 HTTP_PROTOCOL = 'http' 

488 

489 protocol = QUOTED_LINE_PROTOCOL 

490 

491 _showing_debug_info = 0 

492 _show_debug_info_lock = threading.RLock() 

493 

494 def __init__(self, cmd_id, seq, text): 

495 """ 

496 If sequence is 0, new sequence will be generated (otherwise, this was the response 

497 to a command from the client). 

498 """ 

499 self.id = cmd_id 

500 if seq == 0: 

501 NetCommand.next_seq += 2 

502 seq = NetCommand.next_seq 

503 self.seq = seq 

504 

505 if IS_PY2: 

506 if isinstance(text, unicode): 

507 text = text.encode('utf-8') 

508 else: 

509 assert isinstance(text, str) 

510 else: 

511 assert isinstance(text, str) 

512 

513 if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: 

514 self._show_debug_info(cmd_id, seq, text) 

515 

516 if self.protocol == self.HTTP_PROTOCOL: 

517 msg = '%s\t%s\t%s\n' % (cmd_id, seq, text) 

518 else: 

519 encoded = quote(to_string(text), '/<>_=" \t') 

520 msg = '%s\t%s\t%s\n' % (cmd_id, seq, encoded) 

521 

522 

523 if IS_PY2: 

524 assert isinstance(msg, str) # i.e.: bytes 

525 as_bytes = msg 

526 else: 

527 if isinstance(msg, str): 

528 msg = msg.encode('utf-8') 

529 

530 assert isinstance(msg, bytes) 

531 as_bytes = msg 

532 self._as_bytes = as_bytes 

533 

534 def send(self, sock): 

535 as_bytes = self._as_bytes 

536 if self.protocol == self.HTTP_PROTOCOL: 

537 sock.sendall(('Content-Length: %s\r\n\r\n' % len(as_bytes)).encode('ascii')) 

538 

539 sock.sendall(as_bytes) 

540 

541 @classmethod 

542 def _show_debug_info(cls, cmd_id, seq, text): 

543 with cls._show_debug_info_lock: 

544 # Only one thread each time (rlock). 

545 if cls._showing_debug_info: 

546 # avoid recursing in the same thread (just printing could create 

547 # a new command when redirecting output). 

548 return 

549 

550 cls._showing_debug_info += 1 

551 try: 

552 out_message = 'sending cmd --> ' 

553 out_message += "%20s" % ID_TO_MEANING.get(str(cmd_id), 'UNKNOWN') 

554 out_message += ' ' 

555 out_message += text.replace('\n', ' ') 

556 try: 

557 sys.stderr.write('%s\n' % (out_message,)) 

558 except: 

559 pass 

560 finally: 

561 cls._showing_debug_info -= 1 

562 

563 

564#======================================================================================================================= 

565# NetCommandFactory 

566#======================================================================================================================= 

567class NetCommandFactory: 

568 

569 def _thread_to_xml(self, thread): 

570 """ thread information as XML """ 

571 name = pydevd_xml.make_valid_xml_value(thread.getName()) 

572 cmdText = '<thread name="%s" id="%s" />' % (quote(name), get_thread_id(thread)) 

573 return cmdText 

574 

575 def make_error_message(self, seq, text): 

576 cmd = NetCommand(CMD_ERROR, seq, text) 

577 if DebugInfoHolder.DEBUG_TRACE_LEVEL > 2: 

578 sys.stderr.write("Error: %s" % (text,)) 

579 return cmd 

580 

581 def make_protocol_set_message(self, seq): 

582 return NetCommand(CMD_SET_PROTOCOL, seq, '') 

583 

584 def make_thread_created_message(self, thread): 

585 cmdText = "<xml>" + self._thread_to_xml(thread) + "</xml>" 

586 return NetCommand(CMD_THREAD_CREATE, 0, cmdText) 

587 

588 def make_process_created_message(self): 

589 cmdText = '<process/>' 

590 return NetCommand(CMD_PROCESS_CREATED, 0, cmdText) 

591 

592 def make_show_warning_message(self, message_id): 

593 try: 

594 cmdText = '<xml><warning id="%s" /></xml>' % message_id 

595 return NetCommand(CMD_SHOW_CYTHON_WARNING, 0, cmdText) 

596 except: 

597 return self.make_error_message(0, get_exception_traceback_str()) 

598 

599 def make_custom_frame_created_message(self, frameId, frameDescription): 

600 frameDescription = pydevd_xml.make_valid_xml_value(frameDescription) 

601 cmdText = '<xml><thread name="%s" id="%s"/></xml>' % (frameDescription, frameId) 

602 return NetCommand(CMD_THREAD_CREATE, 0, cmdText) 

603 

604 

605 def make_list_threads_message(self, seq): 

606 """ returns thread listing as XML """ 

607 try: 

608 threads = get_non_pydevd_threads() 

609 cmd_text = ["<xml>"] 

610 append = cmd_text.append 

611 for thread in threads: 

612 if is_thread_alive(thread): 

613 append(self._thread_to_xml(thread)) 

614 append("</xml>") 

615 return NetCommand(CMD_RETURN, seq, ''.join(cmd_text)) 

616 except: 

617 return self.make_error_message(seq, get_exception_traceback_str()) 

618 

619 def make_get_thread_stack_message(self, seq, thread_id, topmost_frame, must_be_suspended=False): 

620 """ 

621 Returns thread stack as XML. 

622 

623 :param be_suspended: If True and the thread is not suspended, returns None. 

624 """ 

625 try: 

626 # If frame is None, the return is an empty frame list. 

627 cmd_text = ['<xml><thread id="%s">' % (thread_id,)] 

628 

629 if topmost_frame is not None: 

630 try: 

631 # Note: if we detect that we're already stopped in a given place within 

632 # the debugger, use that stack instead of creating a new one with the 

633 # current position (this is needed because when an uncaught exception 

634 # is reported for a given frame we are actually stopped in a different 

635 # place within the debugger). 

636 frame = topmost_frame 

637 thread_stack_str = '' 

638 while frame is not None: 

639 if frame.f_code.co_name == 'do_wait_suspend' and frame.f_code.co_filename.endswith('pydevd.py'): 

640 thread_stack_str = frame.f_locals.get('thread_stack_str') 

641 break 

642 frame = frame.f_back 

643 else: 

644 # Could not find stack of suspended frame... 

645 if must_be_suspended: 

646 return None 

647 cmd_text.append(thread_stack_str or self.make_thread_stack_str(topmost_frame)) 

648 finally: 

649 topmost_frame = None 

650 cmd_text.append('</thread></xml>') 

651 return NetCommand(CMD_GET_THREAD_STACK, seq, ''.join(cmd_text)) 

652 except: 

653 return self.make_error_message(seq, get_exception_traceback_str()) 

654 

655 def make_variable_changed_message(self, seq, payload): 

656 # notify debugger that value was changed successfully 

657 return NetCommand(CMD_RETURN, seq, payload) 

658 

659 def make_io_message(self, v, ctx): 

660 ''' 

661 @param v: the message to pass to the debug server 

662 @param ctx: 1 for stdio 2 for stderr 

663 ''' 

664 

665 try: 

666 if len(v) > MAX_IO_MSG_SIZE: 

667 v = v[0:MAX_IO_MSG_SIZE] 

668 v += '...' 

669 

670 v = pydevd_xml.make_valid_xml_value(quote(v, '/>_= ')) 

671 return NetCommand(str(CMD_WRITE_TO_CONSOLE), 0, '<xml><io s="%s" ctx="%s"/></xml>' % (v, ctx)) 

672 except: 

673 return self.make_error_message(0, get_exception_traceback_str()) 

674 

675 def make_version_message(self, seq): 

676 try: 

677 return NetCommand(CMD_VERSION, seq, VERSION_STRING) 

678 except: 

679 return self.make_error_message(seq, get_exception_traceback_str()) 

680 

681 def make_thread_killed_message(self, id): 

682 try: 

683 return NetCommand(CMD_THREAD_KILL, 0, str(id)) 

684 except: 

685 return self.make_error_message(0, get_exception_traceback_str()) 

686 

687 def make_thread_stack_str(self, frame, frame_to_lineno=None): 

688 ''' 

689 :param frame_to_lineno: 

690 If available, the line number for the frame will be gotten from this dict, 

691 otherwise frame.f_lineno will be used (needed for unhandled exceptions as 

692 the place where we report may be different from the place where it's raised). 

693 ''' 

694 if frame_to_lineno is None: 

695 frame_to_lineno = {} 

696 make_valid_xml_value = pydevd_xml.make_valid_xml_value 

697 cmd_text_list = [] 

698 append = cmd_text_list.append 

699 

700 curr_frame = frame 

701 frame = None # Clear frame reference 

702 try: 

703 while curr_frame: 

704 my_id = id(curr_frame) 

705 

706 if curr_frame.f_code is None: 

707 break # Iron Python sometimes does not have it! 

708 

709 method_name = curr_frame.f_code.co_name # method name (if in method) or ? if global 

710 if method_name is None: 

711 break # Iron Python sometimes does not have it! 

712 

713 abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(curr_frame) 

714 if get_file_type(abs_path_real_path_and_base[2]) == PYDEV_FILE: 

715 # Syntax errors are a special case in which we don't want to skip the debugger files. 

716 # When a syntax error happens, we stop either in the `execfile` or `_exec` function. 

717 exception_info, is_syntax_error = curr_frame.f_locals.get('__exception__'), False 

718 if exception_info: 

719 is_syntax_error = exception_info[0] is SyntaxError 

720 if not is_syntax_error: 

721 # Skip pydevd files. 

722 curr_frame = curr_frame.f_back 

723 continue 

724 

725 my_file = abs_path_real_path_and_base[0] 

726 

727 if is_real_file(my_file): 

728 # if filename is Jupyter cell id 

729 my_file = pydevd_file_utils.norm_file_to_client(abs_path_real_path_and_base[0]) 

730 

731 if file_system_encoding.lower() != "utf-8" and hasattr(my_file, "decode"): 

732 # my_file is a byte string encoded using the file system encoding 

733 # convert it to utf8 

734 my_file = my_file.decode(file_system_encoding).encode("utf-8") 

735 

736 #print "file is ", my_file 

737 #my_file = inspect.getsourcefile(curr_frame) or inspect.getfile(frame) 

738 

739 lineno = frame_to_lineno.get(curr_frame, curr_frame.f_lineno) 

740 # print("line is ", lineno) 

741 

742 # Note: variables are all gotten 'on-demand'. 

743 append('<frame id="%s" name="%s" ' % (my_id , make_valid_xml_value(method_name))) 

744 append('file="%s" line="%s">' % (make_valid_xml_value(my_file), lineno)) 

745 append("</frame>") 

746 curr_frame = curr_frame.f_back 

747 except: 

748 traceback.print_exc() 

749 

750 curr_frame = None # Clear frame reference 

751 return ''.join(cmd_text_list) 

752 

753 def make_thread_suspend_str( 

754 self, 

755 thread_id, 

756 frame, 

757 stop_reason=None, 

758 message=None, 

759 suspend_type="trace", 

760 frame_to_lineno=None 

761 ): 

762 """ 

763 :return tuple(str,str): 

764 Returns tuple(thread_suspended_str, thread_stack_str). 

765 

766 i.e.: 

767 ( 

768 ''' 

769 <xml> 

770 <thread id="id" stop_reason="reason"> 

771 <frame id="id" name="functionName " file="file" line="line"> 

772 </frame> 

773 </thread> 

774 </xml> 

775 ''' 

776 , 

777 ''' 

778 <frame id="id" name="functionName " file="file" line="line"> 

779 </frame> 

780 ''' 

781 ) 

782 """ 

783 make_valid_xml_value = pydevd_xml.make_valid_xml_value 

784 cmd_text_list = [] 

785 append = cmd_text_list.append 

786 

787 cmd_text_list.append('<xml>') 

788 if message: 

789 message = make_valid_xml_value(message) 

790 

791 append('<thread id="%s"' % (thread_id,)) 

792 if stop_reason is not None: 

793 append(' stop_reason="%s"' % (stop_reason,)) 

794 if message is not None: 

795 append(' message="%s"' % (message,)) 

796 if suspend_type is not None: 

797 append(' suspend_type="%s"' % (suspend_type,)) 

798 append('>') 

799 thread_stack_str = self.make_thread_stack_str(frame, frame_to_lineno) 

800 append(thread_stack_str) 

801 append("</thread></xml>") 

802 

803 return ''.join(cmd_text_list), thread_stack_str 

804 

805 def make_thread_suspend_message(self, thread_id, frame, stop_reason, message, suspend_type, frame_to_lineno=None): 

806 try: 

807 thread_suspend_str, thread_stack_str = self.make_thread_suspend_str( 

808 thread_id, frame, stop_reason, message, suspend_type, frame_to_lineno=frame_to_lineno) 

809 cmd = NetCommand(CMD_THREAD_SUSPEND, 0, thread_suspend_str) 

810 cmd.thread_stack_str = thread_stack_str 

811 cmd.thread_suspend_str = thread_suspend_str 

812 return cmd 

813 except: 

814 return self.make_error_message(0, get_exception_traceback_str()) 

815 

816 def make_thread_suspend_single_notification(self, thread_id, stop_reason): 

817 try: 

818 return NetCommand(CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, 0, json.dumps( 

819 {'thread_id': thread_id, 'stop_reason': stop_reason})) 

820 except: 

821 return self.make_error_message(0, get_exception_traceback_str()) 

822 

823 def make_thread_resume_single_notification(self, thread_id): 

824 try: 

825 return NetCommand(CMD_THREAD_RESUME_SINGLE_NOTIFICATION, 0, json.dumps( 

826 {'thread_id': thread_id})) 

827 except: 

828 return self.make_error_message(0, get_exception_traceback_str()) 

829 

830 def make_thread_run_message(self, thread_id, reason): 

831 try: 

832 return NetCommand(CMD_THREAD_RUN, 0, "%s\t%s" % (thread_id, reason)) 

833 except: 

834 return self.make_error_message(0, get_exception_traceback_str()) 

835 

836 def make_get_variable_message(self, seq, payload): 

837 try: 

838 return NetCommand(CMD_GET_VARIABLE, seq, payload) 

839 except Exception: 

840 return self.make_error_message(seq, get_exception_traceback_str()) 

841 

842 

843 def make_get_array_message(self, seq, payload): 

844 try: 

845 return NetCommand(CMD_GET_ARRAY, seq, payload) 

846 except Exception: 

847 return self.make_error_message(seq, get_exception_traceback_str()) 

848 

849 def make_successful_dataviewer_action_message(self, seq, payload): 

850 try: 

851 return NetCommand(CMD_DATAVIEWER_ACTION, seq, payload) 

852 except Exception: 

853 return self.make_error_message(seq, get_exception_traceback_str()) 

854 

855 def make_get_description_message(self, seq, payload): 

856 try: 

857 return NetCommand(CMD_GET_DESCRIPTION, seq, payload) 

858 except Exception: 

859 return self.make_error_message(seq, get_exception_traceback_str()) 

860 

861 def make_get_frame_message(self, seq, payload): 

862 try: 

863 return NetCommand(CMD_GET_FRAME, seq, payload) 

864 except Exception: 

865 return self.make_error_message(seq, get_exception_traceback_str()) 

866 

867 

868 def make_evaluate_expression_message(self, seq, payload): 

869 try: 

870 return NetCommand(CMD_EVALUATE_EXPRESSION, seq, payload) 

871 except Exception: 

872 return self.make_error_message(seq, get_exception_traceback_str()) 

873 

874 def make_get_completions_message(self, seq, payload): 

875 try: 

876 return NetCommand(CMD_GET_COMPLETIONS, seq, payload) 

877 except Exception: 

878 return self.make_error_message(seq, get_exception_traceback_str()) 

879 

880 def make_get_file_contents(self, seq, payload): 

881 try: 

882 return NetCommand(CMD_GET_FILE_CONTENTS, seq, payload) 

883 except Exception: 

884 return self.make_error_message(seq, get_exception_traceback_str()) 

885 

886 def make_send_breakpoint_exception_message(self, seq, payload): 

887 try: 

888 return NetCommand(CMD_GET_BREAKPOINT_EXCEPTION, seq, payload) 

889 except Exception: 

890 return self.make_error_message(seq, get_exception_traceback_str()) 

891 

892 def _make_send_curr_exception_trace_str(self, thread_id, exc_type, exc_desc, trace_obj): 

893 while trace_obj.tb_next is not None: 

894 trace_obj = trace_obj.tb_next 

895 

896 exc_type = pydevd_xml.make_valid_xml_value(str(exc_type)).replace('\t', ' ') or 'exception: type unknown' 

897 exc_desc = pydevd_xml.make_valid_xml_value(str(exc_desc)).replace('\t', ' ') or 'exception: no description' 

898 

899 thread_suspend_str, thread_stack_str = self.make_thread_suspend_str( 

900 thread_id, trace_obj.tb_frame, CMD_SEND_CURR_EXCEPTION_TRACE, '') 

901 return exc_type, exc_desc, thread_suspend_str, thread_stack_str 

902 

903 def make_send_curr_exception_trace_message(self, seq, thread_id, curr_frame_id, exc_type, exc_desc, trace_obj): 

904 try: 

905 exc_type, exc_desc, thread_suspend_str, _thread_stack_str = self._make_send_curr_exception_trace_str( 

906 thread_id, exc_type, exc_desc, trace_obj) 

907 payload = str(curr_frame_id) + '\t' + exc_type + "\t" + exc_desc + "\t" + thread_suspend_str 

908 return NetCommand(CMD_SEND_CURR_EXCEPTION_TRACE, seq, payload) 

909 except Exception: 

910 return self.make_error_message(seq, get_exception_traceback_str()) 

911 

912 def make_get_exception_details_message(self, seq, thread_id, topmost_frame): 

913 """Returns exception details as XML """ 

914 try: 

915 # If the debugger is not suspended, just return the thread and its id. 

916 cmd_text = ['<xml><thread id="%s" ' % (thread_id,)] 

917 

918 if topmost_frame is not None: 

919 try: 

920 frame = topmost_frame 

921 topmost_frame = None 

922 while frame is not None: 

923 if frame.f_code.co_name == 'do_wait_suspend' and frame.f_code.co_filename.endswith('pydevd.py'): 

924 arg = frame.f_locals.get('arg', None) 

925 if arg is not None: 

926 exc_type, exc_desc, _thread_suspend_str, thread_stack_str = self._make_send_curr_exception_trace_str( 

927 thread_id, *arg) 

928 cmd_text.append('exc_type="%s" ' % (exc_type,)) 

929 cmd_text.append('exc_desc="%s" ' % (exc_desc,)) 

930 cmd_text.append('>') 

931 cmd_text.append(thread_stack_str) 

932 break 

933 frame = frame.f_back 

934 else: 

935 cmd_text.append('>') 

936 finally: 

937 frame = None 

938 cmd_text.append('</thread></xml>') 

939 return NetCommand(CMD_GET_EXCEPTION_DETAILS, seq, ''.join(cmd_text)) 

940 except: 

941 return self.make_error_message(seq, get_exception_traceback_str()) 

942 

943 def make_send_curr_exception_trace_proceeded_message(self, seq, thread_id): 

944 try: 

945 return NetCommand(CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED, 0, str(thread_id)) 

946 except: 

947 return self.make_error_message(0, get_exception_traceback_str()) 

948 

949 def make_send_console_message(self, seq, payload): 

950 try: 

951 return NetCommand(CMD_EVALUATE_CONSOLE_EXPRESSION, seq, payload) 

952 except Exception: 

953 return self.make_error_message(seq, get_exception_traceback_str()) 

954 

955 def make_custom_operation_message(self, seq, payload): 

956 try: 

957 return NetCommand(CMD_RUN_CUSTOM_OPERATION, seq, payload) 

958 except Exception: 

959 return self.make_error_message(seq, get_exception_traceback_str()) 

960 

961 def make_load_source_message(self, seq, source, dbg=None): 

962 try: 

963 net = NetCommand(CMD_LOAD_SOURCE, seq, '%s' % source) 

964 

965 except: 

966 net = self.make_error_message(0, get_exception_traceback_str()) 

967 

968 if dbg: 

969 dbg.writer.add_command(net) 

970 return net 

971 

972 def make_show_console_message(self, thread_id, frame): 

973 try: 

974 thread_suspended_str, _thread_stack_str = self.make_thread_suspend_str(thread_id, frame, CMD_SHOW_CONSOLE, '') 

975 return NetCommand(CMD_SHOW_CONSOLE, 0, thread_suspended_str) 

976 except: 

977 return self.make_error_message(0, get_exception_traceback_str()) 

978 

979 def make_input_requested_message(self, started): 

980 try: 

981 return NetCommand(CMD_INPUT_REQUESTED, 0, str(started)) 

982 except: 

983 return self.make_error_message(0, get_exception_traceback_str()) 

984 

985 def make_set_next_stmnt_status_message(self, seq, is_success, exception_msg): 

986 try: 

987 message = str(is_success) + '\t' + exception_msg 

988 return NetCommand(CMD_SET_NEXT_STATEMENT, int(seq), message) 

989 except: 

990 return self.make_error_message(0, get_exception_traceback_str()) 

991 

992 def make_load_full_value_message(self, seq, payload): 

993 try: 

994 return NetCommand(CMD_LOAD_FULL_VALUE, seq, payload) 

995 except Exception: 

996 return self.make_error_message(seq, get_exception_traceback_str()) 

997 

998 def make_exit_message(self): 

999 try: 

1000 net = NetCommand(CMD_EXIT, 0, '') 

1001 

1002 except: 

1003 net = self.make_error_message(0, get_exception_traceback_str()) 

1004 

1005 return net 

1006 

1007 def make_get_next_statement_targets_message(self, seq, payload): 

1008 try: 

1009 return NetCommand(CMD_GET_NEXT_STATEMENT_TARGETS, seq, payload) 

1010 except Exception: 

1011 return self.make_error_message(seq, get_exception_traceback_str()) 

1012 

1013 

1014INTERNAL_TERMINATE_THREAD = 1 

1015INTERNAL_SUSPEND_THREAD = 2 

1016 

1017 

1018#======================================================================================================================= 

1019# InternalThreadCommand 

1020#======================================================================================================================= 

1021class InternalThreadCommand: 

1022 """ internal commands are generated/executed by the debugger. 

1023 

1024 The reason for their existence is that some commands have to be executed 

1025 on specific threads. These are the InternalThreadCommands that get 

1026 get posted to PyDB.cmdQueue. 

1027 """ 

1028 

1029 def __init__(self, thread_id): 

1030 self.thread_id = thread_id 

1031 

1032 def can_be_executed_by(self, thread_id): 

1033 '''By default, it must be in the same thread to be executed 

1034 ''' 

1035 return self.thread_id == thread_id or self.thread_id.endswith('|' + thread_id) 

1036 

1037 def do_it(self, dbg): 

1038 raise NotImplementedError("you have to override do_it") 

1039 

1040 

1041class ReloadCodeCommand(InternalThreadCommand): 

1042 

1043 

1044 def __init__(self, module_name, thread_id): 

1045 self.thread_id = thread_id 

1046 self.module_name = module_name 

1047 self.executed = False 

1048 self.lock = thread.allocate_lock() 

1049 

1050 

1051 def can_be_executed_by(self, thread_id): 

1052 if self.thread_id == '*': 

1053 return True #Any thread can execute it! 

1054 

1055 return InternalThreadCommand.can_be_executed_by(self, thread_id) 

1056 

1057 

1058 def do_it(self, dbg): 

1059 self.lock.acquire() 

1060 try: 

1061 if self.executed: 

1062 return 

1063 self.executed = True 

1064 finally: 

1065 self.lock.release() 

1066 

1067 module_name = self.module_name 

1068 if module_name not in sys.modules: 

1069 if '.' in module_name: 

1070 new_module_name = module_name.split('.')[-1] 

1071 if new_module_name in sys.modules: 

1072 module_name = new_module_name 

1073 

1074 if module_name not in sys.modules: 

1075 sys.stderr.write('pydev debugger: Unable to find module to reload: "' + module_name + '".\n') 

1076 # Too much info... 

1077 # sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n') 

1078 

1079 else: 

1080 sys.stderr.write('pydev debugger: Start reloading module: "' + module_name + '" ... \n') 

1081 from _pydevd_bundle import pydevd_reload 

1082 if pydevd_reload.xreload(sys.modules[module_name]): 

1083 sys.stderr.write('pydev debugger: reload finished\n') 

1084 else: 

1085 sys.stderr.write('pydev debugger: reload finished without applying any change\n') 

1086 

1087 

1088#======================================================================================================================= 

1089# InternalGetThreadStack 

1090#======================================================================================================================= 

1091class InternalGetThreadStack(InternalThreadCommand): 

1092 ''' 

1093 This command will either wait for a given thread to be paused to get its stack or will provide 

1094 it anyways after a timeout (in which case the stack will be gotten but local variables won't 

1095 be available and it'll not be possible to interact with the frame as it's not actually 

1096 stopped in a breakpoint). 

1097 ''' 

1098 

1099 def __init__(self, seq, thread_id, py_db, set_additional_thread_info, timeout=.5): 

1100 InternalThreadCommand.__init__(self, thread_id) 

1101 self._py_db = weakref.ref(py_db) 

1102 self._timeout = time.time() + timeout 

1103 self.seq = seq 

1104 self._cmd = None 

1105 

1106 # Note: receives set_additional_thread_info to avoid a circular import 

1107 # in this module. 

1108 self._set_additional_thread_info = set_additional_thread_info 

1109 

1110 @overrides(InternalThreadCommand.can_be_executed_by) 

1111 def can_be_executed_by(self, _thread_id): 

1112 timed_out = time.time() >= self._timeout 

1113 

1114 py_db = self._py_db() 

1115 t = pydevd_find_thread_by_id(self.thread_id) 

1116 frame = None 

1117 if t and not getattr(t, 'pydev_do_not_trace', None): 

1118 additional_info = self._set_additional_thread_info(t) 

1119 frame = additional_info.get_topmost_frame(t) 

1120 try: 

1121 self._cmd = py_db.cmd_factory.make_get_thread_stack_message( 

1122 self.seq, self.thread_id, frame, must_be_suspended=not timed_out) 

1123 finally: 

1124 frame = None 

1125 t = None 

1126 

1127 return self._cmd is not None or timed_out 

1128 

1129 @overrides(InternalThreadCommand.do_it) 

1130 def do_it(self, dbg): 

1131 if self._cmd is not None: 

1132 dbg.writer.add_command(self._cmd) 

1133 self._cmd = None 

1134 

1135 

1136#======================================================================================================================= 

1137# InternalRunThread 

1138#======================================================================================================================= 

1139class InternalRunThread(InternalThreadCommand): 

1140 

1141 def do_it(self, dbg): 

1142 t = pydevd_find_thread_by_id(self.thread_id) 

1143 if t: 

1144 t.additional_info.pydev_step_cmd = -1 

1145 t.additional_info.pydev_step_stop = None 

1146 t.additional_info.pydev_state = STATE_RUN 

1147 

1148 

1149#======================================================================================================================= 

1150# InternalStepThread 

1151#======================================================================================================================= 

1152class InternalStepThread(InternalThreadCommand): 

1153 def __init__(self, thread_id, cmd_id): 

1154 self.thread_id = thread_id 

1155 self.cmd_id = cmd_id 

1156 

1157 def do_it(self, dbg): 

1158 t = pydevd_find_thread_by_id(self.thread_id) 

1159 if t: 

1160 t.additional_info.pydev_step_cmd = self.cmd_id 

1161 t.additional_info.pydev_state = STATE_RUN 

1162 

1163 

1164#======================================================================================================================= 

1165# InternalSetNextStatementThread 

1166#======================================================================================================================= 

1167class InternalSetNextStatementThread(InternalThreadCommand): 

1168 def __init__(self, thread_id, cmd_id, line, func_name, seq=0): 

1169 self.thread_id = thread_id 

1170 self.cmd_id = cmd_id 

1171 self.line = line 

1172 self.seq = seq 

1173 

1174 if IS_PY2: 

1175 if isinstance(func_name, unicode): 

1176 # On cython with python 2.X it requires an str, not unicode (but on python 3.3 it should be a str, not bytes). 

1177 func_name = func_name.encode('utf-8') 

1178 

1179 self.func_name = func_name 

1180 

1181 def do_it(self, dbg): 

1182 t = pydevd_find_thread_by_id(self.thread_id) 

1183 if t: 

1184 t.additional_info.pydev_step_cmd = self.cmd_id 

1185 t.additional_info.pydev_next_line = int(self.line) 

1186 t.additional_info.pydev_func_name = self.func_name 

1187 t.additional_info.pydev_state = STATE_RUN 

1188 t.additional_info.pydev_message = str(self.seq) 

1189 

1190 

1191class InternalSmartStepInto(InternalThreadCommand): 

1192 def __init__(self, thread_id, frame_id, cmd_id, func_name, line, call_order, start_line, end_line, seq=0): 

1193 self.thread_id = thread_id 

1194 self.cmd_id = cmd_id 

1195 self.line = line 

1196 self.start_line = start_line 

1197 self.end_line = end_line 

1198 self.seq = seq 

1199 self.call_order = call_order 

1200 

1201 if IS_PY2: 

1202 if isinstance(func_name, unicode): 

1203 # On cython with python 2.X it requires an str, not unicode (but on python 3.3 it should be a str, not bytes). 

1204 func_name = func_name.encode('utf-8') 

1205 

1206 self.func_name = func_name 

1207 

1208 def do_it(self, dbg): 

1209 t = pydevd_find_thread_by_id(self.thread_id) 

1210 if t: 

1211 t.additional_info.pydev_step_cmd = self.cmd_id 

1212 t.additional_info.pydev_next_line = int(self.line) 

1213 t.additional_info.pydev_func_name = self.func_name 

1214 t.additional_info.pydev_state = STATE_RUN 

1215 t.additional_info.pydev_message = str(self.seq) 

1216 t.additional_info.pydev_smart_step_context.call_order = int(self.call_order) 

1217 t.additional_info.pydev_smart_step_context.start_line = int(self.start_line) 

1218 t.additional_info.pydev_smart_step_context.end_line = int(self.end_line) 

1219 

1220 

1221#======================================================================================================================= 

1222# InternalGetVariable 

1223#======================================================================================================================= 

1224class InternalGetVariable(InternalThreadCommand): 

1225 """ gets the value of a variable """ 

1226 def __init__(self, seq, thread_id, frame_id, scope, attrs): 

1227 self.sequence = seq 

1228 self.thread_id = thread_id 

1229 self.frame_id = frame_id 

1230 self.scope = scope 

1231 self.attributes = attrs 

1232 

1233 def do_it(self, dbg): 

1234 """ Converts request into python variable """ 

1235 try: 

1236 xml = StringIO.StringIO() 

1237 xml.write("<xml>") 

1238 _typeName, val_dict = pydevd_vars.resolve_compound_variable_fields(self.thread_id, self.frame_id, self.scope, self.attributes) 

1239 if val_dict is None: 

1240 val_dict = {} 

1241 

1242 # assume properly ordered if resolver returns 'OrderedDict' 

1243 # check type as string to support OrderedDict backport for older Python 

1244 keys = dict_keys(val_dict) 

1245 if not (_typeName == "OrderedDict" or val_dict.__class__.__name__ == "OrderedDict" or IS_PY36_OR_GREATER): 

1246 keys.sort(key=compare_object_attrs_key) 

1247 

1248 for k in keys: 

1249 val = val_dict[k] 

1250 evaluate_full_value = pydevd_xml.should_evaluate_full_value(val) 

1251 xml.write(pydevd_xml.var_to_xml(val, k, evaluate_full_value=evaluate_full_value)) 

1252 

1253 xml.write("</xml>") 

1254 cmd = dbg.cmd_factory.make_get_variable_message(self.sequence, xml.getvalue()) 

1255 xml.close() 

1256 dbg.writer.add_command(cmd) 

1257 except Exception: 

1258 cmd = dbg.cmd_factory.make_error_message( 

1259 self.sequence, "Error resolving variables %s" % (get_exception_traceback_str(),)) 

1260 dbg.writer.add_command(cmd) 

1261 

1262 

1263#======================================================================================================================= 

1264# InternalGetArray 

1265#======================================================================================================================= 

1266class InternalGetArray(InternalThreadCommand): 

1267 def __init__(self, seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs): 

1268 self.sequence = seq 

1269 self.thread_id = thread_id 

1270 self.frame_id = frame_id 

1271 self.scope = scope 

1272 self.name = attrs.split("\t")[-1] 

1273 self.attrs = attrs 

1274 self.roffset = int(roffset) 

1275 self.coffset = int(coffset) 

1276 self.rows = int(rows) 

1277 self.cols = int(cols) 

1278 self.format = format 

1279 

1280 def do_it(self, dbg): 

1281 try: 

1282 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1283 var = pydevd_vars.eval_in_context(self.name, frame.f_globals, frame.f_locals) 

1284 xml = pydevd_vars.table_like_struct_to_xml(var, self.name, self.roffset, self.coffset, self.rows, self.cols, self.format) 

1285 cmd = dbg.cmd_factory.make_get_array_message(self.sequence, xml) 

1286 dbg.writer.add_command(cmd) 

1287 except: 

1288 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error resolving array: " + get_exception_traceback_str()) 

1289 dbg.writer.add_command(cmd) 

1290 

1291 

1292#======================================================================================================================= 

1293# InternalDataViewerAction 

1294#======================================================================================================================= 

1295class InternalDataViewerAction(InternalThreadCommand): 

1296 def __init__(self, sequence, thread_id, frame_id, var, action, args): 

1297 self.sequence = sequence 

1298 self.thread_id = thread_id 

1299 self.frame_id = frame_id 

1300 self.var = var 

1301 self.action = action 

1302 self.args = args 

1303 

1304 def do_it(self, dbg): 

1305 try: 

1306 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1307 tmp_var = pydevd_vars.eval_in_context(self.var, frame.f_globals, frame.f_locals) 

1308 

1309 self.act(tmp_var, self.action, self.args) 

1310 

1311 cmd = dbg.cmd_factory.make_successful_dataviewer_action_message( 

1312 self.sequence, 

1313 "Successful execution") 

1314 dbg.writer.add_command(cmd) 

1315 

1316 except Exception as e: 

1317 cmd = dbg.cmd_factory.make_error_message( 

1318 self.sequence, 

1319 type(e).__name__ + "\nError exporting frame: " + get_exception_traceback_str()) 

1320 dbg.writer.add_command(cmd) 

1321 

1322 @staticmethod 

1323 def act(tmp_var, action, args): 

1324 if action == 'EXPORT': 

1325 return InternalDataViewerAction.export_action(tmp_var, args) 

1326 

1327 @staticmethod 

1328 def get_type_info(var): 

1329 tp = type(var) 

1330 tp_name = tp.__name__ 

1331 tp_qualifier = getattr(tp, "__module__", "") 

1332 

1333 return tp_qualifier, tp_name 

1334 

1335 @staticmethod 

1336 def export_action(var, args): 

1337 # args: (filepath) 

1338 filepath = args[0] 

1339 extension = filepath.rsplit('.', 1)[1].lower() 

1340 

1341 tp_qualifier, tp_name = InternalDataViewerAction.get_type_info(var) 

1342 

1343 if is_pandas_container(tp_qualifier, tp_name, var): 

1344 if extension in ('csv', 'tsv'): 

1345 delim = ',' if extension == 'csv' else '\t' 

1346 var.to_csv(filepath, sep=delim) 

1347 else: 

1348 raise AttributeError("Format '{}' is not supported".format(extension)) 

1349 

1350 elif is_numpy_container(tp_qualifier, tp_name, var): 

1351 try: 

1352 import numpy as np 

1353 

1354 except ImportError: 

1355 # Strange. We have an instance of numpy array but we failed to import numpy 

1356 raise 

1357 

1358 if extension in ('csv', 'tsv'): 

1359 delim = ',' if extension == 'csv' else '\t' 

1360 np.savetxt(filepath, var, fmt="%s", delimiter=delim) 

1361 else: 

1362 raise AttributeError("Format '{}' is not supported".format(extension)) 

1363 

1364 else: 

1365 raise AttributeError("Type {} is not supported".format(type(var))) 

1366 

1367#======================================================================================================================= 

1368# InternalChangeVariable 

1369#======================================================================================================================= 

1370class InternalChangeVariable(InternalThreadCommand): 

1371 """ changes the value of a variable """ 

1372 def __init__(self, seq, thread_id, frame_id, scope, attr, expression): 

1373 self.sequence = seq 

1374 self.thread_id = thread_id 

1375 self.frame_id = frame_id 

1376 self.scope = scope 

1377 self.attr = attr 

1378 self.expression = expression 

1379 

1380 def do_it(self, dbg): 

1381 """ Converts request into python variable """ 

1382 try: 

1383 result = pydevd_vars.change_attr_expression(self.thread_id, self.frame_id, self.attr, self.expression, dbg) 

1384 xml = "<xml>" 

1385 xml += pydevd_xml.var_to_xml(result, "") 

1386 xml += "</xml>" 

1387 cmd = dbg.cmd_factory.make_variable_changed_message(self.sequence, xml) 

1388 dbg.writer.add_command(cmd) 

1389 except Exception: 

1390 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error changing variable attr:%s expression:%s traceback:%s" % (self.attr, self.expression, get_exception_traceback_str())) 

1391 dbg.writer.add_command(cmd) 

1392 

1393 

1394#======================================================================================================================= 

1395# InternalGetFrame 

1396#======================================================================================================================= 

1397class InternalGetFrame(InternalThreadCommand): 

1398 """ gets the value of a variable """ 

1399 def __init__(self, seq, thread_id, frame_id): 

1400 self.sequence = seq 

1401 self.thread_id = thread_id 

1402 self.frame_id = frame_id 

1403 

1404 def do_it(self, dbg): 

1405 """ Converts request into python variable """ 

1406 try: 

1407 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1408 if frame is not None: 

1409 hidden_ns = pydevd_console_integration.get_ipython_hidden_vars() 

1410 xml = "<xml>" 

1411 xml += pydevd_xml.frame_vars_to_xml(frame.f_locals, hidden_ns) 

1412 del frame 

1413 xml += "</xml>" 

1414 cmd = dbg.cmd_factory.make_get_frame_message(self.sequence, xml) 

1415 dbg.writer.add_command(cmd) 

1416 else: 

1417 #pydevd_vars.dump_frames(self.thread_id) 

1418 #don't print this error: frame not found: means that the client is not synchronized (but that's ok) 

1419 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Frame not found: %s from thread: %s" % (self.frame_id, self.thread_id)) 

1420 dbg.writer.add_command(cmd) 

1421 except: 

1422 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error resolving frame: %s from thread: %s" % (self.frame_id, self.thread_id)) 

1423 dbg.writer.add_command(cmd) 

1424 

1425 

1426class InternalGetSmartStepIntoVariants(InternalThreadCommand): 

1427 def __init__(self, seq, thread_id, frame_id, start_line, end_line): 

1428 self.sequence = seq 

1429 self.thread_id = thread_id 

1430 self.frame_id = frame_id 

1431 self.start_line = int(start_line) 

1432 self.end_line = int(end_line) 

1433 

1434 def do_it(self, dbg): 

1435 try: 

1436 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1437 variants = pydevd_bytecode_utils.calculate_smart_step_into_variants(frame, self.start_line, self.end_line) 

1438 xml = "<xml>" 

1439 

1440 for name, is_visited in variants: 

1441 xml += '<variant name="%s" isVisited="%s"></variant>' % (quote(name), str(is_visited).lower()) 

1442 

1443 xml += "</xml>" 

1444 cmd = NetCommand(CMD_GET_SMART_STEP_INTO_VARIANTS, self.sequence, xml) 

1445 dbg.writer.add_command(cmd) 

1446 except: 

1447 pydevd_log(1, traceback.format_exc()) 

1448 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error getting smart step into veriants for frame: %s from thread: %s" 

1449 % (self.frame_id, self.thread_id)) 

1450 self._reset_smart_step_context() 

1451 dbg.writer.add_command(cmd) 

1452 

1453 def _reset_smart_step_context(self): 

1454 t = pydevd_find_thread_by_id(self.thread_id) 

1455 if t: 

1456 try: 

1457 t.additional_info.pydev_smart_step_context.reset() 

1458 except: 

1459 pydevd_log(1, "Error while resetting smart step into context for thread %s" % self.thread_id) 

1460 

1461 

1462#======================================================================================================================= 

1463# InternalGetNextStatementTargets 

1464#======================================================================================================================= 

1465class InternalGetNextStatementTargets(InternalThreadCommand): 

1466 """ gets the valid line numbers for use with set next statement """ 

1467 def __init__(self, seq, thread_id, frame_id): 

1468 self.sequence = seq 

1469 self.thread_id = thread_id 

1470 self.frame_id = frame_id 

1471 

1472 def do_it(self, dbg): 

1473 """ Converts request into set of line numbers """ 

1474 try: 

1475 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1476 if frame is not None: 

1477 code = frame.f_code 

1478 xml = "<xml>" 

1479 if hasattr(code, 'co_lnotab'): 

1480 lineno = code.co_firstlineno 

1481 lnotab = code.co_lnotab 

1482 for i in itertools.islice(lnotab, 1, len(lnotab), 2): 

1483 if isinstance(i, int): 

1484 lineno = lineno + i 

1485 else: 

1486 # in python 2 elements in co_lnotab are of type str 

1487 lineno = lineno + ord(i) 

1488 xml += "<line>%d</line>" % (lineno,) 

1489 else: 

1490 xml += "<line>%d</line>" % (frame.f_lineno,) 

1491 del frame 

1492 xml += "</xml>" 

1493 cmd = dbg.cmd_factory.make_get_next_statement_targets_message(self.sequence, xml) 

1494 dbg.writer.add_command(cmd) 

1495 else: 

1496 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Frame not found: %s from thread: %s" % (self.frame_id, self.thread_id)) 

1497 dbg.writer.add_command(cmd) 

1498 except: 

1499 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error resolving frame: %s from thread: %s" % (self.frame_id, self.thread_id)) 

1500 dbg.writer.add_command(cmd) 

1501 

1502#======================================================================================================================= 

1503# InternalEvaluateExpression 

1504#======================================================================================================================= 

1505class InternalEvaluateExpression(InternalThreadCommand): 

1506 """ gets the value of a variable """ 

1507 

1508 def __init__(self, seq, thread_id, frame_id, expression, doExec, doTrim, temp_name): 

1509 self.sequence = seq 

1510 self.thread_id = thread_id 

1511 self.frame_id = frame_id 

1512 self.expression = expression 

1513 self.doExec = doExec 

1514 self.doTrim = doTrim 

1515 self.temp_name = temp_name 

1516 

1517 def do_it(self, dbg): 

1518 """ Converts request into python variable """ 

1519 try: 

1520 result = pydevd_vars.evaluate_expression(self.thread_id, self.frame_id, self.expression, self.doExec) 

1521 if self.temp_name != "": 

1522 pydevd_vars.change_attr_expression(self.thread_id, self.frame_id, self.temp_name, self.expression, dbg, result) 

1523 xml = "<xml>" 

1524 xml += pydevd_xml.var_to_xml(result, self.expression, self.doTrim) 

1525 xml += "</xml>" 

1526 cmd = dbg.cmd_factory.make_evaluate_expression_message(self.sequence, xml) 

1527 dbg.writer.add_command(cmd) 

1528 except: 

1529 exc = get_exception_traceback_str() 

1530 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating expression " + exc) 

1531 dbg.writer.add_command(cmd) 

1532 

1533#======================================================================================================================= 

1534# InternalGetCompletions 

1535#======================================================================================================================= 

1536class InternalGetCompletions(InternalThreadCommand): 

1537 """ Gets the completions in a given scope """ 

1538 

1539 def __init__(self, seq, thread_id, frame_id, act_tok): 

1540 self.sequence = seq 

1541 self.thread_id = thread_id 

1542 self.frame_id = frame_id 

1543 self.act_tok = act_tok 

1544 

1545 

1546 def do_it(self, dbg): 

1547 """ Converts request into completions """ 

1548 try: 

1549 remove_path = None 

1550 try: 

1551 

1552 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1553 if frame is not None: 

1554 

1555 msg = _pydev_completer.generate_completions_as_xml(frame, self.act_tok) 

1556 

1557 cmd = dbg.cmd_factory.make_get_completions_message(self.sequence, msg) 

1558 dbg.writer.add_command(cmd) 

1559 else: 

1560 cmd = dbg.cmd_factory.make_error_message(self.sequence, "InternalGetCompletions: Frame not found: %s from thread: %s" % (self.frame_id, self.thread_id)) 

1561 dbg.writer.add_command(cmd) 

1562 

1563 

1564 finally: 

1565 if remove_path is not None: 

1566 sys.path.remove(remove_path) 

1567 

1568 except: 

1569 exc = get_exception_traceback_str() 

1570 sys.stderr.write('%s\n' % (exc,)) 

1571 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating expression " + exc) 

1572 dbg.writer.add_command(cmd) 

1573 

1574 

1575# ======================================================================================================================= 

1576# InternalGetDescription 

1577# ======================================================================================================================= 

1578class InternalGetDescription(InternalThreadCommand): 

1579 """ Fetch the variable description stub from the debug console 

1580 """ 

1581 

1582 def __init__(self, seq, thread_id, frame_id, expression): 

1583 self.sequence = seq 

1584 self.thread_id = thread_id 

1585 self.frame_id = frame_id 

1586 self.expression = expression 

1587 

1588 def do_it(self, dbg): 

1589 """ Get completions and write back to the client 

1590 """ 

1591 try: 

1592 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1593 description = pydevd_console.get_description(frame, self.thread_id, self.frame_id, self.expression) 

1594 description = pydevd_xml.make_valid_xml_value(quote(description, '/>_= \t')) 

1595 description_xml = '<xml><var name="" type="" value="%s"/></xml>' % description 

1596 cmd = dbg.cmd_factory.make_get_description_message(self.sequence, description_xml) 

1597 dbg.writer.add_command(cmd) 

1598 except: 

1599 exc = get_exception_traceback_str() 

1600 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error in fetching description" + exc) 

1601 dbg.writer.add_command(cmd) 

1602 

1603 

1604#======================================================================================================================= 

1605# InternalGetBreakpointException 

1606#======================================================================================================================= 

1607class InternalGetBreakpointException(InternalThreadCommand): 

1608 """ Send details of exception raised while evaluating conditional breakpoint """ 

1609 def __init__(self, thread_id, exc_type, stacktrace): 

1610 self.sequence = 0 

1611 self.thread_id = thread_id 

1612 self.stacktrace = stacktrace 

1613 self.exc_type = exc_type 

1614 

1615 def do_it(self, dbg): 

1616 try: 

1617 callstack = "<xml>" 

1618 

1619 makeValid = pydevd_xml.make_valid_xml_value 

1620 

1621 for filename, line, methodname, methodobj in self.stacktrace: 

1622 if file_system_encoding.lower() != "utf-8" and hasattr(filename, "decode"): 

1623 # filename is a byte string encoded using the file system encoding 

1624 # convert it to utf8 

1625 filename = filename.decode(file_system_encoding).encode("utf-8") 

1626 

1627 callstack += '<frame thread_id = "%s" file="%s" line="%s" name="%s" obj="%s" />' \ 

1628 % (self.thread_id, makeValid(filename), line, makeValid(methodname), makeValid(methodobj)) 

1629 callstack += "</xml>" 

1630 

1631 cmd = dbg.cmd_factory.make_send_breakpoint_exception_message(self.sequence, self.exc_type + "\t" + callstack) 

1632 dbg.writer.add_command(cmd) 

1633 except: 

1634 exc = get_exception_traceback_str() 

1635 sys.stderr.write('%s\n' % (exc,)) 

1636 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Exception: " + exc) 

1637 dbg.writer.add_command(cmd) 

1638 

1639 

1640#======================================================================================================================= 

1641# InternalSendCurrExceptionTrace 

1642#======================================================================================================================= 

1643class InternalSendCurrExceptionTrace(InternalThreadCommand): 

1644 """ Send details of the exception that was caught and where we've broken in. 

1645 """ 

1646 def __init__(self, thread_id, arg, curr_frame_id): 

1647 ''' 

1648 :param arg: exception type, description, traceback object 

1649 ''' 

1650 self.sequence = 0 

1651 self.thread_id = thread_id 

1652 self.curr_frame_id = curr_frame_id 

1653 self.arg = arg 

1654 

1655 def do_it(self, dbg): 

1656 try: 

1657 cmd = dbg.cmd_factory.make_send_curr_exception_trace_message(self.sequence, self.thread_id, self.curr_frame_id, *self.arg) 

1658 del self.arg 

1659 dbg.writer.add_command(cmd) 

1660 except: 

1661 exc = get_exception_traceback_str() 

1662 sys.stderr.write('%s\n' % (exc,)) 

1663 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Current Exception Trace: " + exc) 

1664 dbg.writer.add_command(cmd) 

1665 

1666#======================================================================================================================= 

1667# InternalSendCurrExceptionTraceProceeded 

1668#======================================================================================================================= 

1669class InternalSendCurrExceptionTraceProceeded(InternalThreadCommand): 

1670 """ Send details of the exception that was caught and where we've broken in. 

1671 """ 

1672 def __init__(self, thread_id): 

1673 self.sequence = 0 

1674 self.thread_id = thread_id 

1675 

1676 def do_it(self, dbg): 

1677 try: 

1678 cmd = dbg.cmd_factory.make_send_curr_exception_trace_proceeded_message(self.sequence, self.thread_id) 

1679 dbg.writer.add_command(cmd) 

1680 except: 

1681 exc = get_exception_traceback_str() 

1682 sys.stderr.write('%s\n' % (exc,)) 

1683 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Current Exception Trace Proceeded: " + exc) 

1684 dbg.writer.add_command(cmd) 

1685 

1686 

1687#======================================================================================================================= 

1688# InternalEvaluateConsoleExpression 

1689#======================================================================================================================= 

1690class InternalEvaluateConsoleExpression(InternalThreadCommand): 

1691 """ Execute the given command in the debug console """ 

1692 

1693 def __init__(self, seq, thread_id, frame_id, line, buffer_output=True): 

1694 self.sequence = seq 

1695 self.thread_id = thread_id 

1696 self.frame_id = frame_id 

1697 self.line = line 

1698 self.buffer_output = buffer_output 

1699 

1700 def do_it(self, dbg): 

1701 """ Create an XML for console output, error and more (true/false) 

1702 <xml> 

1703 <output message=output_message></output> 

1704 <error message=error_message></error> 

1705 <more>true/false</more> 

1706 </xml> 

1707 """ 

1708 try: 

1709 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1710 if frame is not None: 

1711 console_message = pydevd_console.execute_console_command( 

1712 frame, self.thread_id, self.frame_id, self.line, self.buffer_output) 

1713 

1714 cmd = dbg.cmd_factory.make_send_console_message(self.sequence, console_message.to_xml()) 

1715 else: 

1716 from _pydevd_bundle.pydevd_console import ConsoleMessage 

1717 console_message = ConsoleMessage() 

1718 console_message.add_console_message( 

1719 pydevd_console.CONSOLE_ERROR, 

1720 "Select the valid frame in the debug view (thread: %s, frame: %s invalid)" % (self.thread_id, self.frame_id), 

1721 ) 

1722 cmd = dbg.cmd_factory.make_error_message(self.sequence, console_message.to_xml()) 

1723 except: 

1724 exc = get_exception_traceback_str() 

1725 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating expression " + exc) 

1726 dbg.writer.add_command(cmd) 

1727 

1728 

1729#======================================================================================================================= 

1730# InternalRunCustomOperation 

1731#======================================================================================================================= 

1732class InternalRunCustomOperation(InternalThreadCommand): 

1733 """ Run a custom command on an expression 

1734 """ 

1735 def __init__(self, seq, thread_id, frame_id, scope, attrs, style, encoded_code_or_file, fnname): 

1736 self.sequence = seq 

1737 self.thread_id = thread_id 

1738 self.frame_id = frame_id 

1739 self.scope = scope 

1740 self.attrs = attrs 

1741 self.style = style 

1742 self.code_or_file = unquote_plus(encoded_code_or_file) 

1743 self.fnname = fnname 

1744 

1745 def do_it(self, dbg): 

1746 try: 

1747 res = pydevd_vars.custom_operation(self.thread_id, self.frame_id, self.scope, self.attrs, 

1748 self.style, self.code_or_file, self.fnname) 

1749 resEncoded = quote_plus(res) 

1750 cmd = dbg.cmd_factory.make_custom_operation_message(self.sequence, resEncoded) 

1751 dbg.writer.add_command(cmd) 

1752 except: 

1753 exc = get_exception_traceback_str() 

1754 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error in running custom operation" + exc) 

1755 dbg.writer.add_command(cmd) 

1756 

1757 

1758#======================================================================================================================= 

1759# InternalConsoleGetCompletions 

1760#======================================================================================================================= 

1761class InternalConsoleGetCompletions(InternalThreadCommand): 

1762 """ Fetch the completions in the debug console 

1763 """ 

1764 def __init__(self, seq, thread_id, frame_id, act_tok): 

1765 self.sequence = seq 

1766 self.thread_id = thread_id 

1767 self.frame_id = frame_id 

1768 self.act_tok = act_tok 

1769 

1770 def do_it(self, dbg): 

1771 """ Get completions and write back to the client 

1772 """ 

1773 try: 

1774 frame = pydevd_vars.find_frame(self.thread_id, self.frame_id) 

1775 completions_xml = pydevd_console.get_completions(frame, self.act_tok) 

1776 cmd = dbg.cmd_factory.make_send_console_message(self.sequence, completions_xml) 

1777 dbg.writer.add_command(cmd) 

1778 except: 

1779 exc = get_exception_traceback_str() 

1780 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error in fetching completions" + exc) 

1781 dbg.writer.add_command(cmd) 

1782 

1783 

1784#======================================================================================================================= 

1785# InternalConsoleExec 

1786#======================================================================================================================= 

1787class InternalConsoleExec(InternalThreadCommand): 

1788 """ gets the value of a variable """ 

1789 

1790 def __init__(self, seq, thread_id, frame_id, expression): 

1791 self.sequence = seq 

1792 self.thread_id = thread_id 

1793 self.frame_id = frame_id 

1794 self.expression = expression 

1795 

1796 def do_it(self, dbg): 

1797 """ Converts request into python variable """ 

1798 try: 

1799 try: 

1800 #don't trace new threads created by console command 

1801 disable_trace_thread_modules() 

1802 

1803 result = pydevd_console_integration.console_exec(self.thread_id, self.frame_id, self.expression, dbg) 

1804 xml = "<xml>" 

1805 xml += pydevd_xml.var_to_xml(result, "") 

1806 xml += "</xml>" 

1807 cmd = dbg.cmd_factory.make_evaluate_expression_message(self.sequence, xml) 

1808 dbg.writer.add_command(cmd) 

1809 except: 

1810 exc = get_exception_traceback_str() 

1811 sys.stderr.write('%s\n' % (exc,)) 

1812 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating console expression " + exc) 

1813 dbg.writer.add_command(cmd) 

1814 finally: 

1815 enable_trace_thread_modules() 

1816 

1817 sys.stderr.flush() 

1818 sys.stdout.flush() 

1819 

1820 

1821#======================================================================================================================= 

1822# InternalLoadFullValue 

1823#======================================================================================================================= 

1824class InternalLoadFullValue(InternalThreadCommand): 

1825 """ 

1826 Loads values asynchronously 

1827 """ 

1828 def __init__(self, seq, thread_id, frame_id, vars): 

1829 self.sequence = seq 

1830 self.thread_id = thread_id 

1831 self.frame_id = frame_id 

1832 self.vars = vars 

1833 

1834 def do_it(self, dbg): 

1835 """Starts a thread that will load values asynchronously""" 

1836 try: 

1837 var_objects = [] 

1838 for variable in self.vars: 

1839 variable = variable.strip() 

1840 if len(variable) > 0: 

1841 if '\t' in variable: # there are attributes beyond scope 

1842 scope, attrs = variable.split('\t', 1) 

1843 name = attrs[0] 

1844 else: 

1845 scope, attrs = (variable, None) 

1846 name = scope 

1847 var_obj = pydevd_vars.getVariable(self.thread_id, self.frame_id, scope, attrs) 

1848 var_objects.append((var_obj, name)) 

1849 

1850 t = GetValueAsyncThreadDebug(dbg, self.sequence, var_objects) 

1851 t.start() 

1852 except: 

1853 exc = get_exception_traceback_str() 

1854 sys.stderr.write('%s\n' % (exc,)) 

1855 cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating variable %s " % exc) 

1856 dbg.writer.add_command(cmd) 

1857 

1858 

1859class AbstractGetValueAsyncThread(PyDBDaemonThread): 

1860 """ 

1861 Abstract class for a thread, which evaluates values for async variables 

1862 """ 

1863 def __init__(self, frame_accessor, seq, var_objects): 

1864 PyDBDaemonThread.__init__(self) 

1865 self.frame_accessor = frame_accessor 

1866 self.seq = seq 

1867 self.var_objs = var_objects 

1868 self.cancel_event = threading.Event() 

1869 

1870 def send_result(self, xml): 

1871 raise NotImplementedError() 

1872 

1873 @overrides(PyDBDaemonThread._on_run) 

1874 def _on_run(self): 

1875 start = time.time() 

1876 xml = StringIO.StringIO() 

1877 xml.write("<xml>") 

1878 for (var_obj, name) in self.var_objs: 

1879 current_time = time.time() 

1880 if current_time - start > ASYNC_EVAL_TIMEOUT_SEC or self.cancel_event.is_set(): 

1881 break 

1882 xml.write(pydevd_xml.var_to_xml(var_obj, name, evaluate_full_value=True)) 

1883 xml.write("</xml>") 

1884 self.send_result(xml) 

1885 xml.close() 

1886 

1887 

1888class GetValueAsyncThreadDebug(AbstractGetValueAsyncThread): 

1889 """ 

1890 A thread for evaluation async values, which returns result for debugger 

1891 Create message and send it via writer thread 

1892 """ 

1893 def send_result(self, xml): 

1894 if self.frame_accessor is not None: 

1895 cmd = self.frame_accessor.cmd_factory.make_load_full_value_message(self.seq, xml.getvalue()) 

1896 self.frame_accessor.writer.add_command(cmd) 

1897 

1898 

1899class GetValueAsyncThreadConsole(AbstractGetValueAsyncThread): 

1900 """ 

1901 A thread for evaluation async values, which returns result for Console 

1902 Send result directly to Console's server 

1903 """ 

1904 def send_result(self, xml): 

1905 if self.frame_accessor is not None: 

1906 self.frame_accessor.ReturnFullValue(self.seq, xml.getvalue()) 

1907 

1908 

1909#======================================================================================================================= 

1910# pydevd_find_thread_by_id 

1911#======================================================================================================================= 

1912def pydevd_find_thread_by_id(thread_id): 

1913 try: 

1914 # there was a deadlock here when I did not remove the tracing function when thread was dead 

1915 threads = threading.enumerate() 

1916 for i in threads: 

1917 tid = get_thread_id(i) 

1918 if thread_id == tid or thread_id.endswith('|' + tid): 

1919 return i 

1920 

1921 # This can happen when a request comes for a thread which was previously removed. 

1922 pydevd_log(1, "Could not find thread %s\n" % thread_id) 

1923 pydevd_log(1, "Available: %s\n" % [get_thread_id(t) for t in threads]) 

1924 except: 

1925 traceback.print_exc() 

1926 

1927 return None