Closed mdickinson closed 2 years ago
@sallenEnth Interested in reviewing? (Feel free to unassign yourself from review if not.)
That's unfortunately the part that's not fixed by this PR, and that's much harder to fix in general.
Apologies - looks like I'm wrong about this. So let's keep that test (thank you!), and I need to figure out how this is working when I expected it to fail ...
I need to figure out how this is working when I expected it to fail ...
Got it: the resulting value
from applying deepcopy
to the original TraitListObject
is indeed disconnected from the object, but when we assign that copied value back to the object using setattr
(here), we create a new TraitListObject
that's connected to the newly cloned HasTraits
object.
This PR makes a shallow fix for problems with
clone_traits
applied toList
,Dict
andSet
traits. It doesn't try to touch deeper issues of disconnection ofTraitsListObject
,TraitDictObject
and friends from their owningHasTraits
object.Closes #1622. The cause of that issue is that we were using a function
lambda: None
forobject
where aHasTraits
object was expected. InsideTraitListObject
we then take a weakref to that function. In most cases, thelambda
function has no other references to it, so it's garbage collected immediately and when the weakref is dereferenced, it returnsNone
. But in the deepcopy case the weakref target is kept alive for long enough that we try to use the actuallambda: None
function as aHasTraits
object. The solution is to allow and special-case an object ofNone
in theTraitListObject
constructor.