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