diff --git a/Lib/codeop.py b/Lib/codeop.py index fb759da42ad..0fa677f609b 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -93,10 +93,13 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError as e: err2 = e - if code: - return code - if not code1 and repr(err1) == repr(err2): - raise err1 + try: + if code: + return code + if not code1 and repr(err1) == repr(err2): + raise err1 + finally: + err1 = err2 = None def _compile(source, filename, symbol): return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) diff --git a/Lib/ctypes/macholib/dyld.py b/Lib/ctypes/macholib/dyld.py index c158e672f05..9d86b058765 100644 --- a/Lib/ctypes/macholib/dyld.py +++ b/Lib/ctypes/macholib/dyld.py @@ -149,6 +149,8 @@ def framework_find(fn, executable_path=None, env=None): return dyld_find(fn, executable_path=executable_path, env=env) except ValueError: raise error + finally: + error = None def test_dyld_find(): env = {} diff --git a/Lib/socket.py b/Lib/socket.py index 813f4ef5c3e..5b17906ef47 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -804,7 +804,11 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, sock.close() if err is not None: - raise err + try: + raise err + finally: + # Break explicitly a reference cycle + err = None else: raise error("getaddrinfo returns an empty list") diff --git a/Misc/NEWS.d/next/Library/2019-05-06-15-34-17.bpo-36820.Eh5mIB.rst b/Misc/NEWS.d/next/Library/2019-05-06-15-34-17.bpo-36820.Eh5mIB.rst new file mode 100644 index 00000000000..82f6635c815 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-06-15-34-17.bpo-36820.Eh5mIB.rst @@ -0,0 +1,3 @@ +Break cycle generated when saving an exception in socket.py, codeop.py and +dyld.py as they keep alive not only the exception but user objects through +the ``__traceback__`` attribute. Patch by Mario Corchero.