(self, et, exc)
| 81 | exc = None |
| 82 | |
| 83 | async def _aexit(self, et, exc): |
| 84 | self._exiting = True |
| 85 | |
| 86 | if (exc is not None and |
| 87 | self._is_base_error(exc) and |
| 88 | self._base_error is None): |
| 89 | self._base_error = exc |
| 90 | |
| 91 | if et is not None and issubclass(et, exceptions.CancelledError): |
| 92 | propagate_cancellation_error = exc |
| 93 | else: |
| 94 | propagate_cancellation_error = None |
| 95 | |
| 96 | if et is not None: |
| 97 | if not self._aborting: |
| 98 | # Our parent task is being cancelled: |
| 99 | # |
| 100 | # async with TaskGroup() as g: |
| 101 | # g.create_task(...) |
| 102 | # await ... # <- CancelledError |
| 103 | # |
| 104 | # or there's an exception in "async with": |
| 105 | # |
| 106 | # async with TaskGroup() as g: |
| 107 | # g.create_task(...) |
| 108 | # 1 / 0 |
| 109 | # |
| 110 | self._abort() |
| 111 | |
| 112 | # We use while-loop here because "self._on_completed_fut" |
| 113 | # can be cancelled multiple times if our parent task |
| 114 | # is being cancelled repeatedly (or even once, when |
| 115 | # our own cancellation is already in progress) |
| 116 | while self._tasks: |
| 117 | if self._on_completed_fut is None: |
| 118 | self._on_completed_fut = self._loop.create_future() |
| 119 | |
| 120 | try: |
| 121 | await self._on_completed_fut |
| 122 | except exceptions.CancelledError as ex: |
| 123 | if not self._aborting: |
| 124 | # Our parent task is being cancelled: |
| 125 | # |
| 126 | # async def wrapper(): |
| 127 | # async with TaskGroup() as g: |
| 128 | # g.create_task(foo) |
| 129 | # |
| 130 | # "wrapper" is being cancelled while "foo" is |
| 131 | # still running. |
| 132 | propagate_cancellation_error = ex |
| 133 | self._abort() |
| 134 | |
| 135 | self._on_completed_fut = None |
| 136 | |
| 137 | assert not self._tasks |
| 138 | |
| 139 | if self._base_error is not None: |
| 140 | try: |
no test coverage detected