Static default value in Either not transformed for container
- Dominant language
- Python
- Stars
- 462
- Forks
- 90
- PR merge metrics
- No merged PRs in 30d
Description
Similar issue compared to #1131 but for `Either`.
When the static default value is a container, the default value is not transformed to `TraitListObject` (or friends). Subsequently, validation is not carried out for mutations on the default container.
This issue exists since at least Traits 5.0.0
Of all the tests below, only the ones for dynamic default pass. The other tests fail with "TraitError not raised", because the default container is not converted to `TraitListObject` or `TraitDictObject`.
Tests for default value handling for Either
```
import unittest
from traits.api import Dict, Either, HasTraits, List, Str, TraitError
class TestEither(unittest.TestCase):
def test_either_with_default_constant(self):
class Foo(HasTraits):
str_or_list = Either(Str(), List(), default="now")
foo = Foo()
self.assertEqual(foo.str_or_list, "now")
def test_either_with_static_default_list_value(self):
class Foo(HasTraits):
str_or_list_of_str = Either(Str(), List(Str), default=["now"])
foo = Foo()
self.assertEqual(foo.str_or_list_of_str, ["now"])
with self.assertRaises(TraitError):
foo.str_or_list_of_str.append(1)
def test_either_with_dynamic_default_list_value(self):
class Foo(HasTraits):
str_or_list_of_str = Either(Str(), List(Str))
def _str_or_list_of_str_default(self):
return ["now"]
foo = Foo()
self.assertEqual(foo.str_or_list_of_str, ["now"])
with self.assertRaises(TraitError):
foo.str_or_list_of_str.append(1)
def test_either_with_subclass_default_list_value(self):
class BaseClass(HasTraits):
str_or_list_of_str = Either(Str(), List(Str))
class Foo(BaseClass):
str_or_list_of_str = ["now"]
foo = Foo()
self.assertEqual(foo.str_or_list_of_str, ["now"])
with self.assertRaises(TraitError):
foo.str_or_list_of_str.append(1)
def test_either_with_static_default_dict_value(self):
class Foo(HasTraits):
str_or_dict_of_str = Either(Str(), Dict(Str), default={"now": 0})
foo = Foo()
self.assertEqual(foo.str_or_dict_of_str, {"now": 0})
with self.assertRaises(TraitError):
foo.str_or_dict_of_str[1] = 1
def test_either_with_dynamic_default_dict_value(self):
class Foo(HasTraits):
str_or_dict_of_str = Either(Str(), Dict(Str))
def _str_or_dict_of_str_default(self):
return {"now": 0}
foo = Foo()
self.assertEqual(foo.str_or_dict_of_str, {"now": 0})
with self.assertRaises(TraitError):
foo.str_or_dict_of_str[1] = 1
def test_either_with_subclass_default_dict_value(self):
class BaseClass(HasTraits):
str_or_dict_of_str = Either(Str(), Dict(Str))
class Foo(BaseClass):
str_or_dict_of_str = {"now": 0}
foo = Foo()
self.assertEqual(foo.str_or_dict_of_str, {"now": 0})
with self.assertRaises(TraitError):
foo.str_or_dict_of_str[1] = 1
```
Test failures
```
======================================================================
FAIL: test_either_with_static_default_dict_value (traits.tests.test_either.TestEither)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kchoi/Work/ETS/traits/traits/tests/test_either.py", line 83, in test_either_with_static_default_dict_value
foo.str_or_dict_of_str[1] = 1
AssertionError: TraitError not raised
======================================================================
FAIL: test_either_with_static_default_list_value (traits.tests.test_either.TestEither)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kchoi/Work/ETS/traits/traits/tests/test_either.py", line 40, in test_either_with_static_default_list_value
foo.str_or_list_of_str.append(1)
AssertionError: TraitError not raised
======================================================================
FAIL: test_either_with_subclass_default_dict_value (traits.tests.test_either.TestEither)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kchoi/Work/ETS/traits/traits/tests/test_either.py", line 114, in test_either_with_subclass_default_dict_value
foo.str_or_dict_of_str[1] = 1
AssertionError: TraitError not raised
======================================================================
FAIL: test_either_with_subclass_default_list_value (traits.tests.test_either.TestEither)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kchoi/Work/ETS/traits/traits/tests/test_either.py", line 71, in test_either_with_subclass_default_list_value
foo.str_or_list_of_str.append(1)
AssertionError: TraitError not raised
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.