Add weakref support to array.array and file objects.
This commit is contained in:
parent
691d80532b
commit
cb87bc8e7e
@ -24,6 +24,7 @@ typedef struct {
|
|||||||
int f_newlinetypes; /* Types of newlines seen */
|
int f_newlinetypes; /* Types of newlines seen */
|
||||||
int f_skipnextlf; /* Skip next \n */
|
int f_skipnextlf; /* Skip next \n */
|
||||||
PyObject *f_encoding;
|
PyObject *f_encoding;
|
||||||
|
PyObject *weakreflist; /* List of weak references */
|
||||||
} PyFileObject;
|
} PyFileObject;
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyFile_Type;
|
PyAPI_DATA(PyTypeObject) PyFile_Type;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from test import test_support
|
from test import test_support
|
||||||
|
from weakref import proxy
|
||||||
import array, cStringIO, math
|
import array, cStringIO, math
|
||||||
|
|
||||||
tests = [] # list to accumulate all tests
|
tests = [] # list to accumulate all tests
|
||||||
@ -614,6 +615,13 @@ class BaseTest(unittest.TestCase):
|
|||||||
b = buffer(a)
|
b = buffer(a)
|
||||||
self.assertEqual(b[0], a.tostring()[0])
|
self.assertEqual(b[0], a.tostring()[0])
|
||||||
|
|
||||||
|
def test_weakref(self):
|
||||||
|
s = array.array(self.typecode, self.example)
|
||||||
|
p = proxy(s)
|
||||||
|
self.assertEqual(p.tostring(), s.tostring())
|
||||||
|
s = None
|
||||||
|
self.assertRaises(ReferenceError, len, p)
|
||||||
|
|
||||||
def test_bug_782369(self):
|
def test_bug_782369(self):
|
||||||
import sys
|
import sys
|
||||||
if hasattr(sys, "getrefcount"):
|
if hasattr(sys, "getrefcount"):
|
||||||
@ -624,6 +632,8 @@ class BaseTest(unittest.TestCase):
|
|||||||
b = array.array('B', range(64))
|
b = array.array('B', range(64))
|
||||||
self.assertEqual(rc, sys.getrefcount(10))
|
self.assertEqual(rc, sys.getrefcount(10))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StringTest(BaseTest):
|
class StringTest(BaseTest):
|
||||||
|
|
||||||
def test_setitem(self):
|
def test_setitem(self):
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from array import array
|
from array import array
|
||||||
|
from weakref import proxy
|
||||||
|
|
||||||
from test.test_support import verify, TESTFN, TestFailed
|
from test.test_support import verify, TESTFN, TestFailed
|
||||||
from UserList import UserList
|
from UserList import UserList
|
||||||
|
|
||||||
|
# verify weak references
|
||||||
|
f = file(TESTFN, 'w')
|
||||||
|
p = proxy(f)
|
||||||
|
p.write('teststring')
|
||||||
|
verify(f.tell(), p.tell())
|
||||||
|
f.close()
|
||||||
|
f = None
|
||||||
|
try:
|
||||||
|
p.tell()
|
||||||
|
except ReferenceError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise TestFailed('file proxy still exists when the file is gone')
|
||||||
|
|
||||||
# verify expected attributes exist
|
# verify expected attributes exist
|
||||||
f = file(TESTFN, 'w')
|
f = file(TESTFN, 'w')
|
||||||
softspace = f.softspace
|
softspace = f.softspace
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
The item type is restricted to simple C types like int or float */
|
The item type is restricted to simple C types like int or float */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "structmember.h"
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -32,6 +33,7 @@ typedef struct arrayobject {
|
|||||||
char *ob_item;
|
char *ob_item;
|
||||||
int allocated;
|
int allocated;
|
||||||
struct arraydescr *ob_descr;
|
struct arraydescr *ob_descr;
|
||||||
|
PyObject *weakreflist; /* List of weak references */
|
||||||
} arrayobject;
|
} arrayobject;
|
||||||
|
|
||||||
static PyTypeObject Arraytype;
|
static PyTypeObject Arraytype;
|
||||||
@ -442,6 +444,7 @@ newarrayobject(PyTypeObject *type, int size, struct arraydescr *descr)
|
|||||||
}
|
}
|
||||||
op->ob_descr = descr;
|
op->ob_descr = descr;
|
||||||
op->allocated = size;
|
op->allocated = size;
|
||||||
|
op->weakreflist = NULL;
|
||||||
return (PyObject *) op;
|
return (PyObject *) op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,6 +493,8 @@ ins1(arrayobject *self, int where, PyObject *v)
|
|||||||
static void
|
static void
|
||||||
array_dealloc(arrayobject *op)
|
array_dealloc(arrayobject *op)
|
||||||
{
|
{
|
||||||
|
if (op->weakreflist != NULL)
|
||||||
|
PyObject_ClearWeakRefs((PyObject *) op);
|
||||||
if (op->ob_item != NULL)
|
if (op->ob_item != NULL)
|
||||||
PyMem_DEL(op->ob_item);
|
PyMem_DEL(op->ob_item);
|
||||||
op->ob_type->tp_free((PyObject *)op);
|
op->ob_type->tp_free((PyObject *)op);
|
||||||
@ -1950,12 +1955,12 @@ static PyTypeObject Arraytype = {
|
|||||||
PyObject_GenericGetAttr, /* tp_getattro */
|
PyObject_GenericGetAttr, /* tp_getattro */
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
&array_as_buffer, /* tp_as_buffer*/
|
&array_as_buffer, /* tp_as_buffer*/
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
|
||||||
arraytype_doc, /* tp_doc */
|
arraytype_doc, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
0, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
array_richcompare, /* tp_richcompare */
|
array_richcompare, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */
|
||||||
(getiterfunc)array_iter, /* tp_iter */
|
(getiterfunc)array_iter, /* tp_iter */
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
array_methods, /* tp_methods */
|
array_methods, /* tp_methods */
|
||||||
|
@ -307,6 +307,8 @@ static void drop_readahead(PyFileObject *);
|
|||||||
static void
|
static void
|
||||||
file_dealloc(PyFileObject *f)
|
file_dealloc(PyFileObject *f)
|
||||||
{
|
{
|
||||||
|
if (f->weakreflist != NULL)
|
||||||
|
PyObject_ClearWeakRefs((PyObject *) f);
|
||||||
if (f->f_fp != NULL && f->f_close != NULL) {
|
if (f->f_fp != NULL && f->f_close != NULL) {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
(*f->f_close)(f->f_fp);
|
(*f->f_close)(f->f_fp);
|
||||||
@ -1821,6 +1823,7 @@ file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
((PyFileObject *)self)->f_mode = not_yet_string;
|
((PyFileObject *)self)->f_mode = not_yet_string;
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
((PyFileObject *)self)->f_encoding = Py_None;
|
((PyFileObject *)self)->f_encoding = Py_None;
|
||||||
|
((PyFileObject *)self)->weakreflist = NULL;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -1942,12 +1945,12 @@ PyTypeObject PyFile_Type = {
|
|||||||
/* softspace is writable: we must supply tp_setattro */
|
/* softspace is writable: we must supply tp_setattro */
|
||||||
PyObject_GenericSetAttr, /* tp_setattro */
|
PyObject_GenericSetAttr, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
|
||||||
file_doc, /* tp_doc */
|
file_doc, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
0, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
offsetof(PyFileObject, weakreflist), /* tp_weaklistoffset */
|
||||||
(getiterfunc)file_getiter, /* tp_iter */
|
(getiterfunc)file_getiter, /* tp_iter */
|
||||||
(iternextfunc)file_iternext, /* tp_iternext */
|
(iternextfunc)file_iternext, /* tp_iternext */
|
||||||
file_methods, /* tp_methods */
|
file_methods, /* tp_methods */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user