traits
traits copied to clipboard
Remove default_value_type inference from TraitType subclasses
I've created a series of PRs aimed at bypassing the default_value_type inference code for TraitType
subclasses. See #1531, #1532, #1536.
Code link: https://github.com/enthought/traits/blob/9f934334668c6c0bf1e2866d6a81417275bbc255/traits/trait_type.py#L34-L52
Rationale:
- making Traits less DWIMmy; in general we want to make the Traits codebase more predictable and reduce the number of corner cases with potentially surprising behaviour
- code complexity: if we can remove the
_infer_default_value_type
function completely then some circular import problems go away - the dependence of that function onTraitListObject
,TraitDictObject
andTraitSetObject
in particular is problematic. - performance (minor): in the vast majority of cases we go through the inference code even when it's clear from context that the
default_value_type
should be constant. By settingdefault_value_type
up front we avoid that code path.
Steps:
- [ ] Make sure that none of the built-in TraitType subclasses are using the default value type inference
- [x] Deal with obviously constant defaults: #1531, and a few more in #1539
- [x] Deal with
Any
: #1532 (this is the only case where list and dict default types are of interest) - [x] Deal with
BaseClass
and its subclasses: #1536 (some care required inBaseInstance
) - [x] Deal with
Constant
: #1540 - [x] Deal with
TraitType
subclasses in tests: #1539 - [x] Determine whether
Symbol
needs changes: it doesn't - Symbol is deprecated in #1542 - [x] Deal with
Event
andDisallow
(related: #1546) - [x] Deal with
Delegate
and its subclasses.
- [ ] Loudly deprecate the use of default value type inference for external TraitType subclasses
- [ ] In Traits 7.0, replace
default_value_type = DefaultValue.unspecified
withdefault_value_type = DefaultValue.constant
in theTraitType
base class, and clean up the other classes accordingly.
After #1531, #1532, #1536 and #1539, the following TraitType
subclasses still make use of the type inference. (This list may not be exhaustive - it only covers the trait types for which the default value is exercised by the test suite.)
Constant
Delegate (and its subclasses)
Disallow
Event
ReadOnly
You seem to have missed AbstractArray
here.
Yes, I need to look into that. I find it hard to believe that we never access the default value for an Array
trait within the test suite.
Ah, AbstractArray
overrides get_default_value
, so it never encounters that code. So there's nothing to do for AbstractArray
and its subclasses.
The other notable oddity is Either
, which overrides the as_ctrait
method, so also doesn't invoke TraitType.get_default_value
. (It's possible that Either
shouldn't be a TraitType
subclass at all.)
Constant
is dealt with in #1540; Readonly
is addressed in an updated version of #1531. That just leaves Event
, Disallow
, and Delegate
and its subclasses.
As another check, here are the registered (direct) subclasses of TraitType
after the end of the test run:
>>> [cls.__name__ for cls in TraitType.__subclasses__() if cls.default_value_type == DefaultValue.unspecified]
['Disallow', 'Delegate', 'Event', 'Either', 'Symbol', 'UUID', 'AbstractArray']
As discussed above, Either
and AbstractArray
don't need any change. UUID
similarly overrides get_default_value
, so doesn't make any use of the default_value_type
attribute and doesn't need any change. Symbol
may need some work.
Bumping the remainder of this for 6.4.0