mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
Patch #403985: Add support for weak-keyed dictionaries
This commit is contained in:
parent
bb40dc4892
commit
5e1633365d
5 changed files with 158 additions and 21 deletions
|
@ -8,6 +8,7 @@ struct _PyWeakReference {
|
|||
PyObject_HEAD
|
||||
PyObject *wr_object;
|
||||
PyObject *wr_callback;
|
||||
long hash;
|
||||
PyWeakReference *wr_prev;
|
||||
PyWeakReference *wr_next;
|
||||
};
|
||||
|
@ -39,6 +40,8 @@ new_weakref(void)
|
|||
else {
|
||||
result = PyObject_NEW(PyWeakReference, &PyWeakReference_Type);
|
||||
}
|
||||
if (result)
|
||||
result->hash = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -112,6 +115,20 @@ weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
|
|||
}
|
||||
|
||||
|
||||
static long
|
||||
weakref_hash(PyWeakReference *self)
|
||||
{
|
||||
if (self->hash != -1)
|
||||
return self->hash;
|
||||
if (self->wr_object == Py_None) {
|
||||
PyErr_SetString(PyExc_TypeError, "weak object has gone away");
|
||||
return -1;
|
||||
}
|
||||
self->hash = PyObject_Hash(self->wr_object);
|
||||
return self->hash;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
weakref_repr(PyWeakReference *self)
|
||||
{
|
||||
|
@ -128,6 +145,25 @@ weakref_repr(PyWeakReference *self)
|
|||
return PyString_FromString(buffer);
|
||||
}
|
||||
|
||||
/* Weak references only support equality, not ordering. Two weak references
|
||||
are equal if the underlying objects are equal. If the underlying object has
|
||||
gone away, they are equal if they are identical. */
|
||||
|
||||
static PyObject *
|
||||
weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
|
||||
{
|
||||
if (op != Py_EQ || self->ob_type != other->ob_type) {
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
if (self->wr_object == Py_None || other->wr_object == Py_None) {
|
||||
PyObject *res = self==other ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
return PyObject_RichCompare(self->wr_object, other->wr_object, op);
|
||||
}
|
||||
|
||||
|
||||
statichere PyTypeObject
|
||||
PyWeakReference_Type = {
|
||||
|
@ -145,16 +181,18 @@ PyWeakReference_Type = {
|
|||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
(hashfunc)weakref_hash, /*tp_hash*/
|
||||
(ternaryfunc)weakref_call, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | Py_TPFLAGS_HAVE_RICHCOMPARE,
|
||||
0, /*tp_doc*/
|
||||
(traverseproc)gc_traverse, /*tp_traverse*/
|
||||
(inquiry)gc_clear, /*tp_clear*/
|
||||
(richcmpfunc)weakref_richcompare, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue