selectolax 0.3.24__cp310-cp310-musllinux_1_2_aarch64.whl → 0.3.26__cp310-cp310-musllinux_1_2_aarch64.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/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: "Node", decode_errors: str) -> "_Attributes": ...
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 get(self, key, default: DefaultT | None = None) -> str | DefaultT: ...
12
- def sget(self, key, default: str = "") -> str | DefaultT: ...
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: "Node", query: str): ...
22
- def css(self, query: str) -> "Node":
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["Node"]:
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
- ) -> "Selector":
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
- ) -> "Selector":
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, None | 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) -> "_Attributes":
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["Node"]:
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["Node"]:
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) -> None | "Node":
115
+ def child(self) -> Node | None:
102
116
  """Return the child node."""
103
117
  ...
104
118
  @property
105
- def parent(self) -> None | "Node":
119
+ def parent(self) -> Node | None:
106
120
  """Return the parent node."""
107
121
  ...
108
122
  @property
109
- def next(self) -> None | "Node":
123
+ def next(self) -> Node | None:
110
124
  """Return next node."""
111
125
  ...
112
126
  @property
113
- def prev(self) -> None | "Node":
127
+ def prev(self) -> Node | None:
114
128
  """Return previous node."""
115
129
  ...
116
130
  @property
117
- def last_child(self) -> None | "Node":
131
+ def last_child(self) -> Node | None:
118
132
  """Return last child node."""
119
133
  ...
120
134
  @property
121
- def html(self) -> None | str:
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["Node"]:
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: DefaultT | None = None, strict: bool = False
135
- ) -> "Node" | DefaultT:
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) -> "Selector":
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["Node"]:
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 | None = None, strict: bool = False
214
- ) -> DefaultT | "Node":
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) -> "Node" | None:
259
+ def root(self) -> Node | None:
225
260
  """Returns root node."""
226
261
  ...
227
262
  @property
228
- def head(self) -> "Node" | None:
263
+ def head(self) -> Node | None:
229
264
  """Returns head node."""
230
265
  ...
231
266
  @property
232
- def body(self) -> "Node" | None:
267
+ def body(self) -> Node | None:
233
268
  """Returns document body."""
234
269
  ...
235
- def tags(self, name: str) -> list["Node"]:
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) -> None | str:
283
+ def html(self) -> str | None:
249
284
  """Return HTML representation of the page."""
250
285
  ...
251
- def select(self, query: str | None = None) -> "Selector" | 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) -> "HTMLParser":
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
@@ -3,6 +3,7 @@ from cpython cimport bool
3
3
 
4
4
  include "modest/selection.pxi"
5
5
  include "modest/node.pxi"
6
+ include "modest/util.pxi"
6
7
  include "utils.pxi"
7
8
 
