Using a function as a default for a Callable in a child class fails
- Dominant language
- Python
- Stars
- 462
- Forks
- 90
- PR merge metrics
- No merged PRs in 30d
Description
I have a `HasTraits` class with some `Callable` traits, and a second class that derives from it. I was trying to set the defaults for these traits as class variables, but I noticed that sometimes these defaults didn't get applied. The following example will make this clear. Here I have two Callables in the base class, and one is initialized in the derived class with a builtin function and one with a regular function. The latter does not get applied.
```python
from traits.api import HasStrictTraits, Callable
def regular_fun():
pass
builtin_fun = print
class A(HasStrictTraits):
f1 = Callable()
f2 = Callable()
class B(A):
f1 = builtin_fun
f2 = regular_fun
if __name__ == '__main__':
b = B()
assert b.f1 is not None
assert b.f2 is not None
```
Under the tested version (4.6.0) the first assert passes (as expected), but the second assert fails (`b.f2` is None).
This is because in `MetaHasTraitsObject` we check whether items in the class_dict are functions: https://github.com/enthought/traits/blob/b5cf152c446bb87d575b5ecdc4cda7f8b646d96f/traits/has_traits.py#L550-L553
Builtin functions don't pass this check, but regular functions do. So `f2` gets treated in this block and ultimately ignored, but `f1` skips this block and ends up in the `else` where we look at inherited class traits:
https://github.com/enthought/traits/blob/b5cf152c446bb87d575b5ecdc4cda7f8b646d96f/traits/has_traits.py#L577-L590
Here, `builtin_fun` gets correctly set as the default for `f1`, but `f2` has already been treated and therefore keeps it None default.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.