Unverified Kaydet (Commit) 3cfb84c6 authored tarafından Andrew Svetlov's avatar Andrew Svetlov Kaydeden (comit) GitHub

[3.6] bpo-32650 Add support for async generators and more test for coroutines in…

[3.6] bpo-32650 Add support for async generators and more test for coroutines in pdb  (GH-5403). (#5411)

(cherry picked from commit c7ab581d)
üst 543ec005
...@@ -3,10 +3,13 @@ ...@@ -3,10 +3,13 @@
import fnmatch import fnmatch
import sys import sys
import os import os
from inspect import CO_GENERATOR, CO_COROUTINE from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
__all__ = ["BdbQuit", "Bdb", "Breakpoint"] __all__ = ["BdbQuit", "Bdb", "Breakpoint"]
GENERATOR_AND_COROUTINE_FLAGS = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR
class BdbQuit(Exception): class BdbQuit(Exception):
"""Exception to give up completely.""" """Exception to give up completely."""
...@@ -77,7 +80,7 @@ class Bdb: ...@@ -77,7 +80,7 @@ class Bdb:
# No need to trace this function # No need to trace this function
return # None return # None
# Ignore call events in generator except when stepping. # Ignore call events in generator except when stepping.
if self.stopframe and frame.f_code.co_flags & (CO_GENERATOR | CO_COROUTINE): if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
return self.trace_dispatch return self.trace_dispatch
self.user_call(frame, arg) self.user_call(frame, arg)
if self.quitting: raise BdbQuit if self.quitting: raise BdbQuit
...@@ -86,7 +89,7 @@ class Bdb: ...@@ -86,7 +89,7 @@ class Bdb:
def dispatch_return(self, frame, arg): def dispatch_return(self, frame, arg):
if self.stop_here(frame) or frame == self.returnframe: if self.stop_here(frame) or frame == self.returnframe:
# Ignore return events in generator except when stepping. # Ignore return events in generator except when stepping.
if self.stopframe and frame.f_code.co_flags & (CO_GENERATOR | CO_COROUTINE): if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
return self.trace_dispatch return self.trace_dispatch
try: try:
self.frame_returning = frame self.frame_returning = frame
...@@ -104,7 +107,7 @@ class Bdb: ...@@ -104,7 +107,7 @@ class Bdb:
# When stepping with next/until/return in a generator frame, skip # When stepping with next/until/return in a generator frame, skip
# the internal StopIteration exception (with no traceback) # the internal StopIteration exception (with no traceback)
# triggered by a subiterator run with the 'yield from' statement. # triggered by a subiterator run with the 'yield from' statement.
if not (frame.f_code.co_flags & (CO_GENERATOR | CO_COROUTINE) if not (frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
and arg[0] is StopIteration and arg[2] is None): and arg[0] is StopIteration and arg[2] is None):
self.user_exception(frame, arg) self.user_exception(frame, arg)
if self.quitting: raise BdbQuit if self.quitting: raise BdbQuit
...@@ -113,7 +116,7 @@ class Bdb: ...@@ -113,7 +116,7 @@ class Bdb:
# next/until command at the last statement in the generator before the # next/until command at the last statement in the generator before the
# exception. # exception.
elif (self.stopframe and frame is not self.stopframe elif (self.stopframe and frame is not self.stopframe
and self.stopframe.f_code.co_flags & (CO_GENERATOR | CO_COROUTINE) and self.stopframe.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
and arg[0] in (StopIteration, GeneratorExit)): and arg[0] in (StopIteration, GeneratorExit)):
self.user_exception(frame, arg) self.user_exception(frame, arg)
if self.quitting: raise BdbQuit if self.quitting: raise BdbQuit
...@@ -230,7 +233,7 @@ class Bdb: ...@@ -230,7 +233,7 @@ class Bdb:
def set_return(self, frame): def set_return(self, frame):
"""Stop when returning from the given frame.""" """Stop when returning from the given frame."""
if frame.f_code.co_flags & (CO_GENERATOR | CO_COROUTINE): if frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
self._set_stopinfo(frame, None, -1) self._set_stopinfo(frame, None, -1)
else: else:
self._set_stopinfo(frame.f_back, frame) self._set_stopinfo(frame.f_back, frame)
......
...@@ -739,7 +739,7 @@ def test_pdb_next_command_for_coroutine(): ...@@ -739,7 +739,7 @@ def test_pdb_next_command_for_coroutine():
... await test_coro() ... await test_coro()
>>> def test_function(): >>> def test_function():
... loop = asyncio.get_event_loop() ... loop = asyncio.new_event_loop()
... loop.run_until_complete(test_main()) ... loop.run_until_complete(test_main())
... loop.close() ... loop.close()
... print("finished") ... print("finished")
...@@ -834,6 +834,47 @@ def test_pdb_return_command_for_generator(): ...@@ -834,6 +834,47 @@ def test_pdb_return_command_for_generator():
finished finished
""" """
def test_pdb_return_command_for_coroutine():
"""Testing no unwindng stack on yield for coroutines for "return" command
>>> import asyncio
>>> async def test_coro():
... await asyncio.sleep(0)
... await asyncio.sleep(0)
... await asyncio.sleep(0)
>>> async def test_main():
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
... await test_coro()
>>> def test_function():
... loop = asyncio.new_event_loop()
... loop.run_until_complete(test_main())
... loop.close()
... print("finished")
>>> with PdbTestInput(['step',
... 'step',
... 'next',
... 'continue']):
... test_function()
> <doctest test.test_pdb.test_pdb_return_command_for_coroutine[2]>(3)test_main()
-> await test_coro()
(Pdb) step
--Call--
> <doctest test.test_pdb.test_pdb_return_command_for_coroutine[1]>(1)test_coro()
-> async def test_coro():
(Pdb) step
> <doctest test.test_pdb.test_pdb_return_command_for_coroutine[1]>(2)test_coro()
-> await asyncio.sleep(0)
(Pdb) next
> <doctest test.test_pdb.test_pdb_return_command_for_coroutine[1]>(3)test_coro()
-> await asyncio.sleep(0)
(Pdb) continue
finished
"""
def test_pdb_until_command_for_generator(): def test_pdb_until_command_for_generator():
"""Testing no unwindng stack on yield for generators """Testing no unwindng stack on yield for generators
for "until" command if target breakpoing is not reached for "until" command if target breakpoing is not reached
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment