Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 027bb63

Browse files
committed
Add weakref support to sockets and re pattern objects.
1 parent cb87bc8 commit 027bb63

7 files changed

Lines changed: 69 additions & 5 deletions

File tree

Doc/lib/libweakref.tex

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,23 @@ \section{\module{weakref} ---
4848

4949
Not all objects can be weakly referenced; those objects which can
5050
include class instances, functions written in Python (but not in C),
51-
and methods (both bound and unbound). Extension types can easily
52-
be made to support weak references; see section \ref{weakref-extension},
53-
``Weak References in Extension Types,'' for more information.
51+
methods (both bound and unbound), sets, frozensets, file objects,
52+
sockets, arrays, deques, and regular expression pattern objects.
53+
\versionchanged[Added support for files, sockets, arrays, and patterns]{2.4}
54+
55+
Several builtin types such as \class{list} and \class{dict} do not
56+
directly support weak references but can add support through subclassing:
57+
58+
\begin{verbatim}
59+
class Dict(dict):
60+
pass
61+
62+
obj = Dict(red=1, green=2, blue=3) # this object is weak referencable
63+
\end{verbatim}
64+
65+
Extension types can easily be made to support weak references; see section
66+
\ref{weakref-extension}, ``Weak References in Extension Types,'' for more
67+
information.
5468

5569

5670
\begin{funcdesc}{ref}{object\optional{, callback}}

Lib/socket.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ class _socketobject(object):
147147

148148
__doc__ = _realsocket.__doc__
149149

150-
__slots__ = ["_sock", "send", "recv", "sendto", "recvfrom"]
150+
__slots__ = ["_sock", "send", "recv", "sendto", "recvfrom",
151+
"__weakref__"]
151152

152153
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
153154
if _sock is None:

Lib/test/test_re.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import re
66
from sre import Scanner
77
import sys, os, traceback
8+
from weakref import proxy
89

910
# Misc tests from Tim Peters' re.doc
1011

@@ -15,6 +16,13 @@
1516
import unittest
1617

1718
class ReTests(unittest.TestCase):
19+
20+
def test_weakref(self):
21+
s = 'QabbbcR'
22+
x = re.compile('ab+c')
23+
y = proxy(x)
24+
self.assertEqual(x.findall('QabbbcR'), y.findall('QabbbcR'))
25+
1826
def test_search_star_plus(self):
1927
self.assertEqual(re.search('x*', 'axx').span(0), (0, 0))
2028
self.assertEqual(re.search('x*', 'axx').span(), (0, 0))

Lib/test/test_socket.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import thread, threading
1010
import Queue
1111
import sys
12+
from weakref import proxy
1213

1314
PORT = 50007
1415
HOST = 'localhost'
@@ -191,6 +192,19 @@ def clientTearDown(self):
191192

192193
class GeneralModuleTests(unittest.TestCase):
193194

195+
def test_weakref(self):
196+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
197+
p = proxy(s)
198+
self.assertEqual(p.fileno(), s.fileno())
199+
s.close()
200+
s = None
201+
try:
202+
p.fileno()
203+
except ReferenceError:
204+
pass
205+
else:
206+
self.fail('Socket proxy still exists')
207+
194208
def testSocketError(self):
195209
# Testing socket module exceptions
196210
def raise_error(*args, **kwargs):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ Core and builtins
207207
Extension modules
208208
-----------------
209209

210+
- the weakref module now supports additional objects: array.array,
211+
sre.pattern_objects, file objects, and sockets.
212+
210213
- operator.isMappingType() and operator.isSequenceType() now give
211214
fewer false positives.
212215

Modules/_sre.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,8 @@ _compile(PyObject* self_, PyObject* args)
16731673
Py_XINCREF(indexgroup);
16741674
self->indexgroup = indexgroup;
16751675

1676+
self->weakreflist = NULL;
1677+
16761678
return (PyObject*) self;
16771679
}
16781680

@@ -1985,6 +1987,8 @@ pattern_scanner(PatternObject* pattern, PyObject* args)
19851987
static void
19861988
pattern_dealloc(PatternObject* self)
19871989
{
1990+
if (self->weakreflist != NULL)
1991+
PyObject_ClearWeakRefs((PyObject *) self);
19881992
Py_XDECREF(self->pattern);
19891993
Py_XDECREF(self->groupindex);
19901994
Py_XDECREF(self->indexgroup);
@@ -2632,6 +2636,7 @@ pattern_copy(PatternObject* self, PyObject* args)
26322636

26332637
memcpy((char*) copy + offset, (char*) self + offset,
26342638
sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
2639+
copy->weakreflist = NULL;
26352640

26362641
return (PyObject*) copy;
26372642
#else
@@ -2722,7 +2727,25 @@ statichere PyTypeObject Pattern_Type = {
27222727
sizeof(PatternObject), sizeof(SRE_CODE),
27232728
(destructor)pattern_dealloc, /*tp_dealloc*/
27242729
0, /*tp_print*/
2725-
(getattrfunc)pattern_getattr /*tp_getattr*/
2730+
(getattrfunc)pattern_getattr, /*tp_getattr*/
2731+
0, /* tp_setattr */
2732+
0, /* tp_compare */
2733+
0, /* tp_repr */
2734+
0, /* tp_as_number */
2735+
0, /* tp_as_sequence */
2736+
0, /* tp_as_mapping */
2737+
0, /* tp_hash */
2738+
0, /* tp_call */
2739+
0, /* tp_str */
2740+
0, /* tp_getattro */
2741+
0, /* tp_setattro */
2742+
0, /* tp_as_buffer */
2743+
Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
2744+
0, /* tp_doc */
2745+
0, /* tp_traverse */
2746+
0, /* tp_clear */
2747+
0, /* tp_richcompare */
2748+
offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
27262749
};
27272750

27282751
/* -------------------------------------------------------------------- */

Modules/sre.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef struct {
2929
/* compatibility */
3030
PyObject* pattern; /* pattern source (or None) */
3131
int flags; /* flags used when compiling pattern source */
32+
PyObject *weakreflist; /* List of weak references */
3233
/* pattern code */
3334
int codesize;
3435
SRE_CODE code[1];

0 commit comments

Comments
 (0)