Skip to content

Commit 405952c

Browse files
encukoucolesbury
authored andcommitted
Add an example sketch from Petr Viktorin
1 parent 37a08dc commit 405952c

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

Doc/c-api/object.rst

+39-3
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,45 @@ Object Protocol
632632
}
633633
return 0;
634634
635-
This is intended as a building block for safely dealing with
636-
:term:`borrowed references <borrowed reference>` without the overhead of
637-
creating a :c:type:`!PyWeakReference`.
635+
This is intended as a building block for managing weak references
636+
without the overhead of a Python :c:type:`!PyWeakReference`.
637+
Typically, correct use of this function requires support from *obj*'s
638+
deallocator (:c:member:`~PyTypeObject.tp_dealloc`).
639+
For example, the following sketch could be adapted to implement a
640+
"weakmap" that works like a :py:class:`~weakref.WeakValueDictionary`
641+
for a specific type:
642+
643+
.. code-block:: c
644+
645+
PyObject *
646+
get_value(weakmap_key_type *key)
647+
{
648+
weakmap_type weakmap = ...;
649+
weakmap_lock_mutex(weakmap);
650+
PyObject *result = weakmap_find(weakmap, key);
651+
if (PyUnstable_TryIncRef(result)) {
652+
// `result` is safe to use
653+
weakmap_unlock_mutex(weakmap);
654+
return result;
655+
}
656+
// if we get here, `result` is starting to be garbage-collected,
657+
// but has not been removed from the weakmap yet
658+
weakmap_unlock_mutex(weakmap->mutex);
659+
return NULL;
660+
}
661+
662+
// tp_dealloc function for weakmap values
663+
void
664+
value_dealloc(PyObject *value)
665+
{
666+
weakmap_type weakmap = ...;
667+
weakmap_lock_mutex(weakmap);
668+
weakmap_remove_value(weakmap, value);
669+
670+
...
671+
weakmap_unlock_mutex(weakmap);
672+
}
673+
638674
639675
.. versionadded:: 3.14
640676

0 commit comments

Comments
 (0)