summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libweakref.tex20
-rw-r--r--Lib/socket.py3
-rw-r--r--Lib/test/test_re.py8
-rw-r--r--Lib/test/test_socket.py14
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_sre.c25
-rw-r--r--Modules/sre.h1
7 files changed, 69 insertions, 5 deletions
diff --git a/Doc/lib/libweakref.tex b/Doc/lib/libweakref.tex
index c8d82a8895..f2ba80b03e 100644
--- a/Doc/lib/libweakref.tex
+++ b/Doc/lib/libweakref.tex
@@ -48,9 +48,23 @@ by the \module{weakref} module for the benefit of advanced uses.
Not all objects can be weakly referenced; those objects which can
include class instances, functions written in Python (but not in C),
-and methods (both bound and unbound). Extension types can easily
-be made to support weak references; see section \ref{weakref-extension},
-``Weak References in Extension Types,'' for more information.
+methods (both bound and unbound), sets, frozensets, file objects,
+sockets, arrays, deques, and regular expression pattern objects.
+\versionchanged[Added support for files, sockets, arrays, and patterns]{2.4}
+
+Several builtin types such as \class{list} and \class{dict} do not
+directly support weak references but can add support through subclassing:
+
+\begin{verbatim}
+class Dict(dict):
+ pass
+
+obj = Dict(red=1, green=2, blue=3) # this object is weak referencable
+\end{verbatim}
+
+Extension types can easily be made to support weak references; see section
+\ref{weakref-extension}, ``Weak References in Extension Types,'' for more
+information.
\begin{funcdesc}{ref}{object\optional{, callback}}
diff --git a/Lib/socket.py b/Lib/socket.py
index 39d511962b..e97ce5979f 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -147,7 +147,8 @@ class _socketobject(object):
__doc__ = _realsocket.__doc__
- __slots__ = ["_sock", "send", "recv", "sendto", "recvfrom"]
+ __slots__ = ["_sock", "send", "recv", "sendto", "recvfrom",
+ "__weakref__"]
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
if _sock is None:
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 2363ce5ee6..c7afdc59a2 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -5,6 +5,7 @@ from test.test_support import verbose, run_unittest
import re
from sre import Scanner
import sys, os, traceback
+from weakref import proxy
# Misc tests from Tim Peters' re.doc
@@ -15,6 +16,13 @@ import sys, os, traceback
import unittest
class ReTests(unittest.TestCase):
+
+ def test_weakref(self):
+ s = 'QabbbcR'
+ x = re.compile('ab+c')
+ y = proxy(x)
+ self.assertEqual(x.findall('QabbbcR'), y.findall('QabbbcR'))
+
def test_search_star_plus(self):
self.assertEqual(re.search('x*', 'axx').span(0), (0, 0))
self.assertEqual(re.search('x*', 'axx').span(), (0, 0))
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index f7bf041ebd..6e2f80c407 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -9,6 +9,7 @@ import time
import thread, threading
import Queue
import sys
+from weakref import proxy
PORT = 50007
HOST = 'localhost'
@@ -191,6 +192,19 @@ class SocketConnectedTest(ThreadedTCPSocketTest):
class GeneralModuleTests(unittest.TestCase):
+ def test_weakref(self):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ p = proxy(s)
+ self.assertEqual(p.fileno(), s.fileno())
+ s.close()
+ s = None
+ try:
+ p.fileno()
+ except ReferenceError:
+ pass
+ else:
+ self.fail('Socket proxy still exists')
+
def testSocketError(self):
# Testing socket module exceptions
def raise_error(*args, **kwargs):
diff --git a/Misc/NEWS b/Misc/NEWS
index 7215483a32..032f76ec5b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -207,6 +207,9 @@ Core and builtins
Extension modules
-----------------
+- the weakref module now supports additional objects: array.array,
+ sre.pattern_objects, file objects, and sockets.
+
- operator.isMappingType() and operator.isSequenceType() now give
fewer false positives.
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 45139bc002..4be33d04ca 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -1673,6 +1673,8 @@ _compile(PyObject* self_, PyObject* args)
Py_XINCREF(indexgroup);
self->indexgroup = indexgroup;
+ self->weakreflist = NULL;
+
return (PyObject*) self;
}
@@ -1985,6 +1987,8 @@ pattern_scanner(PatternObject* pattern, PyObject* args)
static void
pattern_dealloc(PatternObject* self)
{
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
Py_XDECREF(self->pattern);
Py_XDECREF(self->groupindex);
Py_XDECREF(self->indexgroup);
@@ -2632,6 +2636,7 @@ pattern_copy(PatternObject* self, PyObject* args)
memcpy((char*) copy + offset, (char*) self + offset,
sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
+ copy->weakreflist = NULL;
return (PyObject*) copy;
#else
@@ -2722,7 +2727,25 @@ statichere PyTypeObject Pattern_Type = {
sizeof(PatternObject), sizeof(SRE_CODE),
(destructor)pattern_dealloc, /*tp_dealloc*/
0, /*tp_print*/
- (getattrfunc)pattern_getattr /*tp_getattr*/
+ (getattrfunc)pattern_getattr, /*tp_getattr*/
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
};
/* -------------------------------------------------------------------- */
diff --git a/Modules/sre.h b/Modules/sre.h
index 4502802466..b07d210805 100644
--- a/Modules/sre.h
+++ b/Modules/sre.h
@@ -29,6 +29,7 @@ typedef struct {
/* compatibility */
PyObject* pattern; /* pattern source (or None) */
int flags; /* flags used when compiling pattern source */
+ PyObject *weakreflist; /* List of weak references */
/* pattern code */
int codesize;
SRE_CODE code[1];