Add weakref support to sockets and re pattern objects.

This commit is contained in:
Raymond Hettinger 2004-05-31 03:09:25 +00:00
parent cb87bc8e7e
commit 027bb633b6
7 changed files with 69 additions and 5 deletions

View 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}}

View 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:

View 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))

View 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):

View File

@ -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.

View 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 */
};
/* -------------------------------------------------------------------- */

View 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];