8
9
  cdef class HTMLParser:
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.24
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 9.09 sec.
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/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ selectolax/lexbor.cpython-310-aarch64-linux-gnu.so,sha256=D-ncPVUcnR5zFznuRpSQuJW7HoT-TUVfp-bzTt1B4ZY,21245048
3
+ selectolax/parser.pyi,sha256=kbR5eWvkJEy-9Hx3L_4JmGy3caIl0ki4SiagWz-fnhw,11557
4
+ selectolax/parser.pxd,sha256=zZlg1vHUg6o4MXaiwKAo5S5hO_DqBGc4_E10qJ2EcM4,24564
5
+ selectolax/lexbor.pxd,sha256=PwygBdb1blWAQcxXubZS5uffhgcXaqgySNMPFMT02-c,20958
6
+ selectolax/base.pxi,sha256=eiPKlY9gG3l49qJoRQVLl1Ljza6z1k0A-met6sDPcqE,89
7
+ selectolax/lexbor.pyi,sha256=X2PMQR2XLd2rOPliKSpeFZ_VEf6mOQFTcFm0ChQbzsQ,6544
8
+ selectolax/lexbor.c,sha256=Bqxtf923DtupnW7ZPAu3f0M1PjMJJSaofiSvOYrP69c,2353590
9
+ selectolax/lexbor.pyx,sha256=ffEzBnZjGTsI-H5qck7bfjVRE9vteOhQnDp6RjVD7G0,10750
10
+ selectolax/parser.pyx,sha256=o1HkYE_nQr3TS7EPlldJx2-ygU9B5FI2uWYFzdF-VaI,12953
11
+ selectolax/utils.pxi,sha256=rPNMFqS0PRLkQPugwPfj-pnHCzkQzQ2cjIRMPZdR6R8,3453
12
+ selectolax/parser.c,sha256=0jrrlXvB2Vu9s8REpwt4l6lu641e4FXVmMYXsaQN2XQ,2214750
13
+ selectolax/__init__.py,sha256=r8TrGaSWTYcCt8yNkcf_pH1I7c7IPOMagr3wd9tCgy8,175
14
+ selectolax/parser.cpython-310-aarch64-linux-gnu.so,sha256=Wq1wFY8jWWtQ6Kkn2H1TSCZmZeelGYaJOpKhpO-Zajc,7387232
15
+ selectolax/modest/util.pxi,sha256=aX9UnRNTITImHVBTlIs9efOd3EyugLq_Lwuo0zVTiuQ,551
16
+ selectolax/modest/node.pxi,sha256=NrMzJnQJDCmgTHpUxpMHDyAfQ_AS_n_Cr_2ryEKjyL0,32550
17
+ selectolax/modest/selection.pxi,sha256=S55MMxEW2B1oPExB_DRwPM46WoWZU73J3rFRZU1URuQ,6393
18
+ selectolax/lexbor/util.pxi,sha256=Zq7S-zlyU3wOo49wGHQHnmmhpbkrcJm59ZCTPENcZQA,563
19
+ selectolax/lexbor/node.pxi,sha256=1XNzUwCbTYXy4D6rZtHxMpoJ9M-xoprB9wjdsiaWhr0,29346
20
+ selectolax/lexbor/selection.pxi,sha256=PqjvpL6H9uFcmcQWVGfML8FDsTO7tGoZujpA00g9pWk,6444
21
+ selectolax/lexbor/attrs.pxi,sha256=-518D5v70GgMJhtsxWrWcgIMnXg8afECpUubzq8kqqs,3102
22
+ selectolax-0.3.26.dist-info/LICENSE,sha256=kYggm2ZJzBgL79x1gCsYsx8rFIYP2IE-BdXRV3Rm0NU,1077
23
+ selectolax-0.3.26.dist-info/METADATA,sha256=HqNPkDK0NqFA-N4HsTn3QtHYktNEwobUdCj7kw-e4VU,5928
24
+ selectolax-0.3.26.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
25
+ selectolax-0.3.26.dist-info/WHEEL,sha256=kX6hYeLpl-XXrxpTwvsavPzBlFpUE9SBAGndUl-PFa4,113
26
+ selectolax-0.3.26.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- selectolax/lexbor.cpython-310-aarch64-linux-gnu.so,sha256=MJUbkuNbLr3KaEzdHHBTECVCmoyn3FrI1p4OeSOE0Do,21024304
2
- selectolax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- selectolax/lexbor.pyi,sha256=N2u6ru6bMnJWsjRmzoctM9AHju41FZVr6Iij-gbkNOs,4945
4
- selectolax/parser.cpython-310-aarch64-linux-gnu.so,sha256=fP1IltiuZZohGvno313kNKWb64TCP5EF6iTGR580GIw,7181768
5
- selectolax/parser.pyx,sha256=2pKAUhY64htRxF5v64Ke7NRNSm1BHAS60wxrmmapJi0,12927
6
- selectolax/base.pxi,sha256=eiPKlY9gG3l49qJoRQVLl1Ljza6z1k0A-met6sDPcqE,89
7
- selectolax/utils.pxi,sha256=BCIzfmduFEuCxu_9vIEmjzrcwawOtyW31lDmfEU1wk4,544
8
- selectolax/parser.c,sha256=NodaVPpvDLnKD8kX08eu9sZNYbzKhb3sT-rBNrRqTAU,1995870
9
- selectolax/parser.pyi,sha256=g8AED0DK6tpLxlgbYtmpzvuUQ1TMGX7hQBi6u5jlbHQ,9908
10
- selectolax/lexbor.pyx,sha256=HhP93LGdiUmRY3F1ybFQHgz7NG25Ae1RFqhxx7HE9BY,10724
11
- selectolax/lexbor.pxd,sha256=PwygBdb1blWAQcxXubZS5uffhgcXaqgySNMPFMT02-c,20958
12
- selectolax/lexbor.c,sha256=Is-9U-NXnZNUGZDh7_HU7ztvIYUMXQVwOOTqujR895c,2134829
13
- selectolax/__init__.py,sha256=0DJWRFlhuIq2te-rSQYt7CZ4a7_wDJZFxi5tMdQTiHM,175
14
- selectolax/parser.pxd,sha256=zZlg1vHUg6o4MXaiwKAo5S5hO_DqBGc4_E10qJ2EcM4,24564
15
- selectolax/modest/selection.pxi,sha256=S55MMxEW2B1oPExB_DRwPM46WoWZU73J3rFRZU1URuQ,6393
16
- selectolax/modest/node.pxi,sha256=NrMzJnQJDCmgTHpUxpMHDyAfQ_AS_n_Cr_2ryEKjyL0,32550
17
- selectolax/lexbor/selection.pxi,sha256=PqjvpL6H9uFcmcQWVGfML8FDsTO7tGoZujpA00g9pWk,6444
18
- selectolax/lexbor/attrs.pxi,sha256=-518D5v70GgMJhtsxWrWcgIMnXg8afECpUubzq8kqqs,3102
19
- selectolax/lexbor/node.pxi,sha256=1XNzUwCbTYXy4D6rZtHxMpoJ9M-xoprB9wjdsiaWhr0,29346
20
- selectolax-0.3.24.dist-info/LICENSE,sha256=kYggm2ZJzBgL79x1gCsYsx8rFIYP2IE-BdXRV3Rm0NU,1077
21
- selectolax-0.3.24.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
22
- selectolax-0.3.24.dist-info/RECORD,,
23
- selectolax-0.3.24.dist-info/METADATA,sha256=tTXFaywjSCLtoHn-mCX-jZCSuhWVZ8CVJocJit3e4Po,5681
24
- selectolax-0.3.24.dist-info/WHEEL,sha256=kX6hYeLpl-XXrxpTwvsavPzBlFpUE9SBAGndUl-PFa4,113