Open felixkol opened 1 year ago
Thanks for the report. It's not exactly intended behaviour (it's clearly not desirable), but it is behaviour that's fairly deeply baked in, and hard to change without breaking existing code (and unfortunately there's a lot of existing Traits-using code out there). Existing issues #358 and #58 are related.
Slightly simpler reproducer:
>>> class A(HasStrictTraits):
... bar = Int()
...
>>> a = A()
>>> "foo" in a.__class_traits__
False
>>> "foo" in a.__class_traits__
False
>>> a.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'foo'
>>> "foo" in a.__class_traits__
True
Wouldn't it be possible to split getting and setting prefix traits?
On getting, a value would be returned, when it has been set or the prefix trait has a default value. On the latter case, the prefixed trait could be created. Setting would work just as it is currently.
Then no trait would exist where getting raises an exception.
Would this break the current functionality of prefix traits?
I have observed some weird behavior when calling
hasattr
with a nonexistent attribute. Assume the following as a minimal example:Yields:
As one can see, after calling
hasattr
a new trait is added for the missing attribute 'a', it appears in the list oftrait_names
as well, but callinggetattr
now would cause anAttributeError
.Furthermore, using a different expression in the observer changes this behavior:
Now, the name of the missing attribute isn't added to the 'trait_names', but the attribute is still created as a class trait.
To my understanding, getting a value should not have such side effects, especially if getting the now appearing attribute in
trait_names
causes an error.hasattr
andtrait_names
should not contradict each other, but the dependents of the observation expression makes this even less deterministic.Am I using traits wrong at this point, is this intended behavior or is it a bug?