Armin Rigo | d77ef8f | 2006-06-28 10:49:51 +0000 | [diff] [blame] | 1 | """ |
| 2 | gc.get_referrers() can be used to see objects before they are fully built. |
Armin Rigo | 4df7c0a | 2006-07-25 18:09:57 +0000 | [diff] [blame] | 3 | |
| 4 | Note that this is only an example. There are many ways to crash Python |
| 5 | by using gc.get_referrers(), as well as many extension modules (even |
| 6 | when they are using perfectly documented patterns to build objects). |
| 7 | |
| 8 | Identifying and removing all places that expose to the GC a |
| 9 | partially-built object is a long-term project. A patch was proposed on |
| 10 | SF specifically for this example but I consider fixing just this single |
| 11 | example a bit pointless (#1517042). |
| 12 | |
| 13 | A fix would include a whole-scale code review, possibly with an API |
| 14 | change to decouple object creation and GC registration, and according |
| 15 | fixes to the documentation for extension module writers. It's unlikely |
| 16 | to happen, though. So this is currently classified as |
| 17 | "gc.get_referrers() is dangerous, use only for debugging". |
Armin Rigo | d77ef8f | 2006-06-28 10:49:51 +0000 | [diff] [blame] | 18 | """ |
| 19 | |
| 20 | import gc |
| 21 | |
| 22 | |
| 23 | def g(): |
| 24 | marker = object() |
| 25 | yield marker |
| 26 | # now the marker is in the tuple being constructed |
| 27 | [tup] = [x for x in gc.get_referrers(marker) if type(x) is tuple] |
| 28 | print tup |
| 29 | print tup[1] |
| 30 | |
| 31 | |
| 32 | tuple(g()) |