enthought / enthought/traits

`@on_trait_change` decorator is not lazy (and a special case of the same issue)

Open
#94 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
462
Forks
90
PR merge metrics
No merged PRs in 30d

Description

The `@on_trait_change` decorator is not lazy, which means that even if we provide a default value for a trait, the `_traitname_default` method is called on intialization.

I have two examples:

1) Consider the class

```
class B(HasTraits):
a = Any
def _a_default(self):
print 'INIT a'
return 42

>>> y=B(a=1)
```

This, as I expected, doesn't output anything.

Now if we add a `on_trait_change` decorator:

```
class A(HasTraits):
a = Any
def _a_default(self):
print 'INIT a'
return 42

@on_trait_change('a')
def _do_something(self):
print 'a CHANGED'

>>> x = A(a=1)
INIT a
a CHANGED
```

Here the 'a' default initializer is called.

2) A variant of the above behavior:

```
class X(HasTraits):
x = Float(12)

class A(HasTraits):
a = Instance(X)

def _a_default(self):
print 'INIT a'
return X()

@on_trait_change('a:x')
def _do_something(self):
print 'a:x CHANGED'

y = X(x=1)
b = A(a=y)
INIT a
```

The `_a_default` method is still called, even though the listener itself is not called.

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.