1
from __future__ import absolute_import, division, unicode_literals
4
from types import ModuleType
6
from pip._vendor.six import text_type
9
import xml.etree.cElementTree as default_etree
11
import xml.etree.ElementTree as default_etree
14
__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair",
15
"surrogatePairToCodepoint", "moduleFactoryFactory",
16
"supports_lone_surrogates", "PY27"]
19
PY27 = sys.version_info[0] == 2 and sys.version_info[1] >= 7
21
# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be
22
# caught by the below test. In general this would be any platform
23
# using UTF-16 as its encoding of unicode strings, such as
24
# Jython. This is because UTF-16 itself is based on the use of such
25
# surrogates, and there is no mechanism to further escape such
28
_x = eval('"\\uD800"') # pylint:disable=eval-used
29
if not isinstance(_x, text_type):
30
# We need this with u"" because of http://bugs.jython.org/issue2039
31
_x = eval('u"\\uD800"') # pylint:disable=eval-used
32
assert isinstance(_x, text_type)
33
except: # pylint:disable=bare-except
34
supports_lone_surrogates = False
36
supports_lone_surrogates = True
39
class MethodDispatcher(dict):
40
"""Dict with 2 special properties:
42
On initiation, keys that are lists, sets or tuples are converted to
43
multiple keys so accessing any one of the items in the original
44
list-like object returns the matching value
46
md = MethodDispatcher({("foo", "bar"):"baz"})
49
A default value which can be set through the default attribute.
52
def __init__(self, items=()):
53
# Using _dictEntries instead of directly assigning to self is about
54
# twice as fast. Please do careful performance testing before changing
57
for name, value in items:
58
if isinstance(name, (list, tuple, frozenset, set)):
60
_dictEntries.append((item, value))
62
_dictEntries.append((name, value))
63
dict.__init__(self, _dictEntries)
64
assert len(self) == len(_dictEntries)
67
def __getitem__(self, key):
68
return dict.get(self, key, self.default)
71
# Some utility functions to deal with weirdness around UCS2 vs UCS4
74
def isSurrogatePair(data):
75
return (len(data) == 2 and
76
ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and
77
ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF)
80
def surrogatePairToCodepoint(data):
81
char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 +
82
(ord(data[1]) - 0xDC00))
85
# Module Factory Factory (no, this isn't Java, I know)
86
# Here to stop this being duplicated all over the place.
89
def moduleFactoryFactory(factory):
92
def moduleFactory(baseModule, *args, **kwargs):
93
if isinstance(ModuleType.__name__, type("")):
94
name = "_%s_factory" % baseModule.__name__
96
name = b"_%s_factory" % baseModule.__name__
98
kwargs_tuple = tuple(kwargs.items())
101
return moduleCache[name][args][kwargs_tuple]
103
mod = ModuleType(name)
104
objs = factory(baseModule, *args, **kwargs)
105
mod.__dict__.update(objs)
106
if "name" not in moduleCache:
107
moduleCache[name] = {}
108
if "args" not in moduleCache[name]:
109
moduleCache[name][args] = {}
110
if "kwargs" not in moduleCache[name][args]:
111
moduleCache[name][args][kwargs_tuple] = {}
112
moduleCache[name][args][kwargs_tuple] = mod
121
def wrapped(*args, **kwargs):
122
key = (tuple(args), tuple(kwargs.items()))
124
cache[key] = func(*args, **kwargs)