enthought / enthought/traits

remove_trait does not remove listeners for extended traits

Open
#1,047 7 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
Python
Stars
462
Forks
90
PR merge metrics
No merged PRs in 30d

Description

Consider this:
```python
from traits.api import HasTraits, Instance, Str

class Foo(HasTraits):
name = Str()

def handler(object, name, old, new):
print("Changed!", (object, name, old, new))

foo = Foo()
foo.add_trait("child", Instance(Foo))
foo.on_trait_change(handler, "child:name")
```

The following behaviour is good:
```
child = Foo()
foo.child = child
foo.child.name = "Martin"
# Changed! (<__main__.Foo object at 0x10457bb30>, 'name', '', 'Martin')
```

This is not expected:
```
foo.remove_trait("child")
child.name = "Paul"
# Changed! (<__main__.Foo object at 0x10457bb30>, 'name', 'Martin', 'Paul')
```

The listener is still gone, so adding the trait again won't bring it back, which is ~good and expected~ Edited: also unexpected.
```
foo.add_trait("child", Instance(Foo))
foo.child = Foo()
foo.child.name = "Joanna"
# Nothing is printed.
```

The second notification (where name is changed from "Martin" to "Paul") is unexpected.
While `add_trait` emits a change event on `trait_added`, `remove_trait` does not emit any events. I believe if `remove_trait` also emits an event for when a trait is removed, it would be possible for the listeners to be unhooked from the removed object.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.