Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/soupsieve/css_types.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """CSS selector structure items.""" | |
2 import copyreg | |
3 from collections.abc import Hashable, Mapping | |
4 | |
5 __all__ = ( | |
6 'Selector', | |
7 'SelectorNull', | |
8 'SelectorTag', | |
9 'SelectorAttribute', | |
10 'SelectorContains', | |
11 'SelectorNth', | |
12 'SelectorLang', | |
13 'SelectorList', | |
14 'Namespaces', | |
15 'CustomSelectors' | |
16 ) | |
17 | |
18 | |
19 SEL_EMPTY = 0x1 | |
20 SEL_ROOT = 0x2 | |
21 SEL_DEFAULT = 0x4 | |
22 SEL_INDETERMINATE = 0x8 | |
23 SEL_SCOPE = 0x10 | |
24 SEL_DIR_LTR = 0x20 | |
25 SEL_DIR_RTL = 0x40 | |
26 SEL_IN_RANGE = 0x80 | |
27 SEL_OUT_OF_RANGE = 0x100 | |
28 SEL_DEFINED = 0x200 | |
29 SEL_PLACEHOLDER_SHOWN = 0x400 | |
30 | |
31 | |
32 class Immutable(object): | |
33 """Immutable.""" | |
34 | |
35 __slots__ = ('_hash',) | |
36 | |
37 def __init__(self, **kwargs): | |
38 """Initialize.""" | |
39 | |
40 temp = [] | |
41 for k, v in kwargs.items(): | |
42 temp.append(type(v)) | |
43 temp.append(v) | |
44 super(Immutable, self).__setattr__(k, v) | |
45 super(Immutable, self).__setattr__('_hash', hash(tuple(temp))) | |
46 | |
47 @classmethod | |
48 def __base__(cls): | |
49 """Get base class.""" | |
50 | |
51 return cls | |
52 | |
53 def __eq__(self, other): | |
54 """Equal.""" | |
55 | |
56 return ( | |
57 isinstance(other, self.__base__()) and | |
58 all([getattr(other, key) == getattr(self, key) for key in self.__slots__ if key != '_hash']) | |
59 ) | |
60 | |
61 def __ne__(self, other): | |
62 """Equal.""" | |
63 | |
64 return ( | |
65 not isinstance(other, self.__base__()) or | |
66 any([getattr(other, key) != getattr(self, key) for key in self.__slots__ if key != '_hash']) | |
67 ) | |
68 | |
69 def __hash__(self): | |
70 """Hash.""" | |
71 | |
72 return self._hash | |
73 | |
74 def __setattr__(self, name, value): | |
75 """Prevent mutability.""" | |
76 | |
77 raise AttributeError("'{}' is immutable".format(self.__class__.__name__)) | |
78 | |
79 def __repr__(self): # pragma: no cover | |
80 """Representation.""" | |
81 | |
82 return "{}({})".format( | |
83 self.__base__(), ', '.join(["{}={!r}".format(k, getattr(self, k)) for k in self.__slots__[:-1]]) | |
84 ) | |
85 | |
86 __str__ = __repr__ | |
87 | |
88 | |
89 class ImmutableDict(Mapping): | |
90 """Hashable, immutable dictionary.""" | |
91 | |
92 def __init__(self, arg): | |
93 """Initialize.""" | |
94 | |
95 arg | |
96 is_dict = isinstance(arg, dict) | |
97 if ( | |
98 is_dict and not all([isinstance(v, Hashable) for v in arg.values()]) or | |
99 not is_dict and not all([isinstance(k, Hashable) and isinstance(v, Hashable) for k, v in arg]) | |
100 ): | |
101 raise TypeError('All values must be hashable') | |
102 | |
103 self._d = dict(arg) | |
104 self._hash = hash(tuple([(type(x), x, type(y), y) for x, y in sorted(self._d.items())])) | |
105 | |
106 def __iter__(self): | |
107 """Iterator.""" | |
108 | |
109 return iter(self._d) | |
110 | |
111 def __len__(self): | |
112 """Length.""" | |
113 | |
114 return len(self._d) | |
115 | |
116 def __getitem__(self, key): | |
117 """Get item: `namespace['key']`.""" | |
118 return self._d[key] | |
119 | |
120 def __hash__(self): | |
121 """Hash.""" | |
122 | |
123 return self._hash | |
124 | |
125 def __repr__(self): # pragma: no cover | |
126 """Representation.""" | |
127 | |
128 return "{!r}".format(self._d) | |
129 | |
130 __str__ = __repr__ | |
131 | |
132 | |
133 class Namespaces(ImmutableDict): | |
134 """Namespaces.""" | |
135 | |
136 def __init__(self, arg): | |
137 """Initialize.""" | |
138 | |
139 # If there are arguments, check the first index. | |
140 # `super` should fail if the user gave multiple arguments, | |
141 # so don't bother checking that. | |
142 is_dict = isinstance(arg, dict) | |
143 if is_dict and not all([isinstance(k, str) and isinstance(v, str) for k, v in arg.items()]): | |
144 raise TypeError('Namespace keys and values must be Unicode strings') | |
145 elif not is_dict and not all([isinstance(k, str) and isinstance(v, str) for k, v in arg]): | |
146 raise TypeError('Namespace keys and values must be Unicode strings') | |
147 | |
148 super(Namespaces, self).__init__(arg) | |
149 | |
150 | |
151 class CustomSelectors(ImmutableDict): | |
152 """Custom selectors.""" | |
153 | |
154 def __init__(self, arg): | |
155 """Initialize.""" | |
156 | |
157 # If there are arguments, check the first index. | |
158 # `super` should fail if the user gave multiple arguments, | |
159 # so don't bother checking that. | |
160 is_dict = isinstance(arg, dict) | |
161 if is_dict and not all([isinstance(k, str) and isinstance(v, str) for k, v in arg.items()]): | |
162 raise TypeError('CustomSelectors keys and values must be Unicode strings') | |
163 elif not is_dict and not all([isinstance(k, str) and isinstance(v, str) for k, v in arg]): | |
164 raise TypeError('CustomSelectors keys and values must be Unicode strings') | |
165 | |
166 super(CustomSelectors, self).__init__(arg) | |
167 | |
168 | |
169 class Selector(Immutable): | |
170 """Selector.""" | |
171 | |
172 __slots__ = ( | |
173 'tag', 'ids', 'classes', 'attributes', 'nth', 'selectors', | |
174 'relation', 'rel_type', 'contains', 'lang', 'flags', '_hash' | |
175 ) | |
176 | |
177 def __init__( | |
178 self, tag, ids, classes, attributes, nth, selectors, | |
179 relation, rel_type, contains, lang, flags | |
180 ): | |
181 """Initialize.""" | |
182 | |
183 super(Selector, self).__init__( | |
184 tag=tag, | |
185 ids=ids, | |
186 classes=classes, | |
187 attributes=attributes, | |
188 nth=nth, | |
189 selectors=selectors, | |
190 relation=relation, | |
191 rel_type=rel_type, | |
192 contains=contains, | |
193 lang=lang, | |
194 flags=flags | |
195 ) | |
196 | |
197 | |
198 class SelectorNull(Immutable): | |
199 """Null Selector.""" | |
200 | |
201 def __init__(self): | |
202 """Initialize.""" | |
203 | |
204 super(SelectorNull, self).__init__() | |
205 | |
206 | |
207 class SelectorTag(Immutable): | |
208 """Selector tag.""" | |
209 | |
210 __slots__ = ("name", "prefix", "_hash") | |
211 | |
212 def __init__(self, name, prefix): | |
213 """Initialize.""" | |
214 | |
215 super(SelectorTag, self).__init__( | |
216 name=name, | |
217 prefix=prefix | |
218 ) | |
219 | |
220 | |
221 class SelectorAttribute(Immutable): | |
222 """Selector attribute rule.""" | |
223 | |
224 __slots__ = ("attribute", "prefix", "pattern", "xml_type_pattern", "_hash") | |
225 | |
226 def __init__(self, attribute, prefix, pattern, xml_type_pattern): | |
227 """Initialize.""" | |
228 | |
229 super(SelectorAttribute, self).__init__( | |
230 attribute=attribute, | |
231 prefix=prefix, | |
232 pattern=pattern, | |
233 xml_type_pattern=xml_type_pattern | |
234 ) | |
235 | |
236 | |
237 class SelectorContains(Immutable): | |
238 """Selector contains rule.""" | |
239 | |
240 __slots__ = ("text", "own", "_hash") | |
241 | |
242 def __init__(self, text, own): | |
243 """Initialize.""" | |
244 | |
245 super(SelectorContains, self).__init__( | |
246 text=text, | |
247 own=own | |
248 ) | |
249 | |
250 | |
251 class SelectorNth(Immutable): | |
252 """Selector nth type.""" | |
253 | |
254 __slots__ = ("a", "n", "b", "of_type", "last", "selectors", "_hash") | |
255 | |
256 def __init__(self, a, n, b, of_type, last, selectors): | |
257 """Initialize.""" | |
258 | |
259 super(SelectorNth, self).__init__( | |
260 a=a, | |
261 n=n, | |
262 b=b, | |
263 of_type=of_type, | |
264 last=last, | |
265 selectors=selectors | |
266 ) | |
267 | |
268 | |
269 class SelectorLang(Immutable): | |
270 """Selector language rules.""" | |
271 | |
272 __slots__ = ("languages", "_hash",) | |
273 | |
274 def __init__(self, languages): | |
275 """Initialize.""" | |
276 | |
277 super(SelectorLang, self).__init__( | |
278 languages=tuple(languages) | |
279 ) | |
280 | |
281 def __iter__(self): | |
282 """Iterator.""" | |
283 | |
284 return iter(self.languages) | |
285 | |
286 def __len__(self): # pragma: no cover | |
287 """Length.""" | |
288 | |
289 return len(self.languages) | |
290 | |
291 def __getitem__(self, index): # pragma: no cover | |
292 """Get item.""" | |
293 | |
294 return self.languages[index] | |
295 | |
296 | |
297 class SelectorList(Immutable): | |
298 """Selector list.""" | |
299 | |
300 __slots__ = ("selectors", "is_not", "is_html", "_hash") | |
301 | |
302 def __init__(self, selectors=tuple(), is_not=False, is_html=False): | |
303 """Initialize.""" | |
304 | |
305 super(SelectorList, self).__init__( | |
306 selectors=tuple(selectors), | |
307 is_not=is_not, | |
308 is_html=is_html | |
309 ) | |
310 | |
311 def __iter__(self): | |
312 """Iterator.""" | |
313 | |
314 return iter(self.selectors) | |
315 | |
316 def __len__(self): | |
317 """Length.""" | |
318 | |
319 return len(self.selectors) | |
320 | |
321 def __getitem__(self, index): | |
322 """Get item.""" | |
323 | |
324 return self.selectors[index] | |
325 | |
326 | |
327 def _pickle(p): | |
328 return p.__base__(), tuple([getattr(p, s) for s in p.__slots__[:-1]]) | |
329 | |
330 | |
331 def pickle_register(obj): | |
332 """Allow object to be pickled.""" | |
333 | |
334 copyreg.pickle(obj, _pickle) | |
335 | |
336 | |
337 pickle_register(Selector) | |
338 pickle_register(SelectorNull) | |
339 pickle_register(SelectorTag) | |
340 pickle_register(SelectorAttribute) | |
341 pickle_register(SelectorContains) | |
342 pickle_register(SelectorNth) | |
343 pickle_register(SelectorLang) | |
344 pickle_register(SelectorList) |