]> granicus.if.org Git - python/commitdiff
make _socket.socket weakrefable (closes #22569)
authorBenjamin Peterson <benjamin@python.org>
Mon, 6 Oct 2014 18:38:20 +0000 (14:38 -0400)
committerBenjamin Peterson <benjamin@python.org>
Mon, 6 Oct 2014 18:38:20 +0000 (14:38 -0400)
Patch from Alex Gaynor.

Lib/test/test_socket.py
Modules/socketmodule.c
Modules/socketmodule.h

index 81bd537e0e361c45c8cbaa4a2604a58b8a6d8eba..0ce80b9444798368c419c056d47214e80a7220ca 100644 (file)
@@ -12,9 +12,9 @@ import sys
 import os
 import array
 import contextlib
-from weakref import proxy
 import signal
 import math
+import weakref
 try:
     import _socket
 except ImportError:
@@ -264,7 +264,7 @@ class GeneralModuleTests(unittest.TestCase):
 
     def test_weakref(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        p = proxy(s)
+        p = weakref.proxy(s)
         self.assertEqual(p.fileno(), s.fileno())
         s.close()
         s = None
@@ -275,6 +275,14 @@ class GeneralModuleTests(unittest.TestCase):
         else:
             self.fail('Socket proxy still exists')
 
+    def test_weakref__sock(self):
+        s = socket.socket()._sock
+        w = weakref.ref(s)
+        self.assertIs(w(), s)
+        del s
+        test_support.gc_collect()
+        self.assertIsNone(w())
+
     def testSocketError(self):
         # Testing socket module exceptions
         def raise_error(*args, **kwargs):
index 0127a6c3c69ab8c13337a85eec6baf6e0e8214ae..e9e4479a667870293461ef22f8b3e15502174fe7 100644 (file)
@@ -3115,6 +3115,8 @@ sock_dealloc(PySocketSockObject *s)
 {
     if (s->sock_fd != -1)
         (void) SOCKETCLOSE(s->sock_fd);
+    if (s->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *)s);
     Py_TYPE(s)->tp_free((PyObject *)s);
 }
 
@@ -3163,6 +3165,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         ((PySocketSockObject *)new)->sock_fd = -1;
         ((PySocketSockObject *)new)->sock_timeout = -1.0;
         ((PySocketSockObject *)new)->errorhandler = &set_error;
+        ((PySocketSockObject *)new)->weakreflist = NULL;
     }
     return new;
 }
@@ -3226,7 +3229,7 @@ static PyTypeObject sock_type = {
     0,                                          /* tp_traverse */
     0,                                          /* tp_clear */
     0,                                          /* tp_richcompare */
-    0,                                          /* tp_weaklistoffset */
+    offsetof(PySocketSockObject, weakreflist),  /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
     sock_methods,                               /* tp_methods */
index 8515499b0286164626189ad1a1925b0634192941..d98e00e88d270187bad8e926cf9cc96ab4a981e3 100644 (file)
@@ -132,6 +132,7 @@ typedef struct {
                                         sets a Python exception */
     double sock_timeout;                 /* Operation timeout in seconds;
                                         0.0 means non-blocking */
+    PyObject *weakreflist;
 } PySocketSockObject;
 
 /* --- C API ----------------------------------------------------*/