matt matt - 21 days ago 9
Python Question

Property-Trait with "depends_on"

Given traits-based classes Material-class, Base-class and Child-class (derived from the Base-class), the following code runs if the Property-trait

b
of the Child-class depends_on only
a
or
x
attributes, i.e.

b = Property(Float, depends_on=['a'])


or

b = Property(Float, depends_on=['x'])


but not if it depends on both:

b = Property(Float, depends_on=['a','x'])


Why?

from traits.api import HasTraits, DelegatesTo, Float, Instance, Range, Property

class Material(HasTraits):
a = Float(10)

class Base(HasTraits):
x = Float(-1)

class Child(Base):
m = Instance(Material)
a = DelegatesTo('m')
# b = Property(Float, depends_on=['a']) # <-- runs
# b = Property(Float, depends_on=['x']) # <-- runs
b = Property(Float, depends_on=['a','x']) # <-- fails

def _get_b(self):
return self.a * self.x

c = Child(m=Material())

Answer

You can solve that by not using a DelegatesTo and only listen to changes on m.a:

class Child(Base):
    m = Instance(Material)
    b = Property(Float, depends_on=['m.a','x'])   # <-- runs

    def _get_b(self):
        return self.a * self.x

The issue with the delegate seems related to set up the listener. The error message I get is

DelegationError: The 'a' attribute of a 'Child' object has a delegate which does not have traits..