bpo-36820: Break unnecessary cycle in socket.py, codeop.py and dyld.py (GH-13135)



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.


https://bugs.python.org/issue36820



Automerge-Triggered-By: @pablogsal
diff --git a/Lib/codeop.py b/Lib/codeop.py
index fc7e1e7..082285f 100644
--- a/Lib/codeop.py
+++ b/Lib/codeop.py
@@ -93,10 +93,13 @@
     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 c158e67..9d86b05 100644
--- a/Lib/ctypes/macholib/dyld.py
+++ b/Lib/ctypes/macholib/dyld.py
@@ -149,6 +149,8 @@
         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 84a5dcb..374f112 100755
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -839,7 +839,11 @@
                 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")