10 import sys |
10 import sys |
11 import bdb |
11 import bdb |
12 import os |
12 import os |
13 import atexit |
13 import atexit |
14 import inspect |
14 import inspect |
|
15 from inspect import CO_GENERATOR |
15 |
16 |
16 from DebugProtocol import ResponseClearWatch, ResponseClearBreak, \ |
17 from DebugProtocol import ResponseClearWatch, ResponseClearBreak, \ |
17 ResponseLine, ResponseSyntax, ResponseException, CallTrace |
18 ResponseLine, ResponseSyntax, ResponseException, CallTrace |
18 |
19 |
19 gRecursionLimit = 64 |
20 gRecursionLimit = 64 |
263 @param arg The arguments |
264 @param arg The arguments |
264 @return local trace function |
265 @return local trace function |
265 @exception bdb.BdbQuit raised to indicate the end of the debug session |
266 @exception bdb.BdbQuit raised to indicate the end of the debug session |
266 """ |
267 """ |
267 if self.stop_here(frame) or frame == self.returnframe: |
268 if self.stop_here(frame) or frame == self.returnframe: |
|
269 # Ignore return events in generator except when stepping. |
|
270 if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: |
|
271 return self.trace_dispatch |
268 self.user_return(frame, arg) |
272 self.user_return(frame, arg) |
269 if self.quitting and not self._dbgClient.passive: |
273 if self.quitting and not self._dbgClient.passive: |
270 raise bdb.BdbQuit |
274 raise bdb.BdbQuit |
271 return self.trace_dispatch |
275 return self.trace_dispatch |
272 |
276 |
278 @param arg The arguments |
282 @param arg The arguments |
279 @return local trace function |
283 @return local trace function |
280 @exception bdb.BdbQuit raised to indicate the end of the debug session |
284 @exception bdb.BdbQuit raised to indicate the end of the debug session |
281 """ |
285 """ |
282 if not self.__skip_it(frame): |
286 if not self.__skip_it(frame): |
|
287 # When stepping with next/until/return in a generator frame, |
|
288 # skip the internal StopIteration exception (with no traceback) |
|
289 # triggered by a subiterator run with the 'yield from' |
|
290 # statement. |
|
291 if not (frame.f_code.co_flags & CO_GENERATOR |
|
292 and arg[0] is StopIteration and arg[2] is None): |
|
293 self.user_exception(frame, arg) |
|
294 if self.quitting: |
|
295 raise bdb.BdbQuit |
|
296 # Stop at the StopIteration or GeneratorExit exception when the user |
|
297 # has set stopframe in a generator by issuing a return command, or a |
|
298 # next/until command at the last statement in the generator before the |
|
299 # exception. |
|
300 elif (self.stopframe and frame is not self.stopframe |
|
301 and self.stopframe.f_code.co_flags & CO_GENERATOR |
|
302 and arg[0] in (StopIteration, GeneratorExit)): |
283 self.user_exception(frame, arg) |
303 self.user_exception(frame, arg) |
284 if self.quitting: |
304 if self.quitting: |
285 raise bdb.BdbQuit |
305 raise bdb.BdbQuit |
|
306 |
286 return self.trace_dispatch |
307 return self.trace_dispatch |
287 |
308 |
288 def set_trace(self, frame=None): |
309 def set_trace(self, frame=None): |
289 """ |
310 """ |
290 Public method reimplemented from bdb.py to do some special setup. |
311 Public method reimplemented from bdb.py to do some special setup. |