在这里可以接受抑制 `asyncio.CancelledError` 吗?

Is suppressing `asyncio.CancelledError` acceptable here?

示例:

    with suppress(asyncio.CancelledError):
        [await t for t in asyncio.all_tasks(loop=self.loop)
            if t is not asyncio.current_task()]

为了避免 Task was destroyed but it is pending! 警告,我必须在取消后等待任务,但等待它们会导致终端被垃圾邮件发送 CancelledError。我知道它已取消,但我不需要看到它。

这里使用 contextlib.suppress 是否会对取消产生负面影响?我可以避免看到取消的错误(或没有等待的任务被破坏警告)的唯一其他方法是使用 asyncio.wait 而不是 asyncio.gather 开始我的初始任务。出于某种原因,wait 似乎抑制了异常。我在 wait 上使用 return_when=asyncio.FIRST_EXCEPTION,在 gather 上使用 return_exceptions=True。但似乎无论我如何设置他们的关键字参数,gather 都会打印异常,而 wait 不会。

CancelledError 在 asyncio 中用于两个目的:一个是发出取消信号 request - 那是你在协程中得到的那个被取消 - 另一个是发出取消 response 的信号 - 这就是您在等待任务的协程中获得的信号。抑制取消请求是一个坏主意,因为它会使协程不响应取消,从而导致以后出现问题。但是抑制响应是完全没问题的,因为您可能希望在不传播异常的情况下等待已取消的协程(例如,避免出现此警告)。

请注意,您的操作方式看起来不太正确,因为列表理解将在 firstCancelledError 终止,因此您不会等待其他协程。正确的方法是将 suppress 放在循环中,例如:

for t in tasks:
    with contextlib.suppress(asyncio.CancelledError):
        await t

# or, simpler:
await asyncio.gather(*tasks, return_exceptions=True)

wait() 不会传播异常,因为它 returns 组 futures 而不是它们的结果。如果您尝试访问返回的期货的结果,您会得到异常。 gather(return_exceptions=True) returns 结果和异常的混合体,不应引发任何问题。如果是,请编辑问题以提供最小示例。