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