[Martin v. Löwis] > Hmmm. Even if a ring member holds only a single reference to another > ring member, would not calling visit() on this member in turn invoke > visit() on the other one, which would, in turn, invoke visit() on > the next one, and so on? Yes, but not recursively (which that description appears to imply), and not because of what's passed *to* visit(). More precisely, visit(some_pointer) does different things during different phases of gc (different phases pass different gcmodule.c callback functions to tp_traverse() implementations). None of them lead to recursive calls to the callback. Maybe a bit ironically, refcount-based deletion can require unbounded stack depth (hence the "trashcan" mechanism to avoid blowing the C stack), but Python's cyclic gc isn't recursive at all. I'm guessing that Jason is confusing the update_refs() and subtract_refs() phases of Python's gc with the "mark" phase of a mark/sweep collector. If so, the visit() callbacks used by those are actually irrelevant to the set of objects whose tp_traverse() is called during those phases. The tp_traverse() of *every* object in the generation being collected is invoked by that pair of phases, and the set of objects passed *to* the visit callbacks during those phases has no effect on the set of objects whose tp_traverse() gets called during those phases. So one of Jason's objects will get its tp_traverse() called by those phases if and only if it's in the generation currently being collected, and it's currently tracked by gc. It doesn't matter whether, e.g., anything points at it, or whether it points at anything (although if nothing anywhere points at it, it would already have been destroyed via refcounting).
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4