You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SortedMap_new (sortedmap.cpp:284-331) has four interrelated bugs:
1. Double reference leak from PySequence_GetItem (line 325-326)
PySequence_GetItem returns a new reference. These raw PyObject* are passed to setitem() which calls MapItem(key, value) constructor (line 36) that does cppy::incref(key) and cppy::incref(value) — a second incref. Every key and value stored via this path leaks one reference.
Reproducer:
importgc; gc.disable()
importosfromatom.datastructures.sortedmapimportsortedmapclassTrackable:
live=0def__init__(self, val):
Trackable.live+=1; self.val=valdef__del__(self):
Trackable.live-=1def__lt__(self, other): returnself.val<other.valdef__eq__(self, other): returnself.val==other.valpairs= [(Trackable(i), Trackable(i*10)) foriinrange(50)]
m=sortedmap(pairs)
delpairs, mprint(f"After del: {Trackable.live} live (should be 0)")
# After del: 100 live (should be 0) — all 100 objects leakedos._exit(0)
Fix: use cppy::ptr to capture the new references and pass via the MapItem(cppy::ptr&, cppy::ptr&) overload (line 38):
PyDict_Items(map) returns a new reference. It is passed directly to PyObject_GetIter() without being stored — leaked every time a SortedMap is constructed from a dict.
Activity
MatthieuDartiailh commentedon Oct 9, 2026
Closed by #263