selectolax 0.3.24__cp313-cp313-macosx_10_13_universal2.whl → 0.3.26__cp313-cp313-macosx_10_13_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of selectolax might be problematic. Click here for more details.
- selectolax/__init__.py +1 -1
- selectolax/lexbor/util.pxi +19 -0
- selectolax/lexbor.c +21520 -16146
- selectolax/lexbor.cpython-313-darwin.so +0 -0
- selectolax/lexbor.pyi +86 -36
- selectolax/lexbor.pyx +1 -0
- selectolax/modest/util.pxi +19 -0
- selectolax/parser.c +6727 -1349
- selectolax/parser.cpython-313-darwin.so +0 -0
- selectolax/parser.pyi +87 -35
- selectolax/parser.pyx +1 -0
- selectolax/utils.pxi +94 -0
- {selectolax-0.3.24.dist-info → selectolax-0.3.26.dist-info}/METADATA +7 -2
- selectolax-0.3.26.dist-info/RECORD +26 -0
- {selectolax-0.3.24.dist-info → selectolax-0.3.26.dist-info}/WHEEL +1 -1
- selectolax-0.3.24.dist-info/RECORD +0 -24
- {selectolax-0.3.24.dist-info → selectolax-0.3.26.dist-info}/LICENSE +0 -0
- {selectolax-0.3.24.dist-info → selectolax-0.3.26.dist-info}/top_level.txt +0 -0
|
Binary file
|
selectolax/parser.pyi
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
from typing import Iterator, TypeVar, Literal
|
|
1
|
+
from typing import Any, Iterator, TypeVar, Literal, overload
|
|
2
2
|
|
|
3
3
|
DefaultT = TypeVar("DefaultT")
|
|
4
4
|
|
|
5
5
|
class _Attributes:
|
|
6
6
|
@staticmethod
|
|
7
|
-
def create(node:
|
|
7
|
+
def create(node: Node, decode_errors: str) -> _Attributes: ...
|
|
8
8
|
def keys(self) -> Iterator[str]: ...
|
|
9
|
-
def items(self) -> Iterator[tuple[str, str]]: ...
|
|
10
|
-
def values(self) -> Iterator[str]: ...
|
|
11
|
-
def
|
|
12
|
-
def
|
|
9
|
+
def items(self) -> Iterator[tuple[str, str | None]]: ...
|
|
10
|
+
def values(self) -> Iterator[str | None]: ...
|
|
11
|
+
def __iter__(self) -> Iterator[str]: ...
|
|
12
|
+
def __len__(self) -> int: ...
|
|
13
|
+
def __getitem__(self, key: str) -> str | None: ...
|
|
14
|
+
def __setitem__(self, key: str, value: str) -> None: ...
|
|
15
|
+
def __delitem__(self, key: str) -> None: ...
|
|
16
|
+
def __contains__(self, key: str) -> bool: ...
|
|
17
|
+
def __repr__(self) -> str: ...
|
|
18
|
+
@overload
|
|
19
|
+
def get(self, key: str, default: DefaultT) -> DefaultT | str | None: ...
|
|
20
|
+
@overload
|
|
21
|
+
def get(self, key: str, default: None = ...) -> str | None: ...
|
|
22
|
+
@overload
|
|
23
|
+
def sget(self, key: str, default: str | DefaultT) -> str | DefaultT: ...
|
|
24
|
+
@overload
|
|
25
|
+
def sget(self, key: str, default: str = "") -> str: ...
|
|
13
26
|
|
|
14
27
|
class Selector:
|
|
15
28
|
"""An advanced CSS selector that supports additional operations.
|
|
@@ -18,12 +31,12 @@ class Selector:
|
|
|
18
31
|
|
|
19
32
|
Please note, this is an experimental feature that can change in the future."""
|
|
20
33
|
|
|
21
|
-
def __init__(self, node:
|
|
22
|
-
def css(self, query: str) ->
|
|
34
|
+
def __init__(self, node: Node, query: str): ...
|
|
35
|
+
def css(self, query: str) -> Node:
|
|
23
36
|
"""Evaluate CSS selector against current scope."""
|
|
24
37
|
...
|
|
25
38
|
@property
|
|
26
|
-
def matches(self) -> list[
|
|
39
|
+
def matches(self) -> list[Node]:
|
|
27
40
|
"""Returns all possible selector matches"""
|
|
28
41
|
...
|
|
29
42
|
@property
|
|
@@ -32,7 +45,7 @@ class Selector:
|
|
|
32
45
|
...
|
|
33
46
|
def text_contains(
|
|
34
47
|
self, text: str, deep: bool = True, separator: str = "", strip: bool = False
|
|
35
|
-
) ->
|
|
48
|
+
) -> Selector:
|
|
36
49
|
"""Filter all current matches given text."""
|
|
37
50
|
...
|
|
38
51
|
def any_text_contains(
|
|
@@ -42,7 +55,7 @@ class Selector:
|
|
|
42
55
|
...
|
|
43
56
|
def attribute_long_than(
|
|
44
57
|
self, text: str, length: int, start: str | None = None
|
|
45
|
-
) ->
|
|
58
|
+
) -> Selector:
|
|
46
59
|
"""Filter all current matches by attribute length.
|
|
47
60
|
|
|
48
61
|
Similar to string-length in XPath."""
|
|
@@ -56,14 +69,15 @@ class Selector:
|
|
|
56
69
|
...
|
|
57
70
|
|
|
58
71
|
class Node:
|
|
72
|
+
parser: HTMLParser
|
|
59
73
|
@property
|
|
60
|
-
def attributes(self) -> dict[str,
|
|
74
|
+
def attributes(self) -> dict[str, str | None]:
|
|
61
75
|
"""Get all attributes that belong to the current node.
|
|
62
76
|
|
|
63
77
|
The value of empty attributes is None."""
|
|
64
78
|
...
|
|
65
79
|
@property
|
|
66
|
-
def attrs(self) ->
|
|
80
|
+
def attrs(self) -> _Attributes:
|
|
67
81
|
"""A dict-like object that is similar to the attributes property, but operates directly on the Node data."""
|
|
68
82
|
...
|
|
69
83
|
@property
|
|
@@ -87,10 +101,10 @@ class Node:
|
|
|
87
101
|
def text(self, deep: bool = True, separator: str = "", strip: bool = False) -> str:
|
|
88
102
|
"""Returns the text of the node including text of all its child nodes."""
|
|
89
103
|
...
|
|
90
|
-
def iter(self, include_text: bool = False) -> Iterator[
|
|
104
|
+
def iter(self, include_text: bool = False) -> Iterator[Node]:
|
|
91
105
|
"""Iterate over nodes on the current level."""
|
|
92
106
|
...
|
|
93
|
-
def traverse(self, include_text: bool = False) -> Iterator[
|
|
107
|
+
def traverse(self, include_text: bool = False) -> Iterator[Node]:
|
|
94
108
|
"""Iterate over all child and next nodes starting from the current level."""
|
|
95
109
|
...
|
|
96
110
|
@property
|
|
@@ -98,30 +112,30 @@ class Node:
|
|
|
98
112
|
"""Return the name of the current tag (e.g. div, p, img)."""
|
|
99
113
|
...
|
|
100
114
|
@property
|
|
101
|
-
def child(self) ->
|
|
115
|
+
def child(self) -> Node | None:
|
|
102
116
|
"""Return the child node."""
|
|
103
117
|
...
|
|
104
118
|
@property
|
|
105
|
-
def parent(self) ->
|
|
119
|
+
def parent(self) -> Node | None:
|
|
106
120
|
"""Return the parent node."""
|
|
107
121
|
...
|
|
108
122
|
@property
|
|
109
|
-
def next(self) ->
|
|
123
|
+
def next(self) -> Node | None:
|
|
110
124
|
"""Return next node."""
|
|
111
125
|
...
|
|
112
126
|
@property
|
|
113
|
-
def prev(self) ->
|
|
127
|
+
def prev(self) -> Node | None:
|
|
114
128
|
"""Return previous node."""
|
|
115
129
|
...
|
|
116
130
|
@property
|
|
117
|
-
def last_child(self) ->
|
|
131
|
+
def last_child(self) -> Node | None:
|
|
118
132
|
"""Return last child node."""
|
|
119
133
|
...
|
|
120
134
|
@property
|
|
121
|
-
def html(self) ->
|
|
135
|
+
def html(self) -> str | None:
|
|
122
136
|
"""Return HTML representation of the current node including all its child nodes."""
|
|
123
137
|
...
|
|
124
|
-
def css(self, query: str) -> list[
|
|
138
|
+
def css(self, query: str) -> list[Node]:
|
|
125
139
|
"""Evaluate CSS selector against current node and its child nodes."""
|
|
126
140
|
...
|
|
127
141
|
def any_css_matches(self, selectors: tuple[str]) -> bool:
|
|
@@ -130,9 +144,18 @@ class Node:
|
|
|
130
144
|
def css_matches(self, selector: str) -> bool:
|
|
131
145
|
"""Returns True if CSS selector matches a node."""
|
|
132
146
|
...
|
|
147
|
+
@overload
|
|
133
148
|
def css_first(
|
|
134
|
-
self, query: str, default:
|
|
135
|
-
) ->
|
|
149
|
+
self, query: str, default: Any = ..., strict: Literal[True] = ...
|
|
150
|
+
) -> Node: ...
|
|
151
|
+
@overload
|
|
152
|
+
def css_first(
|
|
153
|
+
self, query: str, default: DefaultT, strict: bool = False
|
|
154
|
+
) -> Node | DefaultT: ...
|
|
155
|
+
@overload
|
|
156
|
+
def css_first(
|
|
157
|
+
self, query: str, default: None = ..., strict: bool = False
|
|
158
|
+
) -> Node | None:
|
|
136
159
|
"""Evaluate CSS selector against current node and its child nodes."""
|
|
137
160
|
...
|
|
138
161
|
def decompose(self, recursive: bool = True) -> None:
|
|
@@ -161,13 +184,16 @@ class Node:
|
|
|
161
184
|
def insert_after(self, value: str | bytes | None) -> None:
|
|
162
185
|
"""Insert a node after the current Node."""
|
|
163
186
|
...
|
|
187
|
+
def insert_child(self, value: str | bytes | None) -> None:
|
|
188
|
+
"""Insert a node inside (at the end of) the current Node.."""
|
|
189
|
+
...
|
|
164
190
|
@property
|
|
165
191
|
def raw_value(self) -> bytes:
|
|
166
192
|
"""Return the raw (unparsed, original) value of a node.
|
|
167
193
|
|
|
168
194
|
Currently, works on text nodes only."""
|
|
169
195
|
...
|
|
170
|
-
def select(self, query: str | None = None) ->
|
|
196
|
+
def select(self, query: str | None = None) -> Selector:
|
|
171
197
|
"""Select nodes given a CSS selector.
|
|
172
198
|
|
|
173
199
|
Works similarly to the css method, but supports chained filtering and extra features.
|
|
@@ -204,14 +230,23 @@ class HTMLParser:
|
|
|
204
230
|
use_meta_tags: bool = True,
|
|
205
231
|
decode_errors: Literal["strict", "ignore", "replace"] = "ignore",
|
|
206
232
|
): ...
|
|
207
|
-
def css(self, query: str) -> list[
|
|
233
|
+
def css(self, query: str) -> list[Node]:
|
|
208
234
|
"""A CSS selector.
|
|
209
235
|
|
|
210
236
|
Matches pattern query against HTML tree."""
|
|
211
237
|
...
|
|
238
|
+
@overload
|
|
239
|
+
def css_first(
|
|
240
|
+
self, query: str, default: Any = ..., strict: Literal[True] = ...
|
|
241
|
+
) -> Node: ...
|
|
242
|
+
@overload
|
|
212
243
|
def css_first(
|
|
213
|
-
self, query: str, default: DefaultT
|
|
214
|
-
) ->
|
|
244
|
+
self, query: str, default: DefaultT, strict: bool = False
|
|
245
|
+
) -> Node | DefaultT: ...
|
|
246
|
+
@overload
|
|
247
|
+
def css_first(
|
|
248
|
+
self, query: str, default: None = ..., strict: bool = False
|
|
249
|
+
) -> Node | None:
|
|
215
250
|
"""Same as css but returns only the first match."""
|
|
216
251
|
...
|
|
217
252
|
@property
|
|
@@ -221,18 +256,18 @@ class HTMLParser:
|
|
|
221
256
|
Returns unknown in case the encoding is not determined."""
|
|
222
257
|
...
|
|
223
258
|
@property
|
|
224
|
-
def root(self) ->
|
|
259
|
+
def root(self) -> Node | None:
|
|
225
260
|
"""Returns root node."""
|
|
226
261
|
...
|
|
227
262
|
@property
|
|
228
|
-
def head(self) ->
|
|
263
|
+
def head(self) -> Node | None:
|
|
229
264
|
"""Returns head node."""
|
|
230
265
|
...
|
|
231
266
|
@property
|
|
232
|
-
def body(self) ->
|
|
267
|
+
def body(self) -> Node | None:
|
|
233
268
|
"""Returns document body."""
|
|
234
269
|
...
|
|
235
|
-
def tags(self, name: str) -> list[
|
|
270
|
+
def tags(self, name: str) -> list[Node]:
|
|
236
271
|
"""Returns a list of tags that match specified name."""
|
|
237
272
|
...
|
|
238
273
|
def text(self, deep: bool = True, separator: str = "", strip: bool = False) -> str:
|
|
@@ -245,10 +280,10 @@ class HTMLParser:
|
|
|
245
280
|
Works the same as th unwrap method, but applied to a list of tags."""
|
|
246
281
|
...
|
|
247
282
|
@property
|
|
248
|
-
def html(self) ->
|
|
283
|
+
def html(self) -> str | None:
|
|
249
284
|
"""Return HTML representation of the page."""
|
|
250
285
|
...
|
|
251
|
-
def select(self, query: str | None = None) ->
|
|
286
|
+
def select(self, query: str | None = None) -> Selector | None:
|
|
252
287
|
"""Select nodes given a CSS selector.
|
|
253
288
|
|
|
254
289
|
Works similarly to the css method, but supports chained filtering and extra features.
|
|
@@ -268,7 +303,7 @@ class HTMLParser:
|
|
|
268
303
|
Caches values on the first call to improve performance."""
|
|
269
304
|
...
|
|
270
305
|
def css_matches(self, selector: str) -> bool: ...
|
|
271
|
-
def clone(self) ->
|
|
306
|
+
def clone(self) -> HTMLParser:
|
|
272
307
|
"""Clone the current tree."""
|
|
273
308
|
...
|
|
274
309
|
def merge_text_nodes(self):
|
|
@@ -276,3 +311,20 @@ class HTMLParser:
|
|
|
276
311
|
|
|
277
312
|
This is useful for text extraction."""
|
|
278
313
|
...
|
|
314
|
+
|
|
315
|
+
def create_tag(tag: str) -> Node:
|
|
316
|
+
"""
|
|
317
|
+
Given an HTML tag name, e.g. `"div"`, create a single empty node for that tag,
|
|
318
|
+
e.g. `"<div></div>"`.
|
|
319
|
+
"""
|
|
320
|
+
...
|
|
321
|
+
|
|
322
|
+
def parse_fragment(html: str) -> list[Node]:
|
|
323
|
+
"""
|
|
324
|
+
Given HTML, parse it into a list of Nodes, such that the nodes
|
|
325
|
+
correspond to the given HTML.
|
|
326
|
+
|
|
327
|
+
For contrast, HTMLParser adds `<html>`, `<head>`, and `<body>` tags
|
|
328
|
+
if they are missing. This function does not add these tags.
|
|
329
|
+
"""
|
|
330
|
+
...
|
selectolax/parser.pyx
CHANGED
selectolax/utils.pxi
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
from typing import Literal, Optional, Union, Type
|
|
2
|
+
|
|
1
3
|
MAX_HTML_INPUT_SIZE = 250e+7
|
|
2
4
|
|
|
5
|
+
ParserCls = Union[Type["HTMLParser"], Type["LexborHTMLParser"]]
|
|
6
|
+
Parser = Union["HTMLParser", "LexborHTMLParser"]
|
|
7
|
+
|
|
8
|
+
|
|
3
9
|
def preprocess_input(html, decode_errors='ignore'):
|
|
4
10
|
if isinstance(html, (str, unicode)):
|
|
5
11
|
bytes_html = html.encode('UTF-8', errors=decode_errors)
|
|
@@ -11,3 +17,91 @@ def preprocess_input(html, decode_errors='ignore'):
|
|
|
11
17
|
if html_len > MAX_HTML_INPUT_SIZE:
|
|
12
18
|
raise ValueError("The specified HTML input is too large to be processed (%d bytes)" % html_len)
|
|
13
19
|
return bytes_html, html_len
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def do_create_tag(tag: str, parser_cls: ParserCls):
|
|
23
|
+
if not tag:
|
|
24
|
+
raise ValueError("Tag name cannot be empty")
|
|
25
|
+
return do_parse_fragment(f"<{tag}></{tag}>", parser_cls)[0]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_fragment_type(
|
|
29
|
+
html: str,
|
|
30
|
+
parser_cls: ParserCls,
|
|
31
|
+
tree: Optional[Parser] = None,
|
|
32
|
+
) -> Literal["document", "fragment", "head", "body", "head_and_body", "document_no_head", "document_no_body", "document_no_head_no_body"]:
|
|
33
|
+
if not tree:
|
|
34
|
+
tree = parser_cls(html)
|
|
35
|
+
|
|
36
|
+
import re
|
|
37
|
+
html_re = re.compile(r"<html|<body|<head", re.IGNORECASE)
|
|
38
|
+
|
|
39
|
+
has_html = False
|
|
40
|
+
has_head = False
|
|
41
|
+
has_body = False
|
|
42
|
+
for match in html_re.finditer(html):
|
|
43
|
+
if match[0] == "<html":
|
|
44
|
+
has_html = True
|
|
45
|
+
elif match[0] == "<head":
|
|
46
|
+
has_head = True
|
|
47
|
+
elif match[0] == "<body":
|
|
48
|
+
has_body = True
|
|
49
|
+
|
|
50
|
+
if has_html and has_head and has_body:
|
|
51
|
+
break
|
|
52
|
+
|
|
53
|
+
if has_html and has_head and has_body:
|
|
54
|
+
return "document"
|
|
55
|
+
elif has_html and not has_head and has_body:
|
|
56
|
+
return "document_no_head"
|
|
57
|
+
elif has_html and has_head and not has_body:
|
|
58
|
+
return "document_no_body"
|
|
59
|
+
elif has_html and not has_head and not has_body:
|
|
60
|
+
return "document_no_head_no_body"
|
|
61
|
+
elif has_head and not has_body:
|
|
62
|
+
return "head"
|
|
63
|
+
elif not has_head and has_body:
|
|
64
|
+
return "body"
|
|
65
|
+
elif has_head and has_body:
|
|
66
|
+
return "head_and_body"
|
|
67
|
+
else:
|
|
68
|
+
return "fragment"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def do_parse_fragment(html: str, parser_cls: ParserCls):
|
|
72
|
+
"""
|
|
73
|
+
Given HTML, parse it into a list of Nodes, such that the nodes
|
|
74
|
+
correspond to the given HTML.
|
|
75
|
+
|
|
76
|
+
For contrast, HTMLParser adds `<html>`, `<head>`, and `<body>` tags
|
|
77
|
+
if they are missing. This function does not add these tags.
|
|
78
|
+
"""
|
|
79
|
+
html = html.strip()
|
|
80
|
+
tree = parser_cls(html)
|
|
81
|
+
frag_type = get_fragment_type(html, parser_cls, tree)
|
|
82
|
+
|
|
83
|
+
if frag_type == "document":
|
|
84
|
+
return [tree.root]
|
|
85
|
+
if frag_type == "document_no_head":
|
|
86
|
+
tree.head.decompose(recursive=True)
|
|
87
|
+
return [tree.root]
|
|
88
|
+
if frag_type == "document_no_body":
|
|
89
|
+
tree.body.decompose(recursive=True)
|
|
90
|
+
return [tree.root]
|
|
91
|
+
if frag_type == "document_no_head_no_body":
|
|
92
|
+
tree.head.decompose(recursive=True)
|
|
93
|
+
tree.body.decompose(recursive=True)
|
|
94
|
+
return [tree.root]
|
|
95
|
+
elif frag_type == "head":
|
|
96
|
+
tree.body.decompose(recursive=True)
|
|
97
|
+
return [tree.head]
|
|
98
|
+
elif frag_type == "body":
|
|
99
|
+
tree.head.decompose(recursive=True)
|
|
100
|
+
return [tree.body]
|
|
101
|
+
elif frag_type == "head_and_body":
|
|
102
|
+
return [tree.head, tree.body]
|
|
103
|
+
else:
|
|
104
|
+
return [
|
|
105
|
+
*tree.head.iter(include_text=True),
|
|
106
|
+
*tree.body.iter(include_text=True),
|
|
107
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: selectolax
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.26
|
|
4
4
|
Summary: Fast HTML5 parser with CSS selectors.
|
|
5
5
|
Home-page: https://github.com/rushter/selectolax
|
|
6
6
|
Author: Artem Golubin
|
|
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.10
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.11
|
|
24
24
|
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
26
|
License-File: LICENSE
|
|
26
27
|
Provides-Extra: cython
|
|
27
28
|
Requires-Dist: Cython==3.0.11; extra == "cython"
|
|
@@ -122,6 +123,10 @@ Available backends
|
|
|
122
123
|
Selectolax supports two backends: ``Modest`` and ``Lexbor``. By default, all examples use the Modest backend.
|
|
123
124
|
Most of the features between backends are almost identical, but there are still some differences.
|
|
124
125
|
|
|
126
|
+
As of 2024, the preferred backend is ``Lexbor``. The ``Modest`` backend is still available for compatibility reasons
|
|
127
|
+
and the underlying C library that selectolax uses is not maintained anymore.
|
|
128
|
+
|
|
129
|
+
|
|
125
130
|
To use ``lexbor``, just import the parser and use it in the similar way to the `HTMLParser`.
|
|
126
131
|
|
|
127
132
|
.. code:: python
|
|
@@ -147,7 +152,7 @@ Simple Benchmark
|
|
|
147
152
|
Package Time
|
|
148
153
|
============================ ===========
|
|
149
154
|
Beautiful Soup (html.parser) 61.02 sec.
|
|
150
|
-
lxml
|
|
155
|
+
lxml / Beautiful Soup (lxml) 9.09 sec.
|
|
151
156
|
html5_parser 16.10 sec.
|
|
152
157
|
selectolax (Modest) 2.94 sec.
|
|
153
158
|
selectolax (Lexbor) 2.39 sec.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
selectolax-0.3.26.dist-info/RECORD,,
|
|
2
|
+
selectolax-0.3.26.dist-info/LICENSE,sha256=kYggm2ZJzBgL79x1gCsYsx8rFIYP2IE-BdXRV3Rm0NU,1077
|
|
3
|
+
selectolax-0.3.26.dist-info/WHEEL,sha256=pJyWwqOgS8-_dOw_-yPJJDauxCO1NJCkyPNqxURSoZw,115
|
|
4
|
+
selectolax-0.3.26.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
|
|
5
|
+
selectolax-0.3.26.dist-info/METADATA,sha256=HqNPkDK0NqFA-N4HsTn3QtHYktNEwobUdCj7kw-e4VU,5928
|
|
6
|
+
selectolax/lexbor.pyi,sha256=X2PMQR2XLd2rOPliKSpeFZ_VEf6mOQFTcFm0ChQbzsQ,6544
|
|
7
|
+
selectolax/parser.pyx,sha256=o1HkYE_nQr3TS7EPlldJx2-ygU9B5FI2uWYFzdF-VaI,12953
|
|
8
|
+
selectolax/__init__.py,sha256=r8TrGaSWTYcCt8yNkcf_pH1I7c7IPOMagr3wd9tCgy8,175
|
|
9
|
+
selectolax/lexbor.pxd,sha256=PwygBdb1blWAQcxXubZS5uffhgcXaqgySNMPFMT02-c,20958
|
|
10
|
+
selectolax/lexbor.pyx,sha256=ffEzBnZjGTsI-H5qck7bfjVRE9vteOhQnDp6RjVD7G0,10750
|
|
11
|
+
selectolax/parser.pyi,sha256=kbR5eWvkJEy-9Hx3L_4JmGy3caIl0ki4SiagWz-fnhw,11557
|
|
12
|
+
selectolax/utils.pxi,sha256=rPNMFqS0PRLkQPugwPfj-pnHCzkQzQ2cjIRMPZdR6R8,3453
|
|
13
|
+
selectolax/lexbor.c,sha256=mDFnCQbjAav1zsNLpikrhF1nth0NnhlvHwFzo45-hIc,2353590
|
|
14
|
+
selectolax/parser.cpython-313-darwin.so,sha256=kY8S34tGUaohfdBfzBYnoRFo6_ydkw-3WSKSMFrJUGM,6158936
|
|
15
|
+
selectolax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
selectolax/lexbor.cpython-313-darwin.so,sha256=mBSRyPhv-nJxeONweF1uRR3Ll2xljzrsOMnDanrGtd0,23079456
|
|
17
|
+
selectolax/parser.c,sha256=W3VyTzjtoNJZAWLNSx9cFaJcn4D4gtQchsz3APG7iiY,2214752
|
|
18
|
+
selectolax/base.pxi,sha256=eiPKlY9gG3l49qJoRQVLl1Ljza6z1k0A-met6sDPcqE,89
|
|
19
|
+
selectolax/parser.pxd,sha256=zZlg1vHUg6o4MXaiwKAo5S5hO_DqBGc4_E10qJ2EcM4,24564
|
|
20
|
+
selectolax/modest/selection.pxi,sha256=S55MMxEW2B1oPExB_DRwPM46WoWZU73J3rFRZU1URuQ,6393
|
|
21
|
+
selectolax/modest/util.pxi,sha256=aX9UnRNTITImHVBTlIs9efOd3EyugLq_Lwuo0zVTiuQ,551
|
|
22
|
+
selectolax/modest/node.pxi,sha256=NrMzJnQJDCmgTHpUxpMHDyAfQ_AS_n_Cr_2ryEKjyL0,32550
|
|
23
|
+
selectolax/lexbor/selection.pxi,sha256=PqjvpL6H9uFcmcQWVGfML8FDsTO7tGoZujpA00g9pWk,6444
|
|
24
|
+
selectolax/lexbor/util.pxi,sha256=Zq7S-zlyU3wOo49wGHQHnmmhpbkrcJm59ZCTPENcZQA,563
|
|
25
|
+
selectolax/lexbor/node.pxi,sha256=1XNzUwCbTYXy4D6rZtHxMpoJ9M-xoprB9wjdsiaWhr0,29346
|
|
26
|
+
selectolax/lexbor/attrs.pxi,sha256=-518D5v70GgMJhtsxWrWcgIMnXg8afECpUubzq8kqqs,3102
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
selectolax-0.3.24.dist-info/RECORD,,
|
|
2
|
-
selectolax-0.3.24.dist-info/LICENSE,sha256=kYggm2ZJzBgL79x1gCsYsx8rFIYP2IE-BdXRV3Rm0NU,1077
|
|
3
|
-
selectolax-0.3.24.dist-info/WHEEL,sha256=Atbd32uHC5ud5B4JupjIDNKQgnXrL6njGq322U0ClSQ,115
|
|
4
|
-
selectolax-0.3.24.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
|
|
5
|
-
selectolax-0.3.24.dist-info/METADATA,sha256=tTXFaywjSCLtoHn-mCX-jZCSuhWVZ8CVJocJit3e4Po,5681
|
|
6
|
-
selectolax/lexbor.pyi,sha256=N2u6ru6bMnJWsjRmzoctM9AHju41FZVr6Iij-gbkNOs,4945
|
|
7
|
-
selectolax/parser.pyx,sha256=2pKAUhY64htRxF5v64Ke7NRNSm1BHAS60wxrmmapJi0,12927
|
|
8
|
-
selectolax/__init__.py,sha256=0DJWRFlhuIq2te-rSQYt7CZ4a7_wDJZFxi5tMdQTiHM,175
|
|
9
|
-
selectolax/lexbor.pxd,sha256=PwygBdb1blWAQcxXubZS5uffhgcXaqgySNMPFMT02-c,20958
|
|
10
|
-
selectolax/lexbor.pyx,sha256=HhP93LGdiUmRY3F1ybFQHgz7NG25Ae1RFqhxx7HE9BY,10724
|
|
11
|
-
selectolax/parser.pyi,sha256=g8AED0DK6tpLxlgbYtmpzvuUQ1TMGX7hQBi6u5jlbHQ,9908
|
|
12
|
-
selectolax/utils.pxi,sha256=BCIzfmduFEuCxu_9vIEmjzrcwawOtyW31lDmfEU1wk4,544
|
|
13
|
-
selectolax/lexbor.c,sha256=r7XCW9QHJ5FQ4WD-XdHTfZGOlsVeAhjKrohfm_qcFR8,2134829
|
|
14
|
-
selectolax/parser.cpython-313-darwin.so,sha256=lZybv0UkJeENZjcFRpihPTDaPBGpWojxL3ZAo7eQgSc,6054792
|
|
15
|
-
selectolax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
selectolax/lexbor.cpython-313-darwin.so,sha256=RJHXcSafauwSqez_UKyV-DcWKO3H4wdYd3ig5L6DYZo,22959168
|
|
17
|
-
selectolax/parser.c,sha256=mKvGJLHhe2iXRBHj4VxBCfrjtfpnJpzODRx37_v51gA,1995872
|
|
18
|
-
selectolax/base.pxi,sha256=eiPKlY9gG3l49qJoRQVLl1Ljza6z1k0A-met6sDPcqE,89
|
|
19
|
-
selectolax/parser.pxd,sha256=zZlg1vHUg6o4MXaiwKAo5S5hO_DqBGc4_E10qJ2EcM4,24564
|
|
20
|
-
selectolax/modest/selection.pxi,sha256=S55MMxEW2B1oPExB_DRwPM46WoWZU73J3rFRZU1URuQ,6393
|
|
21
|
-
selectolax/modest/node.pxi,sha256=NrMzJnQJDCmgTHpUxpMHDyAfQ_AS_n_Cr_2ryEKjyL0,32550
|
|
22
|
-
selectolax/lexbor/selection.pxi,sha256=PqjvpL6H9uFcmcQWVGfML8FDsTO7tGoZujpA00g9pWk,6444
|
|
23
|
-
selectolax/lexbor/node.pxi,sha256=1XNzUwCbTYXy4D6rZtHxMpoJ9M-xoprB9wjdsiaWhr0,29346
|
|
24
|
-
selectolax/lexbor/attrs.pxi,sha256=-518D5v70GgMJhtsxWrWcgIMnXg8afECpUubzq8kqqs,3102
|
|
File without changes
|
|
File without changes
|