Kaydet (Commit) 3d1f2d3b authored tarafından Benjamin Peterson's avatar Benjamin Peterson

make _socket.socket weakrefable (closes #22569)

Patch from Alex Gaynor.
üst 7788dba2
...@@ -12,9 +12,9 @@ import sys ...@@ -12,9 +12,9 @@ import sys
import os import os
import array import array
import contextlib import contextlib
from weakref import proxy
import signal import signal
import math import math
import weakref
try: try:
import _socket import _socket
except ImportError: except ImportError:
...@@ -264,7 +264,7 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -264,7 +264,7 @@ class GeneralModuleTests(unittest.TestCase):
def test_weakref(self): def test_weakref(self):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
p = proxy(s) p = weakref.proxy(s)
self.assertEqual(p.fileno(), s.fileno()) self.assertEqual(p.fileno(), s.fileno())
s.close() s.close()
s = None s = None
...@@ -275,6 +275,14 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -275,6 +275,14 @@ class GeneralModuleTests(unittest.TestCase):
else: else:
self.fail('Socket proxy still exists') 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): def testSocketError(self):
# Testing socket module exceptions # Testing socket module exceptions
def raise_error(*args, **kwargs): def raise_error(*args, **kwargs):
......
...@@ -3115,6 +3115,8 @@ sock_dealloc(PySocketSockObject *s) ...@@ -3115,6 +3115,8 @@ sock_dealloc(PySocketSockObject *s)
{ {
if (s->sock_fd != -1) if (s->sock_fd != -1)
(void) SOCKETCLOSE(s->sock_fd); (void) SOCKETCLOSE(s->sock_fd);
if (s->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *)s);
Py_TYPE(s)->tp_free((PyObject *)s); Py_TYPE(s)->tp_free((PyObject *)s);
} }
...@@ -3163,6 +3165,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -3163,6 +3165,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
((PySocketSockObject *)new)->sock_fd = -1; ((PySocketSockObject *)new)->sock_fd = -1;
((PySocketSockObject *)new)->sock_timeout = -1.0; ((PySocketSockObject *)new)->sock_timeout = -1.0;
((PySocketSockObject *)new)->errorhandler = &set_error; ((PySocketSockObject *)new)->errorhandler = &set_error;
((PySocketSockObject *)new)->weakreflist = NULL;
} }
return new; return new;
} }
...@@ -3226,7 +3229,7 @@ static PyTypeObject sock_type = { ...@@ -3226,7 +3229,7 @@ static PyTypeObject sock_type = {
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
0, /* tp_richcompare */ 0, /* tp_richcompare */
0, /* tp_weaklistoffset */ offsetof(PySocketSockObject, weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
sock_methods, /* tp_methods */ sock_methods, /* tp_methods */
......
...@@ -132,6 +132,7 @@ typedef struct { ...@@ -132,6 +132,7 @@ typedef struct {
sets a Python exception */ sets a Python exception */
double sock_timeout; /* Operation timeout in seconds; double sock_timeout; /* Operation timeout in seconds;
0.0 means non-blocking */ 0.0 means non-blocking */
PyObject *weakreflist;
} PySocketSockObject; } PySocketSockObject;
/* --- C API ----------------------------------------------------*/ /* --- C API ----------------------------------------------------*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment