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