]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add weakref support to sockets and re pattern objects.
authorRaymond Hettinger <python@rcn.com>
Mon, 31 May 2004 03:09:25 +0000 (03:09 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 31 May 2004 03:09:25 +0000 (03:09 +0000)
Doc/lib/libweakref.tex
Lib/socket.py
Lib/test/test_re.py
Lib/test/test_socket.py
Misc/NEWS
Modules/_sre.c
Modules/sre.h

index c8d82a8895785b5d9fd1ebb9a56ef9ef7070fb86..f2ba80b03ed4fcf7c1d66a917cf09e941a0af045 100644 (file)
@@ -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}}
index 39d511962b2cf1a52c94314e70b26f2c6b9d952a..e97ce5979f5df85849cf6d0b1f80a93f80be92f1 100644 (file)
@@ -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:
index 2363ce5ee6e3e0998e8ce7accfee5d8b0a3bb6f4..c7afdc59a2a036ab748d2c0e4762ccba708ca402 100644 (file)
@@ -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))
index f7bf041ebd0d1c0e298bf693d2370b32f7ef6707..6e2f80c407bd7395d96ad0a3639d82b24326143a 100644 (file)
@@ -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):
index 7215483a329a7fb9ea8f446f4b79f3038326633e..032f76ec5bd53885226a1412a1d90da21888b6b6 100644 (file)
--- 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.
 
index 45139bc0023524555390b10d1f42122bbc921c78..4be33d04ca8bc0dc20e657737e5201d4f3788450 100644 (file)
@@ -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 */
 };
 
 /* -------------------------------------------------------------------- */
index 45028024665ba50477a87f4dbaf3418d4a1f918f..b07d210805267b9226556636c32d6c7db1524031 100644 (file)
@@ -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];