1
1
from __future__ import annotations
2
2
3
- import copy
4
3
import sys
5
4
from collections import OrderedDict
6
5
from contextlib import asynccontextmanager
@@ -152,14 +151,14 @@ async def open_websocket(
152
151
# yield to user code. If only one of those raise a non-cancelled exception
153
152
# we will raise that non-cancelled exception.
154
153
# If we get multiple cancelled, we raise the user's cancelled.
155
- # If both raise exceptions, we raise the user code's exception with the entire
156
- # exception group as the __cause__.
154
+ # If both raise exceptions, we raise the user code's exception with __context__
155
+ # set to a group containing internal exception(s) + any user exception __context__
157
156
# If we somehow get multiple exceptions, but no user exception, then we raise
158
157
# TrioWebsocketInternalError.
159
158
160
159
# If closing the connection fails, then that will be raised as the top
161
160
# exception in the last `finally`. If we encountered exceptions in user code
162
- # or in reader task then they will be set as the `__cause__ `.
161
+ # or in reader task then they will be set as the `__context__ `.
163
162
164
163
165
164
async def _open_connection (nursery : trio .Nursery ) -> WebSocketConnection :
@@ -183,6 +182,8 @@ async def _close_connection(connection: WebSocketConnection) -> None:
183
182
raise DisconnectionTimeout from None
184
183
185
184
def _raise (exc : BaseException ) -> NoReturn :
185
+ """This helper allows re-raising an exception without __context__ being set."""
186
+ # cause does not need special handlng, we simply avoid using `raise .. from ..`
186
187
__tracebackhide__ = True
187
188
context = exc .__context__
188
189
try :
@@ -199,11 +200,7 @@ def _raise(exc: BaseException) -> NoReturn:
199
200
# the exception we raise also being inside the group that's set as the context.
200
201
# This leads to loss of info unless properly handled.
201
202
# See https://github.com/python-trio/flake8-async/issues/298
202
- # We therefore save the exception before raising it, and save our intended context,
203
- # so they can be modified in the `finally`.
204
- exc_to_raise = None
205
- exc_context = None
206
- # by avoiding use of `raise .. from ..` we leave the original __cause__
203
+ # We therefore avoid having the exceptiongroup included as either cause or context
207
204
208
205
try :
209
206
async with trio .open_nursery () as new_nursery :
@@ -243,7 +240,7 @@ def _raise(exc: BaseException) -> NoReturn:
243
240
_raise (user_error )
244
241
# multiple internal Cancelled is not possible afaik
245
242
# but if so we just raise one of them
246
- _raise (e .exceptions [0 ])
243
+ _raise (e .exceptions [0 ]) # pragma: no cover
247
244
# raise the non-cancelled exception
248
245
_raise (exception_to_raise )
249
246
0 commit comments