Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/bleach/_vendor/html5lib/_utils.py: 34%

88 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1from __future__ import absolute_import, division, unicode_literals 

2 

3from types import ModuleType 

4 

5try: 

6 from collections.abc import Mapping 

7except ImportError: 

8 from collections import Mapping 

9 

10from six import text_type, PY3 

11 

12if PY3: 

13 import xml.etree.ElementTree as default_etree 

14else: 

15 try: 

16 import xml.etree.cElementTree as default_etree 

17 except ImportError: 

18 import xml.etree.ElementTree as default_etree 

19 

20 

21__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", 

22 "surrogatePairToCodepoint", "moduleFactoryFactory", 

23 "supports_lone_surrogates"] 

24 

25 

26# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be 

27# caught by the below test. In general this would be any platform 

28# using UTF-16 as its encoding of unicode strings, such as 

29# Jython. This is because UTF-16 itself is based on the use of such 

30# surrogates, and there is no mechanism to further escape such 

31# escapes. 

32try: 

33 _x = eval('"\\uD800"') # pylint:disable=eval-used 

34 if not isinstance(_x, text_type): 

35 # We need this with u"" because of http://bugs.jython.org/issue2039 

36 _x = eval('u"\\uD800"') # pylint:disable=eval-used 

37 assert isinstance(_x, text_type) 

38except Exception: 

39 supports_lone_surrogates = False 

40else: 

41 supports_lone_surrogates = True 

42 

43 

44class MethodDispatcher(dict): 

45 """Dict with 2 special properties: 

46 

47 On initiation, keys that are lists, sets or tuples are converted to 

48 multiple keys so accessing any one of the items in the original 

49 list-like object returns the matching value 

50 

51 md = MethodDispatcher({("foo", "bar"):"baz"}) 

52 md["foo"] == "baz" 

53 

54 A default value which can be set through the default attribute. 

55 """ 

56 

57 def __init__(self, items=()): 

58 _dictEntries = [] 

59 for name, value in items: 

60 if isinstance(name, (list, tuple, frozenset, set)): 

61 for item in name: 

62 _dictEntries.append((item, value)) 

63 else: 

64 _dictEntries.append((name, value)) 

65 dict.__init__(self, _dictEntries) 

66 assert len(self) == len(_dictEntries) 

67 self.default = None 

68 

69 def __getitem__(self, key): 

70 return dict.get(self, key, self.default) 

71 

72 def __get__(self, instance, owner=None): 

73 return BoundMethodDispatcher(instance, self) 

74 

75 

76class BoundMethodDispatcher(Mapping): 

77 """Wraps a MethodDispatcher, binding its return values to `instance`""" 

78 def __init__(self, instance, dispatcher): 

79 self.instance = instance 

80 self.dispatcher = dispatcher 

81 

82 def __getitem__(self, key): 

83 # see https://docs.python.org/3/reference/datamodel.html#object.__get__ 

84 # on a function, __get__ is used to bind a function to an instance as a bound method 

85 return self.dispatcher[key].__get__(self.instance) 

86 

87 def get(self, key, default): 

88 if key in self.dispatcher: 

89 return self[key] 

90 else: 

91 return default 

92 

93 def __iter__(self): 

94 return iter(self.dispatcher) 

95 

96 def __len__(self): 

97 return len(self.dispatcher) 

98 

99 def __contains__(self, key): 

100 return key in self.dispatcher 

101 

102 

103# Some utility functions to deal with weirdness around UCS2 vs UCS4 

104# python builds 

105 

106def isSurrogatePair(data): 

107 return (len(data) == 2 and 

108 ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and 

109 ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) 

110 

111 

112def surrogatePairToCodepoint(data): 

113 char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + 

114 (ord(data[1]) - 0xDC00)) 

115 return char_val 

116 

117# Module Factory Factory (no, this isn't Java, I know) 

118# Here to stop this being duplicated all over the place. 

119 

120 

121def moduleFactoryFactory(factory): 

122 moduleCache = {} 

123 

124 def moduleFactory(baseModule, *args, **kwargs): 

125 if isinstance(ModuleType.__name__, type("")): 

126 name = "_%s_factory" % baseModule.__name__ 

127 else: 

128 name = b"_%s_factory" % baseModule.__name__ 

129 

130 kwargs_tuple = tuple(kwargs.items()) 

131 

132 try: 

133 return moduleCache[name][args][kwargs_tuple] 

134 except KeyError: 

135 mod = ModuleType(name) 

136 objs = factory(baseModule, *args, **kwargs) 

137 mod.__dict__.update(objs) 

138 if "name" not in moduleCache: 

139 moduleCache[name] = {} 

140 if "args" not in moduleCache[name]: 

141 moduleCache[name][args] = {} 

142 if "kwargs" not in moduleCache[name][args]: 

143 moduleCache[name][args][kwargs_tuple] = {} 

144 moduleCache[name][args][kwargs_tuple] = mod 

145 return mod 

146 

147 return moduleFactory 

148 

149 

150def memoize(func): 

151 cache = {} 

152 

153 def wrapped(*args, **kwargs): 

154 key = (tuple(args), tuple(kwargs.items())) 

155 if key not in cache: 

156 cache[key] = func(*args, **kwargs) 

157 return cache[key] 

158 

159 return wrapped