14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgc.get_referrers() can be used to see objects before they are fully built. 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNote that this is only an example. There are many ways to crash Python 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmby using gc.get_referrers(), as well as many extension modules (even 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwhen they are using perfectly documented patterns to build objects). 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIdentifying and removing all places that expose to the GC a 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpartially-built object is a long-term project. A patch was proposed on 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSF specifically for this example but I consider fixing just this single 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexample a bit pointless (#1517042). 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmA fix would include a whole-scale code review, possibly with an API 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmchange to decouple object creation and GC registration, and according 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfixes to the documentation for extension module writers. It's unlikely 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmto happen, though. So this is currently classified as 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"gc.get_referrers() is dangerous, use only for debugging". 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport gc 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef g(): 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm marker = object() 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm yield marker 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # now the marker is in the tuple being constructed 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [tup] = [x for x in gc.get_referrers(marker) if type(x) is tuple] 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print tup 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print tup[1] 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtuple(g()) 33