From 82842821abb1daed99c5e6fc67cb53dd1f753804 2012-09-11 22:20:09 From: Min RK Date: 2012-09-11 22:20:09 Subject: [PATCH] Merge pull request #2311 from minrk/trait_change always perform requested trait assignments Some assignments do not change value, but do change the object, and these should not be ignored. For instance, container objects are currently impossible to assign if they evaluate as equal, even if their types don't match (e.g. assigning an empty defaultdict to a Dict trait, which prompted this PR). --- diff --git a/IPython/utils/tests/test_traitlets.py b/IPython/utils/tests/test_traitlets.py index ef9024b..6f1592a 100644 --- a/IPython/utils/tests/test_traitlets.py +++ b/IPython/utils/tests/test_traitlets.py @@ -25,10 +25,11 @@ import re import sys from unittest import TestCase +import nose.tools as nt from nose import SkipTest from IPython.utils.traitlets import ( - HasTraits, MetaHasTraits, TraitType, Any, CBytes, + HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict, Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError, Undefined, Type, This, Instance, TCPAddress, List, Tuple, ObjectName, DottedObjectName, CRegExp @@ -906,3 +907,14 @@ class TestCRegExp(TraitTestBase): _default_value = re.compile(r'') _good_values = [r'\d+', re.compile(r'\d+')] _bad_values = [r'(', None, ()] + +class DictTrait(HasTraits): + value = Dict() + +def test_dict_assignment(): + d = dict() + c = DictTrait() + c.value = d + d['a'] = 5 + nt.assert_equal(d, c.value) + nt.assert_true(c.value is d) diff --git a/IPython/utils/traitlets.py b/IPython/utils/traitlets.py index 8a40133..cd08d4b 100644 --- a/IPython/utils/traitlets.py +++ b/IPython/utils/traitlets.py @@ -309,8 +309,8 @@ class TraitType(object): def __set__(self, obj, value): new_value = self._validate(obj, value) old_value = self.__get__(obj) + obj._trait_values[self.name] = new_value if old_value != new_value: - obj._trait_values[self.name] = new_value obj._notify_trait(self.name, old_value, new_value) def _validate(self, obj, value):