Django

Code

Ticket #2970: case_insensitive_dict.py

File case_insensitive_dict.py, 3.0 kB (added by SmileyChris, 2 years ago)

Here's a (2.3 compatible) case insensitive dict I whipped up

Line 
1 class CaseInsensitiveDict(dict):
2     def __init__(self, *kw, **kwargs):
3         super(CaseInsensitiveDict, self).__init__(*kw, **kwargs)
4         # Set up case insensitive dict for future reference.
5         keys = {}
6         for key in self.keys():
7             if isinstance(key, basestring):
8                 keys[key.lower()] = key
9         self._case_insensitive_keys = keys
10        
11     def _get_case_sensitive_key(self, key):
12         if isinstance(key, basestring):
13             key = self._case_insensitive_keys.get(key.lower(), key)
14         return key
15
16     def __getitem__(self, key):
17         key = self._get_case_sensitive_key(key)
18         return super(CaseInsensitiveDict, self).__getitem__(key)
19
20     def __setitem__(self, key, value):
21         if isinstance(key, basestring):
22             key_lower = key.lower()
23             if key_lower in self._case_insensitive_keys.keys():
24                 # Delete old key (since it may be a different case).
25                 old_key = self._case_insensitive_keys[key_lower]
26                 super(CaseInsensitiveDict, self).__delitem__(old_key)
27             # Save new key in case insensitive dict.
28             self._case_insensitive_keys[key_lower] = key
29         return super(CaseInsensitiveDict, self).__setitem__(key, value)
30
31     def __delitem__(self, key):
32         key = self._get_case_sensitive_key(key)
33         if isinstance(key, basestring):
34             # Delete key from case insensitive dict.
35             del self._case_insensitive_keys[key.lower()]
36         return super(CaseInsensitiveDict, self).__delitem__(key)
37
38     def __contains__(self, key):
39         key = self._get_case_sensitive_key(key)
40         return super(CaseInsensitiveDict, self).__contains__(key)
41
42     def get(self, key):
43         key = self._get_case_sensitive_key(key)
44         return super(CaseInsensitiveDict, self).get(key)
45
46     def has_key(self, key):
47         key = self._get_case_sensitive_key(key)
48         return super(CaseInsensitiveDict, self).has_key(key)
49
50     def pop(self, key):
51         key = self._get_case_sensitive_key(key)
52         return super(CaseInsensitiveDict, self).pop(key)
53
54     def update(self, dict=None, **kwargs):
55         if dict is None:
56             dict = kwargs
57         if dict:
58             # Check for keys in new dict which may differ to the current keys.
59             for key in dict.keys():
60                 case_sensitive_key = self._get_case_sensitive_key(key)
61                 if key != case_sensitive_key:
62                     # Change case to match existing key.
63                     dict[case_sensitive_key] = dict[key]
64                     del dict[key]
65         return super(CaseInsensitiveDict, self).update(dict)
66
67     def clear(self):
68         # Reset case insensitive dict
69         self._case_insensitive_keys = {}
70         return super(CaseInsensitiveDict, self).clear()
71
72     def setdefault(self, key, default=None):
73         key = self._get_case_sensitive_key(key)
74         return super(CaseInsensitiveDict, self).setdefault(key, default)
75