bpo-35930: Raising an exception raised in a "future" instance will create reference cycles (#24995)

Before: https://lists.es.python.org/pipermail/general/attachments/20201229/0c14bc58/attachment-0002.png

After: https://lists.es.python.org/pipermail/general/attachments/20201229/0c14bc58/attachment-0003.png
This commit is contained in:
Jesús Cea 2021-03-29 19:22:13 +02:00 committed by GitHub
parent 7bfd65eba7
commit 32430aadad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 13 deletions

View File

@ -386,7 +386,11 @@ class Future(object):
def __get_result(self):
if self._exception:
raise self._exception
try:
raise self._exception
finally:
# Break a reference cycle with the exception in self._exception
self = None
else:
return self._result
@ -426,20 +430,24 @@ class Future(object):
timeout.
Exception: If the call raised then that exception will be raised.
"""
with self._condition:
if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
raise CancelledError()
elif self._state == FINISHED:
return self.__get_result()
try:
with self._condition:
if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
raise CancelledError()
elif self._state == FINISHED:
return self.__get_result()
self._condition.wait(timeout)
self._condition.wait(timeout)
if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
raise CancelledError()
elif self._state == FINISHED:
return self.__get_result()
else:
raise TimeoutError()
if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
raise CancelledError()
elif self._state == FINISHED:
return self.__get_result()
else:
raise TimeoutError()
finally:
# Break a reference cycle with the exception in self._exception
self = None
def exception(self, timeout=None):
"""Return the exception raised by the call that the future represents.

View File

@ -0,0 +1,2 @@
Raising an exception raised in a "future" instance will create reference
cycles.