chained cached properties get evaluated too often
- Dominant language
- Python
- Stars
- 462
- Forks
- 90
- PR merge metrics
- No merged PRs in 30d
Description
When a cached property depends on an intermediate cached property, the intermediate property gets immediately evaluated when it's dependencies change. This is suboptimal, as cached properties are typically expensive to compute and therefore should only be computed when needed. In particular, during object construction, when the object is unlikely to be in a valid state anyway, properties are likely to be called several times. Take the following example:
```
class Test(HasTraits):
a = Int
b = Int
c = Property(depends_on='a,b')
d = Property(depends_on='a,c')
e = Property(depends_on='c,d')
@cached_property
def _get_c(self):
print('Test._get_c')
return self.a*self.b
@cached_property
def _get_d(self):
print('Test._get_d')
return self.a*self.c
@cached_property
def _get_e(self):
print('Test._get_e')
return self.c+self.d
t = Test(a=1,b=2)
```
This will print
```
Test._get_c
Test._get_d
Test._get_c
Test._get_d
```
so two calls each, without really needed at all.
The reason is of course the same as in issue #94: The traits notification invalidating the chained property's cache triggers the computation of the `old` value of the intermediate property. However, contrary to the general case, here one could solve this by always traversing the dependency chain to it's end, i.e. in the example above, both `d` and `e` should `depends_on='a,b'` instead. However, it would be nice if traits would do this for us automatically, as in some cases these properties could be on different objects, and encapsulation should not require us to know if these traits on the other object are actually properties or not, or on what traits these depend.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.