traits
traits copied to clipboard
Reference cycles in TraitListObject
After code resembling this:
class Model(HasStrictTraits):
foo = List()
model = Model()
my_list = model.foo
my_list
is now an object of type TraitListObject
, and is involved in the following reference cycle:
We should see if we can find a way to eliminate the reference cycle. (If it's easy to do so, we should definitely do it. If it turns out to be hard to do reliably, then we'll have to think about what the best path forward is.)
Marking as a bug: this is a regression since 6.0.0, where there was no reference cycle.
For future reference, here's the full script I ran to find the cycle above. It needs refcycle
installed, and Graphviz needs to be installed for the export_image
call to work.
import refcycle
from traits.api import HasStrictTraits, List
class Model(HasStrictTraits):
foo = List()
def main():
my_list = Model(foo=[1, 2, 3]).foo
snapshot = refcycle.snapshot()
scc = next(scc for scc in snapshot.strongly_connected_components() if my_list in scc)
scc.export_image()
if __name__ == "__main__":
main()
EDIT: script simplified
We should also check TraitDictObject
and TraitSetObject
for similar cycles.
Quick findings: it's relatively easy to fix this; the only fly in the ointment is pickling support, but I'm not convinced that pickling of a TraitListObject
has ever worked properly anyway.
Proof of concept in the cycle-fixes branch. I don't have time to develop this further right now.
I took another stab at this recently, and came to the same conclusion as last time around. It's relatively easy to fix, so long as you don't care about pickling and unpickling. Once you start trying to get pickling and unpickling to work, it becomes much messier to fix.
Anyway, we're not going to get to a fix for this in this release.