Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2 

3""" 

4requests.structures 

5~~~~~~~~~~~~~~~~~~~ 

6 

7Data structures that power Requests. 

8""" 

9 

10from collections import OrderedDict 

11 

12from .compat import Mapping, MutableMapping 

13 

14 

15class CaseInsensitiveDict(MutableMapping): 

16 """A case-insensitive ``dict``-like object. 

17 

18 Implements all methods and operations of 

19 ``MutableMapping`` as well as dict's ``copy``. Also 

20 provides ``lower_items``. 

21 

22 All keys are expected to be strings. The structure remembers the 

23 case of the last key to be set, and ``iter(instance)``, 

24 ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` 

25 will contain case-sensitive keys. However, querying and contains 

26 testing is case insensitive:: 

27 

28 cid = CaseInsensitiveDict() 

29 cid['Accept'] = 'application/json' 

30 cid['aCCEPT'] == 'application/json' # True 

31 list(cid) == ['Accept'] # True 

32 

33 For example, ``headers['content-encoding']`` will return the 

34 value of a ``'Content-Encoding'`` response header, regardless 

35 of how the header name was originally stored. 

36 

37 If the constructor, ``.update``, or equality comparison 

38 operations are given keys that have equal ``.lower()``s, the 

39 behavior is undefined. 

40 """ 

41 

42 def __init__(self, data=None, **kwargs): 

43 self._store = OrderedDict() 

44 if data is None: 

45 data = {} 

46 self.update(data, **kwargs) 

47 

48 def __setitem__(self, key, value): 

49 # Use the lowercased key for lookups, but store the actual 

50 # key alongside the value. 

51 self._store[key.lower()] = (key, value) 

52 

53 def __getitem__(self, key): 

54 return self._store[key.lower()][1] 

55 

56 def __delitem__(self, key): 

57 del self._store[key.lower()] 

58 

59 def __iter__(self): 

60 return (casedkey for casedkey, mappedvalue in self._store.values()) 

61 

62 def __len__(self): 

63 return len(self._store) 

64 

65 def lower_items(self): 

66 """Like iteritems(), but with all lowercase keys.""" 

67 return ( 

68 (lowerkey, keyval[1]) 

69 for (lowerkey, keyval) 

70 in self._store.items() 

71 ) 

72 

73 def __eq__(self, other): 

74 if isinstance(other, Mapping): 

75 other = CaseInsensitiveDict(other) 

76 else: 

77 return NotImplemented 

78 # Compare insensitively 

79 return dict(self.lower_items()) == dict(other.lower_items()) 

80 

81 # Copy is required 

82 def copy(self): 

83 return CaseInsensitiveDict(self._store.values()) 

84 

85 def __repr__(self): 

86 return str(dict(self.items())) 

87 

88 

89class LookupDict(dict): 

90 """Dictionary lookup object.""" 

91 

92 def __init__(self, name=None): 

93 self.name = name 

94 super(LookupDict, self).__init__() 

95 

96 def __repr__(self): 

97 return '<lookup \'%s\'>' % (self.name) 

98 

99 def __getitem__(self, key): 

100 # We allow fall-through here, so values default to None 

101 

102 return self.__dict__.get(key, None) 

103 

104 def get(self, key, default=None): 

105 return self.__dict__.get(key, default)