129 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| """
 | |
| requests.structures
 | |
| ~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Data structures that power Requests.
 | |
| 
 | |
| """
 | |
| 
 | |
| import os
 | |
| import collections
 | |
| from itertools import islice
 | |
| 
 | |
| 
 | |
| class IteratorProxy(object):
 | |
|     """docstring for IteratorProxy"""
 | |
|     def __init__(self, i):
 | |
|         self.i = i
 | |
|         # self.i = chain.from_iterable(i)
 | |
| 
 | |
|     def __iter__(self):
 | |
|         return self.i
 | |
| 
 | |
|     def __len__(self):
 | |
|         if hasattr(self.i, '__len__'):
 | |
|             return len(self.i)
 | |
|         if hasattr(self.i, 'len'):
 | |
|             return self.i.len
 | |
|         if hasattr(self.i, 'fileno'):
 | |
|             return os.fstat(self.i.fileno()).st_size
 | |
| 
 | |
|     def read(self, n):
 | |
|         return "".join(islice(self.i, None, n))
 | |
| 
 | |
| 
 | |
| class CaseInsensitiveDict(collections.MutableMapping):
 | |
|     """
 | |
|     A case-insensitive ``dict``-like object.
 | |
| 
 | |
|     Implements all methods and operations of
 | |
|     ``collections.MutableMapping`` as well as dict's ``copy``. Also
 | |
|     provides ``lower_items``.
 | |
| 
 | |
|     All keys are expected to be strings. The structure remembers the
 | |
|     case of the last key to be set, and ``iter(instance)``,
 | |
|     ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
 | |
|     will contain case-sensitive keys. However, querying and contains
 | |
|     testing is case insensitive:
 | |
| 
 | |
|         cid = CaseInsensitiveDict()
 | |
|         cid['Accept'] = 'application/json'
 | |
|         cid['aCCEPT'] == 'application/json'  # True
 | |
|         list(cid) == ['Accept']  # True
 | |
| 
 | |
|     For example, ``headers['content-encoding']`` will return the
 | |
|     value of a ``'Content-Encoding'`` response header, regardless
 | |
|     of how the header name was originally stored.
 | |
| 
 | |
|     If the constructor, ``.update``, or equality comparison
 | |
|     operations are given keys that have equal ``.lower()``s, the
 | |
|     behavior is undefined.
 | |
| 
 | |
|     """
 | |
|     def __init__(self, data=None, **kwargs):
 | |
|         self._store = dict()
 | |
|         if data is None:
 | |
|             data = {}
 | |
|         self.update(data, **kwargs)
 | |
| 
 | |
|     def __setitem__(self, key, value):
 | |
|         # Use the lowercased key for lookups, but store the actual
 | |
|         # key alongside the value.
 | |
|         self._store[key.lower()] = (key, value)
 | |
| 
 | |
|     def __getitem__(self, key):
 | |
|         return self._store[key.lower()][1]
 | |
| 
 | |
|     def __delitem__(self, key):
 | |
|         del self._store[key.lower()]
 | |
| 
 | |
|     def __iter__(self):
 | |
|         return (casedkey for casedkey, mappedvalue in self._store.values())
 | |
| 
 | |
|     def __len__(self):
 | |
|         return len(self._store)
 | |
| 
 | |
|     def lower_items(self):
 | |
|         """Like iteritems(), but with all lowercase keys."""
 | |
|         return (
 | |
|             (lowerkey, keyval[1])
 | |
|             for (lowerkey, keyval)
 | |
|             in self._store.items()
 | |
|         )
 | |
| 
 | |
|     def __eq__(self, other):
 | |
|         if isinstance(other, collections.Mapping):
 | |
|             other = CaseInsensitiveDict(other)
 | |
|         else:
 | |
|             return NotImplemented
 | |
|         # Compare insensitively
 | |
|         return dict(self.lower_items()) == dict(other.lower_items())
 | |
| 
 | |
|     # Copy is required
 | |
|     def copy(self):
 | |
|          return CaseInsensitiveDict(self._store.values())
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return '%s(%r)' % (self.__class__.__name__, dict(self.items()))
 | |
| 
 | |
| 
 | |
| class LookupDict(dict):
 | |
|     """Dictionary lookup object."""
 | |
| 
 | |
|     def __init__(self, name=None):
 | |
|         self.name = name
 | |
|         super(LookupDict, self).__init__()
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return '<lookup \'%s\'>' % (self.name)
 | |
| 
 | |
|     def __getitem__(self, key):
 | |
|         # We allow fall-through here, so values default to None
 | |
| 
 | |
|         return self.__dict__.get(key, None)
 | |
| 
 | |
|     def get(self, key, default=None):
 | |
|         return self.__dict__.get(key, default)
 |