| Viewing file:  _utils.py (4.82 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
from __future__ import absolute_import, division, unicode_literals
 from types import ModuleType
 
 try:
 from collections.abc import Mapping
 except ImportError:
 from collections import Mapping
 
 from pip._vendor.six import text_type, PY3
 
 if PY3:
 import xml.etree.ElementTree as default_etree
 else:
 try:
 import xml.etree.cElementTree as default_etree
 except ImportError:
 import xml.etree.ElementTree as default_etree
 
 
 __all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair",
 "surrogatePairToCodepoint", "moduleFactoryFactory",
 "supports_lone_surrogates"]
 
 
 # Platforms not supporting lone surrogates (\uD800-\uDFFF) should be
 # caught by the below test. In general this would be any platform
 # using UTF-16 as its encoding of unicode strings, such as
 # Jython. This is because UTF-16 itself is based on the use of such
 # surrogates, and there is no mechanism to further escape such
 # escapes.
 try:
 _x = eval('"\\uD800"')  # pylint:disable=eval-used
 if not isinstance(_x, text_type):
 # We need this with u"" because of http://bugs.jython.org/issue2039
 _x = eval('u"\\uD800"')  # pylint:disable=eval-used
 assert isinstance(_x, text_type)
 except Exception:
 supports_lone_surrogates = False
 else:
 supports_lone_surrogates = True
 
 
 class MethodDispatcher(dict):
 """Dict with 2 special properties:
 
 On initiation, keys that are lists, sets or tuples are converted to
 multiple keys so accessing any one of the items in the original
 list-like object returns the matching value
 
 md = MethodDispatcher({("foo", "bar"):"baz"})
 md["foo"] == "baz"
 
 A default value which can be set through the default attribute.
 """
 
 def __init__(self, items=()):
 _dictEntries = []
 for name, value in items:
 if isinstance(name, (list, tuple, frozenset, set)):
 for item in name:
 _dictEntries.append((item, value))
 else:
 _dictEntries.append((name, value))
 dict.__init__(self, _dictEntries)
 assert len(self) == len(_dictEntries)
 self.default = None
 
 def __getitem__(self, key):
 return dict.get(self, key, self.default)
 
 def __get__(self, instance, owner=None):
 return BoundMethodDispatcher(instance, self)
 
 
 class BoundMethodDispatcher(Mapping):
 """Wraps a MethodDispatcher, binding its return values to `instance`"""
 def __init__(self, instance, dispatcher):
 self.instance = instance
 self.dispatcher = dispatcher
 
 def __getitem__(self, key):
 # see https://docs.python.org/3/reference/datamodel.html#object.__get__
 # on a function, __get__ is used to bind a function to an instance as a bound method
 return self.dispatcher[key].__get__(self.instance)
 
 def get(self, key, default):
 if key in self.dispatcher:
 return self[key]
 else:
 return default
 
 def __iter__(self):
 return iter(self.dispatcher)
 
 def __len__(self):
 return len(self.dispatcher)
 
 def __contains__(self, key):
 return key in self.dispatcher
 
 
 # Some utility functions to deal with weirdness around UCS2 vs UCS4
 # python builds
 
 def isSurrogatePair(data):
 return (len(data) == 2 and
 ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and
 ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF)
 
 
 def surrogatePairToCodepoint(data):
 char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 +
 (ord(data[1]) - 0xDC00))
 return char_val
 
 # Module Factory Factory (no, this isn't Java, I know)
 # Here to stop this being duplicated all over the place.
 
 
 def moduleFactoryFactory(factory):
 moduleCache = {}
 
 def moduleFactory(baseModule, *args, **kwargs):
 if isinstance(ModuleType.__name__, type("")):
 name = "_%s_factory" % baseModule.__name__
 else:
 name = b"_%s_factory" % baseModule.__name__
 
 kwargs_tuple = tuple(kwargs.items())
 
 try:
 return moduleCache[name][args][kwargs_tuple]
 except KeyError:
 mod = ModuleType(name)
 objs = factory(baseModule, *args, **kwargs)
 mod.__dict__.update(objs)
 if "name" not in moduleCache:
 moduleCache[name] = {}
 if "args" not in moduleCache[name]:
 moduleCache[name][args] = {}
 if "kwargs" not in moduleCache[name][args]:
 moduleCache[name][args][kwargs_tuple] = {}
 moduleCache[name][args][kwargs_tuple] = mod
 return mod
 
 return moduleFactory
 
 
 def memoize(func):
 cache = {}
 
 def wrapped(*args, **kwargs):
 key = (tuple(args), tuple(kwargs.items()))
 if key not in cache:
 cache[key] = func(*args, **kwargs)
 return cache[key]
 
 return wrapped
 
 |