diff --git a/traits-stubs/traits-stubs/trait_types.pyi b/traits-stubs/traits-stubs/trait_types.pyi index 46d9543b3..00bdef73e 100644 --- a/traits-stubs/traits-stubs/trait_types.pyi +++ b/traits-stubs/traits-stubs/trait_types.pyi @@ -27,7 +27,6 @@ from uuid import UUID as _UUID from .trait_type import _TraitType -MutableTypes: _Any SetTypes: _Any int_fast_validate: _Any float_fast_validate: _Any diff --git a/traits/tests/test_constant.py b/traits/tests/test_constant.py new file mode 100644 index 000000000..5ad091947 --- /dev/null +++ b/traits/tests/test_constant.py @@ -0,0 +1,54 @@ +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! + + +import unittest + +from traits.api import Constant, HasTraits, TraitError + + +class TestConstantTrait(unittest.TestCase): + + def test_initial_value(self): + class TestClass(HasTraits): + c_atr = Constant(5) + + self.assertEqual(TestClass().c_atr, 5) + + def test_mutable_initial_value(self): + class TestClass(HasTraits): + c_atr_1 = Constant([1, 2, 3, 4, 5]) + c_atr_2 = Constant({"a": 1, "b": 2}) + + obj = TestClass() + + self.assertEqual(obj.c_atr_1, [1, 2, 3, 4, 5]) + self.assertEqual(obj.c_atr_2, {"a": 1, "b": 2}) + + def test_assign_fails(self): + class TestClass(HasTraits): + c_atr = Constant(5) + + with self.assertRaises(TraitError): + TestClass(c_atr=5) + with self.assertRaises(TraitError): + del TestClass().c_atr + + def test_mutate_succeeds(self): + class TestClass(HasTraits): + c_atr_1 = Constant([1, 2, 3, 4, 5]) + c_atr_2 = Constant({"a": 1, "b": 2}) + + obj = TestClass() + obj.c_atr_1.append(6) + obj.c_atr_2["c"] = 3 + + self.assertEqual(obj.c_atr_1, [1, 2, 3, 4, 5, 6]) + self.assertEqual(obj.c_atr_2, {"a": 1, "b": 2, "c": 3}) diff --git a/traits/trait_types.py b/traits/trait_types.py index b8b33a155..b2f8bbb8b 100644 --- a/traits/trait_types.py +++ b/traits/trait_types.py @@ -69,7 +69,6 @@ # Constants -MutableTypes = (list, dict) SetTypes = SequenceTypes + (set,) # Numeric type fast validator definitions @@ -1012,12 +1011,11 @@ class Constant(TraitType): Traits of this type are very space efficient (and fast) because *value* is not stored in each instance using the trait, but only in - the trait object itself. The *value* cannot be a list or dictionary, - because those types have mutable values. + the trait object itself. Parameters ---------- - value : any type other than list or dict + value : any The constant value for the trait. **metadata Trait metadata for the trait. @@ -1029,14 +1027,6 @@ class Constant(TraitType): #: The standard metadata for the trait: metadata = {"type": "constant", "transient": True} - def __init__(self, value, **metadata): - if type(value) in MutableTypes: - raise TraitError( - "Cannot define a constant using a mutable list or dictionary" - ) - - super(Constant, self).__init__(value, **metadata) - class Delegate(TraitType): """ A trait type whose value is delegated to a trait on another object.