summaryrefslogtreecommitdiff
path: root/django/utils/datastructures.py
diff options
context:
space:
mode:
authorIllia Volochii <illia.volochii@gmail.com>2021-09-20 22:33:42 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-22 09:26:21 +0200
commitbc4c7e5d68e01207268c868932eb14ae4206f02c (patch)
tree7af7b0aa55c53dfc837867147cb734041c399e34 /django/utils/datastructures.py
parente0a56ad3c86c1b5c3d5842783bf6b20e96304770 (diff)
downloaddjango-bc4c7e5d68e01207268c868932eb14ae4206f02c.tar.gz
Optimized handling case-insensitive mappings.
Elements yielded by _destruct_iterable_mapping_values are always unpacked. Since unpacking can be done with any iterable, there is no need to convert elements to tuples. Also, such elements can be used directly in for loops, creating a dictionary of them is excessive. Co-authored-by: Nick Pope <nick@nickpope.me.uk>
Diffstat (limited to 'django/utils/datastructures.py')
-rw-r--r--django/utils/datastructures.py33
1 files changed, 18 insertions, 15 deletions
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index f1e9986ca1..18c91aa5e8 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -284,18 +284,6 @@ class DictWrapper(dict):
return value
-def _destruct_iterable_mapping_values(data):
- for i, elem in enumerate(data):
- if len(elem) != 2:
- raise ValueError(
- 'dictionary update sequence element #{} has '
- 'length {}; 2 is required.'.format(i, len(elem))
- )
- if not isinstance(elem[0], str):
- raise ValueError('Element key %r invalid, only strings are allowed' % elem[0])
- yield tuple(elem)
-
-
class CaseInsensitiveMapping(Mapping):
"""
Mapping allowing case-insensitive key lookups. Original case of keys is
@@ -315,9 +303,7 @@ class CaseInsensitiveMapping(Mapping):
"""
def __init__(self, data):
- if not isinstance(data, Mapping):
- data = {k: v for k, v in _destruct_iterable_mapping_values(data)}
- self._store = {k.lower(): (k, v) for k, v in data.items()}
+ self._store = {k.lower(): (k, v) for k, v in self._unpack_items(data)}
def __getitem__(self, key):
return self._store[key.lower()][1]
@@ -340,3 +326,20 @@ class CaseInsensitiveMapping(Mapping):
def copy(self):
return self
+
+ @staticmethod
+ def _unpack_items(data):
+ if isinstance(data, Mapping):
+ yield from data.items()
+ return
+ for i, elem in enumerate(data):
+ if len(elem) != 2:
+ raise ValueError(
+ 'dictionary update sequence element #{} has length {}; '
+ '2 is required.'.format(i, len(elem))
+ )
+ if not isinstance(elem[0], str):
+ raise ValueError(
+ 'Element key %r invalid, only strings are allowed' % elem[0]
+ )
+ yield elem