mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
bpo-32591: Add native coroutine origin tracking (#5250)
* Add coro.cr_origin and sys.set_coroutine_origin_tracking_depth * Use coroutine origin information in the unawaited coroutine warning * Stop using set_coroutine_wrapper in asyncio debug mode * In BaseEventLoop.set_debug, enable debugging in the correct thread
This commit is contained in:
parent
1211c9a989
commit
fc2f407829
20 changed files with 485 additions and 100 deletions
|
@ -34,6 +34,7 @@ try:
|
|||
except ImportError: # pragma: no cover
|
||||
ssl = None
|
||||
|
||||
from . import constants
|
||||
from . import coroutines
|
||||
from . import events
|
||||
from . import futures
|
||||
|
@ -224,7 +225,8 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
self.slow_callback_duration = 0.1
|
||||
self._current_handle = None
|
||||
self._task_factory = None
|
||||
self._coroutine_wrapper_set = False
|
||||
self._coroutine_origin_tracking_enabled = False
|
||||
self._coroutine_origin_tracking_saved_depth = None
|
||||
|
||||
if hasattr(sys, 'get_asyncgen_hooks'):
|
||||
# Python >= 3.6
|
||||
|
@ -382,7 +384,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
if events._get_running_loop() is not None:
|
||||
raise RuntimeError(
|
||||
'Cannot run the event loop while another loop is running')
|
||||
self._set_coroutine_wrapper(self._debug)
|
||||
self._set_coroutine_origin_tracking(self._debug)
|
||||
self._thread_id = threading.get_ident()
|
||||
if self._asyncgens is not None:
|
||||
old_agen_hooks = sys.get_asyncgen_hooks()
|
||||
|
@ -398,7 +400,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
self._stopping = False
|
||||
self._thread_id = None
|
||||
events._set_running_loop(None)
|
||||
self._set_coroutine_wrapper(False)
|
||||
self._set_coroutine_origin_tracking(False)
|
||||
if self._asyncgens is not None:
|
||||
sys.set_asyncgen_hooks(*old_agen_hooks)
|
||||
|
||||
|
@ -1531,39 +1533,20 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
handle._run()
|
||||
handle = None # Needed to break cycles when an exception occurs.
|
||||
|
||||
def _set_coroutine_wrapper(self, enabled):
|
||||
try:
|
||||
set_wrapper = sys.set_coroutine_wrapper
|
||||
get_wrapper = sys.get_coroutine_wrapper
|
||||
except AttributeError:
|
||||
def _set_coroutine_origin_tracking(self, enabled):
|
||||
if bool(enabled) == bool(self._coroutine_origin_tracking_enabled):
|
||||
return
|
||||
|
||||
enabled = bool(enabled)
|
||||
if self._coroutine_wrapper_set == enabled:
|
||||
return
|
||||
|
||||
wrapper = coroutines.debug_wrapper
|
||||
current_wrapper = get_wrapper()
|
||||
|
||||
if enabled:
|
||||
if current_wrapper not in (None, wrapper):
|
||||
warnings.warn(
|
||||
f"loop.set_debug(True): cannot set debug coroutine "
|
||||
f"wrapper; another wrapper is already set "
|
||||
f"{current_wrapper!r}",
|
||||
RuntimeWarning)
|
||||
else:
|
||||
set_wrapper(wrapper)
|
||||
self._coroutine_wrapper_set = True
|
||||
self._coroutine_origin_tracking_saved_depth = (
|
||||
sys.get_coroutine_origin_tracking_depth())
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
constants.DEBUG_STACK_DEPTH)
|
||||
else:
|
||||
if current_wrapper not in (None, wrapper):
|
||||
warnings.warn(
|
||||
f"loop.set_debug(False): cannot unset debug coroutine "
|
||||
f"wrapper; another wrapper was set {current_wrapper!r}",
|
||||
RuntimeWarning)
|
||||
else:
|
||||
set_wrapper(None)
|
||||
self._coroutine_wrapper_set = False
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
self._coroutine_origin_tracking_saved_depth)
|
||||
|
||||
self._coroutine_origin_tracking_enabled = enabled
|
||||
|
||||
def get_debug(self):
|
||||
return self._debug
|
||||
|
@ -1572,4 +1555,4 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
self._debug = enabled
|
||||
|
||||
if self.is_running():
|
||||
self._set_coroutine_wrapper(enabled)
|
||||
self.call_soon_threadsafe(self._set_coroutine_origin_tracking, enabled)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue