diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 000000000..5ecf9f05a --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,20 @@ +Apptools CHANGELOG +================== + +Change summary since 4.2.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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). + +Changes + + * + +Fixes + + * + diff --git a/apptools/preferences/preferences.py b/apptools/preferences/preferences.py index 5c76649d2..9a64d6ebc 100644 --- a/apptools/preferences/preferences.py +++ b/apptools/preferences/preferences.py @@ -362,7 +362,7 @@ def load(self, file_or_filename=None): # use a different persistence mechanism). from configobj import ConfigObj - config_obj = ConfigObj(file_or_filename) + config_obj = ConfigObj(file_or_filename, encoding='utf-8') # 'name' is the section name, 'value' is a dictionary containing the # name/value pairs in the section (the actual preferences ;^). @@ -398,7 +398,7 @@ def save(self, file_or_filename=None): logger.debug('saving preferences to <%s>', file_or_filename) - config_obj = ConfigObj(file_or_filename) + config_obj = ConfigObj(file_or_filename, encoding='utf-8') self._add_node_to_dictionary(self, config_obj) config_obj.write() @@ -542,9 +542,6 @@ def _remove_preferences_listener(self, listener): def _set(self, key, value): """ Set the value of a preference in this node. """ - # Preferences are *always* stored as strings. - value = str(value) - self._lk.acquire() old = self._preferences.get(key) self._preferences[key] = value diff --git a/apptools/preferences/preferences_helper.py b/apptools/preferences/preferences_helper.py index 9b4770e65..227bac943 100644 --- a/apptools/preferences/preferences_helper.py +++ b/apptools/preferences/preferences_helper.py @@ -132,9 +132,10 @@ def _get_value(self, trait_name, value): if isinstance(handler, Str) or trait.is_str: pass - # If the trait type is 'Unicode' then we convert the raw value. elif isinstance(handler, Unicode): - value = unicode(value) + # Just in case we get back an ASCII `str` object, convert it to a + # `unicode` object. + value = unicode(value) # Otherwise, we eval it! else: diff --git a/apptools/preferences/tests/preferences_helper_test_case.py b/apptools/preferences/tests/preferences_helper_test_case.py index eeb1a31fb..305a7a47d 100644 --- a/apptools/preferences/tests/preferences_helper_test_case.py +++ b/apptools/preferences/tests/preferences_helper_test_case.py @@ -200,6 +200,49 @@ class AcmeUIPreferencesHelper(PreferencesHelper): return + def test_real_unicode_values(self): + """ default values """ + + p = self.preferences + p.load(self.example) + + class AcmeUIPreferencesHelper(PreferencesHelper): + """ A helper! """ + + # The path to the preferences node that contains our preferences. + preferences_path = 'acme.ui' + + # The traits that we want to initialize from preferences. + bgcolor = Str('blue') + width = Int(50) + ratio = Float(1.0) + visible = Bool(True) + description = Unicode(u'U\xdc\xf2ser') + offsets = List(Int, [1, 2, 3, 4]) + names = List(Str, ['joe', 'fred', 'jane']) + + helper = AcmeUIPreferencesHelper() + + original_description = helper.description + helper.description = u'U\xdc\xf2ser' + self.assertEqual(u'U\xdc\xf2ser', helper.description) + + + helper.description = u'caf\xe9' + self.assertEqual(u'caf\xe9', helper.description) + self.assertEqual(u'caf\xe9', 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(u'True', p.get('acme.ui.visible')) + self.assertEqual(True, helper.visible) + + # reset the original description and save the example file + helper.description = original_description + p.save(self.example) + def test_no_preferences_path(self): """ no preferences path """ @@ -453,11 +496,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