Index: django/newforms/fields.py
===================================================================
--- django/newforms/fields.py	(revision 6251)
+++ django/newforms/fields.py	(working copy)
@@ -479,6 +479,10 @@
         # choices can be any iterable, but we call list() on it because
         # it will be consumed more than once.
         self._choices = self.widget.choices = list(value)
+        # Build an index mapping the unicode value of each choice key to the
+        # original key. Strings are forced to unicode as per django policy, 
+        # but other types are left alone.
+        self._choices_idx = dict([(smart_unicode(k),(isinstance(k, str) and unicode(k) or k)) for k, v in self._choices])
 
     choices = property(_get_choices, _set_choices)
 
@@ -492,10 +496,10 @@
         value = smart_unicode(value)
         if value == u'':
             return value
-        valid_values = set([smart_unicode(k) for k, v in self.choices])
-        if value not in valid_values:
+        
+        if value not in self._choices_idx:
             raise ValidationError(ugettext(u'Select a valid choice. That choice is not one of the available choices.'))
-        return value
+        return self._choices_idx[value]
 
 class MultipleChoiceField(ChoiceField):
     hidden_widget = MultipleHiddenInput
@@ -511,13 +515,11 @@
             return []
         if not isinstance(value, (list, tuple)):
             raise ValidationError(ugettext(u'Enter a list of values.'))
-        new_value = [smart_unicode(val) for val in value]
         # Validate that each value in the value list is in self.choices.
-        valid_values = set([smart_unicode(k) for k, v in self.choices])
-        for val in new_value:
-            if val not in valid_values:
-                raise ValidationError(ugettext(u'Select a valid choice. %s is not one of the available choices.') % val)
-        return new_value
+        try:
+            return [self._choices_idx[smart_unicode(val)] for val in value] 
+        except KeyError:
+            raise ValidationError(ugettext(u'Select a valid choice. %s is not one of the available choices.') % val)
 
 class ComboField(Field):
     """
Index: tests/regressiontests/forms/tests.py
===================================================================
--- tests/regressiontests/forms/tests.py	(revision 6251)
+++ tests/regressiontests/forms/tests.py	(working copy)
@@ -1795,6 +1795,27 @@
 ...
 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
 
+>>> class TestX(object):
+...     def __unicode__(self):
+...         return u'TestX-U'
+...     def __str__(self):
+...         return 'TestX-S'
+>>> f = ChoiceField(choices=[(1, '1'), (True, 'Good'), (TestX(), 'X')])
+>>> f.clean('1')
+1
+>>> f.clean('True')
+True
+>>> type(f.clean('TestX-U'))
+<class '__main__.TestX'>
+>>> f.clean('TestX-S')
+Traceback (most recent call last):
+...
+ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
+>>> f.clean(True)
+True
+>>> f.clean(1)
+1
+
 # NullBooleanField ############################################################
 
 >>> f = NullBooleanField()
@@ -1875,6 +1896,27 @@
 ...
 ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
 
+>>> class TestX(object):
+...     def __unicode__(self):
+...         return u'TestX-U'
+...     def __str__(self):
+...         return 'TestX-S'
+>>> f = MultipleChoiceField(choices=[(1, '1'), (True, 'Good'), (TestX(), 'X')])
+>>> f.clean(['1'])
+[1]
+>>> f.clean(['True'])
+[True]
+>>> type(f.clean(['TestX-U'])[0])
+<class '__main__.TestX'>
+>>> f.clean(['TestX-S'])
+Traceback (most recent call last):
+...
+ValidationError: [u'Select a valid choice. TestX-S is not one of the available choices.']
+>>> f.clean(['True', '1'])
+[True, 1]
+>>> f.clean([True, 1])
+[True, 1]
+
 # ComboField ##################################################################
 
 ComboField takes a list of fields that should be used to validate a value,
Index: tests/regressiontests/forms/regressions.py
===================================================================
--- tests/regressiontests/forms/regressions.py	(revision 6251)
+++ tests/regressiontests/forms/regressions.py	(working copy)
@@ -53,6 +53,13 @@
 >>> f.clean('\xd1\x88\xd1\x82.')
 u'\u0448\u0442.'
 
+>>> UNITS = ((u'\u043c\u0435\u0441.', u'\u043c\u0435\u0441.'), (u'\u0448\u0442.', u'\u0448\u0442.'))
+>>> f = ChoiceField(choices=UNITS)
+>>> f.clean(u'\u0448\u0442.')
+u'\u0448\u0442.'
+>>> f.clean('\xd1\x88\xd1\x82.')
+u'\u0448\u0442.'
+
 Translated error messages used to be buggy.
 >>> activate('ru')
 >>> f = SomeForm({})
