AttributeError: 'TraitCompound' object has no attribute 'clone'

724 Views Asked by At

Let's say I want to create, using the Traits package, a "bases" attribute that can be a 'none' string or a dictionary with keys which are ‘hrf’ or ‘fourier’ or ‘fourier_han’ or ‘gamma’ or ‘fir’ and with values which are a dictionary with keys which are ‘derivs’ or ‘length' or ‘order’ and with values which are a list or a float). Ex:

bases == 'none'
or
bases == {'hrf': {'derivs': [0, 0]}}
or
bases == {'fourier': {'length': 1.4, 'order': 3}}

if I define a 'none' string or a dictionary with keys which are ‘hrf’ or ‘fourier’ or ‘fourier_han’ or ‘gamma’ or ‘fir’ and with values which are a dictionary with keys which are ‘derivs’ or ‘length' or ‘order’ and with values which are a list) it's working fine:

>>> import traits.api as traits
>>> class Foo(traits.HasTraits):
...  bases = traits.Either(traits.Dict(traits.Enum("hrf","fourier","fourier_han","gamma","fir"),traits.Dict(traits.Enum("derivs","length","order"), traits.List)),'none',default={"hrf":{"derivs":[0,0]}})
... 
>>> foo=Foo()
>>> foo.bases
{'hrf': {'derivs': [0, 0]}}

But this is not exactly what I want. If now I try to give the possibility to use list or float in the inside dictionary, it's not working:

 >>> import traits.api as traits
 >>> class Foo(traits.HasTraits):
...  bases = traits.Either(traits.Dict(traits.Enum("hrf","fourier","fourier_han","gamma","fir"),traits.Dict(traits.Enum("derivs","length","order"), traits.Either(traits.List, traits.Float))),'none',default={"hrf":{"derivs":[0,0]}})
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in Foo
  File "/home/econdami/.local/lib/python3.7/site-packages/traits/trait_types.py", line 2804, in __init__
    handler = handler.clone()
AttributeError: 'TraitCompound' object has no attribute 'clone'

why ?

1

There are 1 best solutions below

0
servoz On BEST ANSWER

It's not the first time I've interact with the team that develops the Traits project.

As always, they very quickly managed to solve the problem and gave a very detailed answer on it.

In a nutshell, as early as Traits 6.1, on the one hand, prefer:

traits.Union(traits.Float, traits.List)

to

traits.Either(traits.Float, traits.List)

On the other hand, pay attention to the default_value argument for Union() (default for Either()). It would be better to initialise it by other means.