@@ -632,9 +632,45 @@ Object Protocol
632
632
}
633
633
return 0;
634
634
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
+
638
674
639
675
.. versionadded :: 3.14
640
676
0 commit comments