| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -190,7 +190,8 @@ def result(self): | |||
| 190 | 190 | the future is done and has an exception set, this exception is raised. | |
| 191 | 191 | """ | |
| 192 | 192 | if self._state == _CANCELLED: | |
| 193 | - raise self._make_cancelled_error() | ||
| 193 | + exc = self._make_cancelled_error() | ||
| 194 | + raise exc | ||
| 194 | 195 | if self._state != _FINISHED: | |
| 195 | 196 | raise exceptions.InvalidStateError('Result is not ready.') | |
| 196 | 197 | self.__log_traceback = False | |
@@ -207,7 +208,8 @@ def exception(self): | |||
| 207 | 208 | InvalidStateError. | |
| 208 | 209 | """ | |
| 209 | 210 | if self._state == _CANCELLED: | |
| 210 | - raise self._make_cancelled_error() | ||
| 211 | + exc = self._make_cancelled_error() | ||
| 212 | + raise exc | ||
| 211 | 213 | if self._state != _FINISHED: | |
| 212 | 214 | raise exceptions.InvalidStateError('Exception is not set.') | |
| 213 | 215 | self.__log_traceback = False | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,20 +66,6 @@ async def __aenter__(self): | |||
| 66 | 66 | return self | |
| 67 | 67 | ||
| 68 | 68 | async def __aexit__(self, et, exc, tb): | |
| 69 | - tb = None | ||
| 70 | - try: | ||
| 71 | - return await self._aexit(et, exc) | ||
| 72 | - finally: | ||
| 73 | - # Exceptions are heavy objects that can have object | ||
| 74 | - # cycles (bad for GC); let's not keep a reference to | ||
| 75 | - # a bunch of them. It would be nicer to use a try/finally | ||
| 76 | - # in __aexit__ directly but that introduced some diff noise | ||
| 77 | - self._parent_task = None | ||
| 78 | - self._errors = None | ||
| 79 | - self._base_error = None | ||
| 80 | - exc = None | ||
| 81 | - | ||
| 82 | - async def _aexit(self, et, exc): | ||
| 83 | 69 | self._exiting = True | |
| 84 | 70 | ||
| 85 | 71 | if (exc is not None and | |
@@ -136,10 +122,7 @@ async def _aexit(self, et, exc): | |||
| 136 | 122 | assert not self._tasks | |
| 137 | 123 | ||
| 138 | 124 | if self._base_error is not None: | |
| 139 | - try: | ||
| 140 | - raise self._base_error | ||
| 141 | - finally: | ||
| 142 | - exc = None | ||
| 125 | + raise self._base_error | ||
| 143 | 126 | ||
| 144 | 127 | if self._parent_cancel_requested: | |
| 145 | 128 | # If this flag is set we *must* call uncancel(). | |
@@ -150,14 +133,8 @@ async def _aexit(self, et, exc): | |||
| 150 | 133 | ||
| 151 | 134 | # Propagate CancelledError if there is one, except if there | |
| 152 | 135 | # are other errors -- those have priority. | |
| 153 | - try: | ||
| 154 | - if propagate_cancellation_error is not None and not self._errors: | ||
| 155 | - try: | ||
| 156 | - raise propagate_cancellation_error | ||
| 157 | - finally: | ||
| 158 | - exc = None | ||
| 159 | - finally: | ||
| 160 | - propagate_cancellation_error = None | ||
| 136 | + if propagate_cancellation_error is not None and not self._errors: | ||
| 137 | + raise propagate_cancellation_error | ||
| 161 | 138 | ||
| 162 | 139 | if et is not None and not issubclass(et, exceptions.CancelledError): | |
| 163 | 140 | self._errors.append(exc) | |
@@ -169,14 +146,14 @@ async def _aexit(self, et, exc): | |||
| 169 | 146 | if self._parent_task.cancelling(): | |
| 170 | 147 | self._parent_task.uncancel() | |
| 171 | 148 | self._parent_task.cancel() | |
| 149 | + # Exceptions are heavy objects that can have object | ||
| 150 | + # cycles (bad for GC); let's not keep a reference to | ||
| 151 | + # a bunch of them. | ||
| 172 | 152 | try: | |
| 173 | - raise BaseExceptionGroup( | ||
| 174 | - 'unhandled errors in a TaskGroup', | ||
| 175 | - self._errors, | ||
| 176 | - ) from None | ||
| 153 | + me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors) | ||
| 154 | + raise me from None | ||
| 177 | 155 | finally: | |
| 178 | - exc = None | ||
| 179 | - | ||
| 156 | + self._errors = None | ||
| 180 | 157 | ||
| 181 | 158 | def create_task(self, coro, *, name=None, context=None): | |
| 182 | 159 | """Create a new task in this group and return it. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -659,28 +659,6 @@ def __del__(self): | |||
| 659 | 659 | fut = self._new_future(loop=self.loop) | |
| 660 | 660 | fut.set_result(Evil()) | |
| 661 | 661 | ||
| 662 | - def test_future_cancelled_result_refcycles(self): | ||
| 663 | - f = self._new_future(loop=self.loop) | ||
| 664 | - f.cancel() | ||
| 665 | - exc = None | ||
| 666 | - try: | ||
| 667 | - f.result() | ||
| 668 | - except asyncio.CancelledError as e: | ||
| 669 | - exc = e | ||
| 670 | - self.assertIsNotNone(exc) | ||
| 671 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 672 | - | ||
| 673 | - def test_future_cancelled_exception_refcycles(self): | ||
| 674 | - f = self._new_future(loop=self.loop) | ||
| 675 | - f.cancel() | ||
| 676 | - exc = None | ||
| 677 | - try: | ||
| 678 | - f.exception() | ||
| 679 | - except asyncio.CancelledError as e: | ||
| 680 | - exc = e | ||
| 681 | - self.assertIsNotNone(exc) | ||
| 682 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 683 | - | ||
| 684 | 662 | ||
| 685 | 663 | @unittest.skipUnless(hasattr(futures, '_CFuture'), | |
| 686 | 664 | 'requires the C _asyncio module') | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,7 @@ | |||
| 1 | 1 | # Adapted with permission from the EdgeDB project; | |
| 2 | 2 | # license: PSFL. | |
| 3 | 3 | ||
| 4 | - import gc | ||
| 4 | + | ||
| 5 | 5 | import asyncio | |
| 6 | 6 | import contextvars | |
| 7 | 7 | import contextlib | |
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | 12 | from test.test_asyncio.utils import await_without_task | |
| 13 | 13 | ||
| 14 | + | ||
| 14 | 15 | # To prevent a warning "test altered the execution environment" | |
| 15 | 16 | def tearDownModule(): | |
| 16 | 17 | asyncio.set_event_loop_policy(None) | |
@@ -898,95 +899,6 @@ async def outer(): | |||
| 898 | 899 | ||
| 899 | 900 | await outer() | |
| 900 | 901 | ||
| 901 | - async def test_exception_refcycles_direct(self): | ||
| 902 | - """Test that TaskGroup doesn't keep a reference to the raised ExceptionGroup""" | ||
| 903 | - tg = asyncio.TaskGroup() | ||
| 904 | - exc = None | ||
| 905 | - | ||
| 906 | - class _Done(Exception): | ||
| 907 | - pass | ||
| 908 | - | ||
| 909 | - try: | ||
| 910 | - async with tg: | ||
| 911 | - raise _Done | ||
| 912 | - except ExceptionGroup as e: | ||
| 913 | - exc = e | ||
| 914 | - | ||
| 915 | - self.assertIsNotNone(exc) | ||
| 916 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 917 | - | ||
| 918 | - | ||
| 919 | - async def test_exception_refcycles_errors(self): | ||
| 920 | - """Test that TaskGroup deletes self._errors, and __aexit__ args""" | ||
| 921 | - tg = asyncio.TaskGroup() | ||
| 922 | - exc = None | ||
| 923 | - | ||
| 924 | - class _Done(Exception): | ||
| 925 | - pass | ||
| 926 | - | ||
| 927 | - try: | ||
| 928 | - async with tg: | ||
| 929 | - raise _Done | ||
| 930 | - except* _Done as excs: | ||
| 931 | - exc = excs.exceptions[0] | ||
| 932 | - | ||
| 933 | - self.assertIsInstance(exc, _Done) | ||
| 934 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 935 | - | ||
| 936 | - | ||
| 937 | - async def test_exception_refcycles_parent_task(self): | ||
| 938 | - """Test that TaskGroup deletes self._parent_task""" | ||
| 939 | - tg = asyncio.TaskGroup() | ||
| 940 | - exc = None | ||
| 941 | - | ||
| 942 | - class _Done(Exception): | ||
| 943 | - pass | ||
| 944 | - | ||
| 945 | - async def coro_fn(): | ||
| 946 | - async with tg: | ||
| 947 | - raise _Done | ||
| 948 | - | ||
| 949 | - try: | ||
| 950 | - async with asyncio.TaskGroup() as tg2: | ||
| 951 | - tg2.create_task(coro_fn()) | ||
| 952 | - except* _Done as excs: | ||
| 953 | - exc = excs.exceptions[0].exceptions[0] | ||
| 954 | - | ||
| 955 | - self.assertIsInstance(exc, _Done) | ||
| 956 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 957 | - | ||
| 958 | - async def test_exception_refcycles_propagate_cancellation_error(self): | ||
| 959 | - """Test that TaskGroup deletes propagate_cancellation_error""" | ||
| 960 | - tg = asyncio.TaskGroup() | ||
| 961 | - exc = None | ||
| 962 | - | ||
| 963 | - try: | ||
| 964 | - async with asyncio.timeout(-1): | ||
| 965 | - async with tg: | ||
| 966 | - await asyncio.sleep(0) | ||
| 967 | - except TimeoutError as e: | ||
| 968 | - exc = e.__cause__ | ||
| 969 | - | ||
| 970 | - self.assertIsInstance(exc, asyncio.CancelledError) | ||
| 971 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 972 | - | ||
| 973 | - async def test_exception_refcycles_base_error(self): | ||
| 974 | - """Test that TaskGroup deletes self._base_error""" | ||
| 975 | - class MyKeyboardInterrupt(KeyboardInterrupt): | ||
| 976 | - pass | ||
| 977 | - | ||
| 978 | - tg = asyncio.TaskGroup() | ||
| 979 | - exc = None | ||
| 980 | - | ||
| 981 | - try: | ||
| 982 | - async with tg: | ||
| 983 | - raise MyKeyboardInterrupt | ||
| 984 | - except MyKeyboardInterrupt as e: | ||
| 985 | - exc = e | ||
| 986 | - | ||
| 987 | - self.assertIsNotNone(exc) | ||
| 988 | - self.assertListEqual(gc.get_referrers(exc), []) | ||
| 989 | - | ||
| 990 | 902 | ||
| 991 | 903 | if __name__ == "__main__": | |
| 992 | 904 | unittest.main() | |
| Back | FazBrowse Home | New Git URL |
0 commit comments