You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
trait_names: ['trait_added', 'trait_modified']
observed: TraitChangeEvent(object=<__main__.AClass object at 0x7f4031f304a0>, name='trait_added', old=<undefined>, new='a')
hasattr: False
trait_names: ['trait_added', 'trait_modified', 'a']
is 'a' in dir(inst)?: True
class traits of inst: dict_keys(['trait_added', 'trait_modified', 'a'])
As one can see, after calling hasattr a new trait is added for the missing attribute 'a', it appears in the list of trait_names as well, but calling getattr now would cause an AttributeError.
Furthermore, using a different expression in the observer changes this behavior:
...
inst.observe(observer, "trait_added")
...
trait_names: ['trait_added', 'trait_modified']
observed: TraitChangeEvent(object=<__main__.AClass object at 0x7f2068cf1450>, name='trait_added', old=<undefined>, new='a')
hasattr: False
trait_names: ['trait_added', 'trait_modified']
is 'a' in dir(inst)?: False
class traits of inst: dict_keys(['trait_added', 'trait_modified', 'a'])
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 and trait_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?
The text was updated successfully, but these errors were encountered:
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?
The text was updated successfully, but these errors were encountered: