diff options
author | Illia Volochii <illia.volochii@gmail.com> | 2021-09-20 22:33:42 +0300 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-09-22 09:26:21 +0200 |
commit | bc4c7e5d68e01207268c868932eb14ae4206f02c (patch) | |
tree | 7af7b0aa55c53dfc837867147cb734041c399e34 /django/utils/datastructures.py | |
parent | e0a56ad3c86c1b5c3d5842783bf6b20e96304770 (diff) | |
download | django-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.py | 33 |
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 |