Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions apptools/preferences/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 2 additions & 7 deletions apptools/preferences/preferences_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
25 changes: 15 additions & 10 deletions apptools/preferences/tests/preferences_helper_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

Expand Down Expand Up @@ -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

Expand Down