remove_trait does not remove listeners for extended traits
- 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.