diff --git a/CHANGES.txt b/CHANGES.txt index e4cbdca8f..d8f5c6b48 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,7 +8,7 @@ Enhancements * Apptools now have a changelog! * Preferences system defaults to utf-8 encoded string with ConfigObj providing - better support for unicode in the PreferenceHelper (#41). + better support for unicode in the PreferenceHelper (#41, #45). * Added a traitsified backport of Python 3's lru_cache (#39). * Added PyTables support to the io submodule (#19, #20, and #24 through #34). * Added a SelectionService for managing selections within an application (#15, #16, #17, diff --git a/apptools/preferences/preferences.py b/apptools/preferences/preferences.py index 9a64d6ebc..8a4b8c115 100644 --- a/apptools/preferences/preferences.py +++ b/apptools/preferences/preferences.py @@ -541,6 +541,11 @@ def _remove_preferences_listener(self, listener): def _set(self, key, value): """ Set the value of a preference in this node. """ + + # everything must be unicode encoded so that ConfigObj configuration + # can properly serialize the data. Python str are supposed to be ASCII + # encoded. + value = unicode(value) self._lk.acquire() old = self._preferences.get(key) diff --git a/apptools/preferences/preferences_helper.py b/apptools/preferences/preferences_helper.py index 227bac943..dfe643e7e 100644 --- a/apptools/preferences/preferences_helper.py +++ b/apptools/preferences/preferences_helper.py @@ -128,15 +128,10 @@ def _get_value(self, trait_name, value): trait = self.trait(trait_name) handler = trait.handler - # If the trait type is 'Str' then we just take the raw value. - if isinstance(handler, Str) or trait.is_str: + # If the trait type is 'Str' or Unicode then we just take the raw value. + if isinstance(handler, (Str, Unicode)) or trait.is_str: pass - elif isinstance(handler, Unicode): - # Just in case we get back an ASCII `str` object, convert it to a - # `unicode` object. - value = unicode(value) - # Otherwise, we eval it! else: try: diff --git a/apptools/preferences/tests/preferences_helper_test_case.py b/apptools/preferences/tests/preferences_helper_test_case.py index 305a7a47d..792908343 100644 --- a/apptools/preferences/tests/preferences_helper_test_case.py +++ b/apptools/preferences/tests/preferences_helper_test_case.py @@ -201,7 +201,7 @@ class AcmeUIPreferencesHelper(PreferencesHelper): return def test_real_unicode_values(self): - """ default values """ + """ Test with real life unicode values """ p = self.preferences p.load(self.example) @@ -217,25 +217,30 @@ class AcmeUIPreferencesHelper(PreferencesHelper): width = Int(50) ratio = Float(1.0) visible = Bool(True) - description = Unicode(u'U\xdc\xf2ser') + description = Unicode(u'') offsets = List(Int, [1, 2, 3, 4]) names = List(Str, ['joe', 'fred', 'jane']) helper = AcmeUIPreferencesHelper() + first_unicode_str = u'U\xdc\xf2ser' + first_utf8_str = 'U\xc3\x9c\xc3\xb2ser' + original_description = helper.description - helper.description = u'U\xdc\xf2ser' - self.assertEqual(u'U\xdc\xf2ser', helper.description) + helper.description = first_unicode_str + self.assertEqual(first_unicode_str, helper.description) - helper.description = u'caf\xe9' - self.assertEqual(u'caf\xe9', helper.description) - self.assertEqual(u'caf\xe9', p.get('acme.ui.description')) + second_unicode_str = u'caf\xe9' + second_utf8_str = 'caf\xc3\xa9' + helper.description = second_unicode_str + self.assertEqual(second_unicode_str, helper.description) + self.assertEqual(second_unicode_str, p.get('acme.ui.description')) p.save(self.example) p.load(self.example) - self.assertEqual(u'caf\xe9', p.get('acme.ui.description')) + self.assertEqual(second_unicode_str, p.get('acme.ui.description')) self.assertEqual(u'True', p.get('acme.ui.visible')) self.assertEqual(True, helper.visible) @@ -496,11 +501,11 @@ def _width_changed(self, trait_name, old, new): # ratio to get set via the static trait change handler on the helper. p.set('acme.ui.width', 42) self.assertEqual(42, helper.width) - self.assertEqual(42, p.get('acme.ui.width')) + self.assertEqual('42', p.get('acme.ui.width')) # Did the ratio get changed? self.assertEqual(3.0, helper.ratio) - self.assertEqual(3.0, p.get('acme.ui.ratio')) + self.assertEqual('3.0', p.get('acme.ui.ratio')) return