mirror of https://github.com/django/django.git
Removed django.utils.datastructures.MergeDict per deprecation timeline; refs #18659.
This commit is contained in:
parent
75f107b884
commit
37b7776a01
|
@ -9,7 +9,7 @@ from itertools import chain
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.forms.utils import flatatt, to_current_timezone
|
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.encoding import force_text, python_2_unicode_compatible
|
||||||
from django.utils.html import conditional_escape, format_html
|
from django.utils.html import conditional_escape, format_html
|
||||||
from django.utils.translation import ugettext_lazy
|
from django.utils.translation import ugettext_lazy
|
||||||
|
@ -319,7 +319,7 @@ class MultipleHiddenInput(HiddenInput):
|
||||||
return mark_safe('\n'.join(inputs))
|
return mark_safe('\n'.join(inputs))
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
if isinstance(data, (MultiValueDict, MergeDict)):
|
if isinstance(data, MultiValueDict):
|
||||||
return data.getlist(name)
|
return data.getlist(name)
|
||||||
return data.get(name, None)
|
return data.get(name, None)
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ class SelectMultiple(Select):
|
||||||
return mark_safe('\n'.join(output))
|
return mark_safe('\n'.join(output))
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
if isinstance(data, (MultiValueDict, MergeDict)):
|
if isinstance(data, MultiValueDict):
|
||||||
return data.getlist(name)
|
return data.getlist(name)
|
||||||
return data.get(name, None)
|
return data.get(name, None)
|
||||||
|
|
||||||
|
|
|
@ -6,121 +6,6 @@ from django.utils import six
|
||||||
from django.utils.deprecation import RemovedInDjango19Warning
|
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):
|
class SortedDict(dict):
|
||||||
"""
|
"""
|
||||||
A dictionary that keeps its keys in the order in which they're inserted.
|
A dictionary that keeps its keys in the order in which they're inserted.
|
||||||
|
|
|
@ -18,10 +18,9 @@ from django.forms import (
|
||||||
from django.forms.utils import ErrorList
|
from django.forms.utils import ErrorList
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.template import Template, Context
|
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.test.utils import str_prefix
|
||||||
from django.utils.datastructures import MultiValueDict, MergeDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.deprecation import RemovedInDjango19Warning
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.safestring import mark_safe, SafeData
|
from django.utils.safestring import mark_safe, SafeData
|
||||||
|
@ -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>
|
<li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li>
|
||||||
</ul>""")
|
</ul>""")
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango19Warning) # MergeDict deprecation
|
|
||||||
def test_multiple_choice_list_data(self):
|
def test_multiple_choice_list_data(self):
|
||||||
# Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and
|
# Data for a MultipleChoiceField should be a list. QueryDict and
|
||||||
# MergeDict (when created as a merge of MultiValueDicts) conveniently work with
|
# MultiValueDict conveniently work with this.
|
||||||
# this.
|
|
||||||
class SongForm(Form):
|
class SongForm(Form):
|
||||||
name = CharField()
|
name = CharField()
|
||||||
composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple)
|
composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple)
|
||||||
|
@ -573,11 +570,6 @@ class FormsTestCase(TestCase):
|
||||||
f = SongForm(data)
|
f = SongForm(data)
|
||||||
self.assertEqual(f.errors, {})
|
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):
|
def test_multiple_hidden(self):
|
||||||
class SongForm(Form):
|
class SongForm(Form):
|
||||||
name = CharField()
|
name = CharField()
|
||||||
|
|
|
@ -7,7 +7,7 @@ import pickle
|
||||||
|
|
||||||
from django.test import SimpleTestCase, ignore_warnings
|
from django.test import SimpleTestCase, ignore_warnings
|
||||||
from django.utils.datastructures import (DictWrapper, ImmutableList,
|
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.deprecation import RemovedInDjango19Warning
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
|
@ -137,77 +137,6 @@ class SortedDictTests(SimpleTestCase):
|
||||||
self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
|
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):
|
class OrderedSetTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_bool(self):
|
def test_bool(self):
|
||||||
|
|
Loading…
Reference in New Issue