Loading django/forms/widgets.py +3 −3 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ from itertools import chain from django.conf import settings from django.forms.utils import flatatt, to_current_timezone from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.html import conditional_escape, format_html from django.utils.translation import ugettext_lazy Loading Loading @@ -319,7 +319,7 @@ class MultipleHiddenInput(HiddenInput): return mark_safe('\n'.join(inputs)) def value_from_datadict(self, data, files, name): if isinstance(data, (MultiValueDict, MergeDict)): if isinstance(data, MultiValueDict): return data.getlist(name) return data.get(name, None) Loading Loading @@ -587,7 +587,7 @@ class SelectMultiple(Select): return mark_safe('\n'.join(output)) def value_from_datadict(self, data, files, name): if isinstance(data, (MultiValueDict, MergeDict)): if isinstance(data, MultiValueDict): return data.getlist(name) return data.get(name, None) Loading django/utils/datastructures.py +0 −115 Original line number Diff line number Diff line Loading @@ -6,121 +6,6 @@ from django.utils import six from django.utils.deprecation import RemovedInDjango19Warning class MergeDict(object): """ A simple class for creating new "virtual" dictionaries that actually look up values in more than one dictionary, passed in the constructor. If a key appears in more than one of the given dictionaries, only the first occurrence will be used. """ def __init__(self, *dicts): warnings.warn('`MergeDict` is deprecated, use `dict.update()` ' 'instead.', RemovedInDjango19Warning, 2) self.dicts = dicts def __bool__(self): return any(self.dicts) def __nonzero__(self): return type(self).__bool__(self) def __getitem__(self, key): for dict_ in self.dicts: try: return dict_[key] except KeyError: pass raise KeyError(key) def __copy__(self): return self.__class__(*self.dicts) def get(self, key, default=None): try: return self[key] except KeyError: return default # This is used by MergeDicts of MultiValueDicts. def getlist(self, key): for dict_ in self.dicts: if key in dict_: return dict_.getlist(key) return [] def _iteritems(self): seen = set() for dict_ in self.dicts: for item in six.iteritems(dict_): k = item[0] if k in seen: continue seen.add(k) yield item def _iterkeys(self): for k, v in self._iteritems(): yield k def _itervalues(self): for k, v in self._iteritems(): yield v if six.PY3: items = _iteritems keys = _iterkeys values = _itervalues else: iteritems = _iteritems iterkeys = _iterkeys itervalues = _itervalues def items(self): return list(self.iteritems()) def keys(self): return list(self.iterkeys()) def values(self): return list(self.itervalues()) def has_key(self, key): for dict_ in self.dicts: if key in dict_: return True return False __contains__ = has_key __iter__ = _iterkeys def copy(self): """Returns a copy of this object.""" return self.__copy__() def __str__(self): ''' Returns something like "{'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}" instead of the generic "<object meta-data>" inherited from object. ''' return str(dict(self.items())) def __repr__(self): ''' Returns something like MergeDict({'key1': 'val1', 'key2': 'val2'}, {'key3': 'val3'}) instead of generic "<object meta-data>" inherited from object. ''' dictreprs = ', '.join(repr(d) for d in self.dicts) return '%s(%s)' % (self.__class__.__name__, dictreprs) class SortedDict(dict): """ A dictionary that keeps its keys in the order in which they're inserted. Loading tests/forms_tests/tests/test_forms.py +4 −12 Original line number Diff line number Diff line Loading @@ -18,10 +18,9 @@ from django.forms import ( from django.forms.utils import ErrorList from django.http import QueryDict from django.template import Template, Context from django.test import TestCase, ignore_warnings from django.test import TestCase from django.test.utils import str_prefix from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.deprecation import RemovedInDjango19Warning from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe, SafeData Loading Loading @@ -552,11 +551,9 @@ class FormsTestCase(TestCase): <li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li> </ul>""") @ignore_warnings(category=RemovedInDjango19Warning) # MergeDict deprecation def test_multiple_choice_list_data(self): # Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and # MergeDict (when created as a merge of MultiValueDicts) conveniently work with # this. # Data for a MultipleChoiceField should be a list. QueryDict and # MultiValueDict conveniently work with this. class SongForm(Form): name = CharField() composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) Loading @@ -573,11 +570,6 @@ class FormsTestCase(TestCase): f = SongForm(data) self.assertEqual(f.errors, {}) # MergeDict is deprecated, but is supported until removed. data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))) f = SongForm(data) self.assertEqual(f.errors, {}) def test_multiple_hidden(self): class SongForm(Form): name = CharField() Loading tests/utils_tests/test_datastructures.py +1 −72 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import pickle from django.test import SimpleTestCase, ignore_warnings from django.utils.datastructures import (DictWrapper, ImmutableList, MultiValueDict, MultiValueDictKeyError, MergeDict, OrderedSet, SortedDict) MultiValueDict, MultiValueDictKeyError, OrderedSet, SortedDict) from django.utils.deprecation import RemovedInDjango19Warning from django.utils import six Loading Loading @@ -137,77 +137,6 @@ class SortedDictTests(SimpleTestCase): self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1]) @ignore_warnings(category=RemovedInDjango19Warning) class MergeDictTests(SimpleTestCase): def test_simple_mergedict(self): d1 = {'chris': 'cool', 'camri': 'cute', 'cotton': 'adorable', 'tulip': 'snuggable', 'twoofme': 'firstone'} d2 = {'chris2': 'cool2', 'camri2': 'cute2', 'cotton2': 'adorable2', 'tulip2': 'snuggable2'} d3 = {'chris3': 'cool3', 'camri3': 'cute3', 'cotton3': 'adorable3', 'tulip3': 'snuggable3'} md = MergeDict(d1, d2, d3) self.assertEqual(md['chris'], 'cool') self.assertEqual(md['camri'], 'cute') self.assertEqual(md['twoofme'], 'firstone') md2 = md.copy() self.assertEqual(md2['chris'], 'cool') def test_mergedict_merges_multivaluedict(self): """ MergeDict can merge MultiValueDicts """ multi1 = MultiValueDict({'key1': ['value1'], 'key2': ['value2', 'value3']}) multi2 = MultiValueDict({'key2': ['value4'], 'key4': ['value5', 'value6']}) mm = MergeDict(multi1, multi2) # Although 'key2' appears in both dictionaries, # only the first value is used. self.assertEqual(mm.getlist('key2'), ['value2', 'value3']) self.assertEqual(mm.getlist('key4'), ['value5', 'value6']) self.assertEqual(mm.getlist('undefined'), []) self.assertEqual(sorted(six.iterkeys(mm)), ['key1', 'key2', 'key4']) self.assertEqual(len(list(six.itervalues(mm))), 3) self.assertIn('value1', six.itervalues(mm)) self.assertEqual( sorted(six.iteritems(mm), key=lambda k: k[0]), [('key1', 'value1'), ('key2', 'value3'), ('key4', 'value6')] ) self.assertEqual( [(k, mm.getlist(k)) for k in sorted(mm)], [('key1', ['value1']), ('key2', ['value2', 'value3']), ('key4', ['value5', 'value6'])] ) def test_bool_casting(self): empty = MergeDict({}, {}, {}) not_empty = MergeDict({}, {}, {"key": "value"}) self.assertFalse(empty) self.assertTrue(not_empty) def test_key_error(self): """ Test that the message of KeyError contains the missing key name. """ d1 = MergeDict({'key1': 42}) with six.assertRaisesRegex(self, KeyError, 'key2'): d1['key2'] class OrderedSetTests(SimpleTestCase): def test_bool(self): Loading Loading
django/forms/widgets.py +3 −3 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ from itertools import chain from django.conf import settings from django.forms.utils import flatatt, to_current_timezone from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.html import conditional_escape, format_html from django.utils.translation import ugettext_lazy Loading Loading @@ -319,7 +319,7 @@ class MultipleHiddenInput(HiddenInput): return mark_safe('\n'.join(inputs)) def value_from_datadict(self, data, files, name): if isinstance(data, (MultiValueDict, MergeDict)): if isinstance(data, MultiValueDict): return data.getlist(name) return data.get(name, None) Loading Loading @@ -587,7 +587,7 @@ class SelectMultiple(Select): return mark_safe('\n'.join(output)) def value_from_datadict(self, data, files, name): if isinstance(data, (MultiValueDict, MergeDict)): if isinstance(data, MultiValueDict): return data.getlist(name) return data.get(name, None) Loading
django/utils/datastructures.py +0 −115 Original line number Diff line number Diff line Loading @@ -6,121 +6,6 @@ from django.utils import six from django.utils.deprecation import RemovedInDjango19Warning class MergeDict(object): """ A simple class for creating new "virtual" dictionaries that actually look up values in more than one dictionary, passed in the constructor. If a key appears in more than one of the given dictionaries, only the first occurrence will be used. """ def __init__(self, *dicts): warnings.warn('`MergeDict` is deprecated, use `dict.update()` ' 'instead.', RemovedInDjango19Warning, 2) self.dicts = dicts def __bool__(self): return any(self.dicts) def __nonzero__(self): return type(self).__bool__(self) def __getitem__(self, key): for dict_ in self.dicts: try: return dict_[key] except KeyError: pass raise KeyError(key) def __copy__(self): return self.__class__(*self.dicts) def get(self, key, default=None): try: return self[key] except KeyError: return default # This is used by MergeDicts of MultiValueDicts. def getlist(self, key): for dict_ in self.dicts: if key in dict_: return dict_.getlist(key) return [] def _iteritems(self): seen = set() for dict_ in self.dicts: for item in six.iteritems(dict_): k = item[0] if k in seen: continue seen.add(k) yield item def _iterkeys(self): for k, v in self._iteritems(): yield k def _itervalues(self): for k, v in self._iteritems(): yield v if six.PY3: items = _iteritems keys = _iterkeys values = _itervalues else: iteritems = _iteritems iterkeys = _iterkeys itervalues = _itervalues def items(self): return list(self.iteritems()) def keys(self): return list(self.iterkeys()) def values(self): return list(self.itervalues()) def has_key(self, key): for dict_ in self.dicts: if key in dict_: return True return False __contains__ = has_key __iter__ = _iterkeys def copy(self): """Returns a copy of this object.""" return self.__copy__() def __str__(self): ''' Returns something like "{'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}" instead of the generic "<object meta-data>" inherited from object. ''' return str(dict(self.items())) def __repr__(self): ''' Returns something like MergeDict({'key1': 'val1', 'key2': 'val2'}, {'key3': 'val3'}) instead of generic "<object meta-data>" inherited from object. ''' dictreprs = ', '.join(repr(d) for d in self.dicts) return '%s(%s)' % (self.__class__.__name__, dictreprs) class SortedDict(dict): """ A dictionary that keeps its keys in the order in which they're inserted. Loading
tests/forms_tests/tests/test_forms.py +4 −12 Original line number Diff line number Diff line Loading @@ -18,10 +18,9 @@ from django.forms import ( from django.forms.utils import ErrorList from django.http import QueryDict from django.template import Template, Context from django.test import TestCase, ignore_warnings from django.test import TestCase from django.test.utils import str_prefix from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.deprecation import RemovedInDjango19Warning from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe, SafeData Loading Loading @@ -552,11 +551,9 @@ class FormsTestCase(TestCase): <li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li> </ul>""") @ignore_warnings(category=RemovedInDjango19Warning) # MergeDict deprecation def test_multiple_choice_list_data(self): # Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and # MergeDict (when created as a merge of MultiValueDicts) conveniently work with # this. # Data for a MultipleChoiceField should be a list. QueryDict and # MultiValueDict conveniently work with this. class SongForm(Form): name = CharField() composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple) Loading @@ -573,11 +570,6 @@ class FormsTestCase(TestCase): f = SongForm(data) self.assertEqual(f.errors, {}) # MergeDict is deprecated, but is supported until removed. data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))) f = SongForm(data) self.assertEqual(f.errors, {}) def test_multiple_hidden(self): class SongForm(Form): name = CharField() Loading
tests/utils_tests/test_datastructures.py +1 −72 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import pickle from django.test import SimpleTestCase, ignore_warnings from django.utils.datastructures import (DictWrapper, ImmutableList, MultiValueDict, MultiValueDictKeyError, MergeDict, OrderedSet, SortedDict) MultiValueDict, MultiValueDictKeyError, OrderedSet, SortedDict) from django.utils.deprecation import RemovedInDjango19Warning from django.utils import six Loading Loading @@ -137,77 +137,6 @@ class SortedDictTests(SimpleTestCase): self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1]) @ignore_warnings(category=RemovedInDjango19Warning) class MergeDictTests(SimpleTestCase): def test_simple_mergedict(self): d1 = {'chris': 'cool', 'camri': 'cute', 'cotton': 'adorable', 'tulip': 'snuggable', 'twoofme': 'firstone'} d2 = {'chris2': 'cool2', 'camri2': 'cute2', 'cotton2': 'adorable2', 'tulip2': 'snuggable2'} d3 = {'chris3': 'cool3', 'camri3': 'cute3', 'cotton3': 'adorable3', 'tulip3': 'snuggable3'} md = MergeDict(d1, d2, d3) self.assertEqual(md['chris'], 'cool') self.assertEqual(md['camri'], 'cute') self.assertEqual(md['twoofme'], 'firstone') md2 = md.copy() self.assertEqual(md2['chris'], 'cool') def test_mergedict_merges_multivaluedict(self): """ MergeDict can merge MultiValueDicts """ multi1 = MultiValueDict({'key1': ['value1'], 'key2': ['value2', 'value3']}) multi2 = MultiValueDict({'key2': ['value4'], 'key4': ['value5', 'value6']}) mm = MergeDict(multi1, multi2) # Although 'key2' appears in both dictionaries, # only the first value is used. self.assertEqual(mm.getlist('key2'), ['value2', 'value3']) self.assertEqual(mm.getlist('key4'), ['value5', 'value6']) self.assertEqual(mm.getlist('undefined'), []) self.assertEqual(sorted(six.iterkeys(mm)), ['key1', 'key2', 'key4']) self.assertEqual(len(list(six.itervalues(mm))), 3) self.assertIn('value1', six.itervalues(mm)) self.assertEqual( sorted(six.iteritems(mm), key=lambda k: k[0]), [('key1', 'value1'), ('key2', 'value3'), ('key4', 'value6')] ) self.assertEqual( [(k, mm.getlist(k)) for k in sorted(mm)], [('key1', ['value1']), ('key2', ['value2', 'value3']), ('key4', ['value5', 'value6'])] ) def test_bool_casting(self): empty = MergeDict({}, {}, {}) not_empty = MergeDict({}, {}, {"key": "value"}) self.assertFalse(empty) self.assertTrue(not_empty) def test_key_error(self): """ Test that the message of KeyError contains the missing key name. """ d1 = MergeDict({'key1': 42}) with six.assertRaisesRegex(self, KeyError, 'key2'): d1['key2'] class OrderedSetTests(SimpleTestCase): def test_bool(self): Loading